From ab47777685eec5af4403600dbe81230e1cad3837 Mon Sep 17 00:00:00 2001 From: "robertlipe@gmail.com" Date: Sun, 24 Jul 2011 20:04:53 +0000 Subject: [PATCH] Grand style "fix" courtesy of astyle. Everything (whitespace, tabs, curlies) is now internall consistent. git-svn-id: http://gpsbabel.googlecode.com/svn/trunk@4074 f51c46e8-681c-474f-0cfe-069cfd0219fb --- gpsbabel/GPSBabel.pro | 4 +- gpsbabel/alan.c | 500 +- gpsbabel/an1.c | 2032 +++--- gpsbabel/an1sym.h | 1118 ++-- gpsbabel/arcdist.c | 231 +- gpsbabel/avltree.c | 1035 ++-- gpsbabel/avltree.h | 33 +- gpsbabel/axim_gpb.c | 204 +- gpsbabel/bcr.c | 706 ++- gpsbabel/brauniger_iq.c | 440 +- gpsbabel/bushnell.c | 75 +- gpsbabel/bushnell_trl.c | 35 +- gpsbabel/cet.c | 690 ++- gpsbabel/cet.h | 34 +- gpsbabel/cet_util.c | 1266 ++-- gpsbabel/cet_util.h | 2 +- gpsbabel/cetus.c | 1034 ++-- gpsbabel/coastexp.c | 896 +-- gpsbabel/compegps.c | 978 +-- gpsbabel/copilot.c | 256 +- gpsbabel/coto.c | 586 +- gpsbabel/cst.c | 509 +- gpsbabel/csv_util.c | 3473 +++++------ gpsbabel/csv_util.h | 112 +- gpsbabel/defs.h | 682 +-- gpsbabel/delbin.c | 4782 ++++++++------- gpsbabel/delgpl.c | 196 +- gpsbabel/destinator.c | 828 +-- gpsbabel/dg-100.c | 993 +-- gpsbabel/discard.c | 235 +- gpsbabel/dmtlog.c | 1045 ++-- gpsbabel/duplicate.c | 333 +- gpsbabel/easygps.c | 276 +- gpsbabel/enigma.c | 202 +- gpsbabel/exif.c | 2130 ++++--- gpsbabel/explorist_ini.c | 20 +- gpsbabel/fatal.c | 18 +- gpsbabel/filter_skeleton.c | 52 +- gpsbabel/filter_vecs.c | 531 +- gpsbabel/filterdefs.h | 14 +- gpsbabel/format_skeleton.c | 64 +- gpsbabel/formspec.c | 70 +- gpsbabel/g7towin.c | 906 +-- gpsbabel/garmin.c | 1979 +++--- gpsbabel/garmin_device_xml.c | 77 +- gpsbabel/garmin_device_xml.h | 2883 ++++----- gpsbabel/garmin_fs.c | 762 +-- gpsbabel/garmin_fs.h | 93 +- gpsbabel/garmin_gpi.c | 2388 ++++---- gpsbabel/garmin_gpi.h | 206 +- gpsbabel/garmin_tables.c | 1871 +++--- gpsbabel/garmin_tables.h | 53 +- gpsbabel/garmin_txt.c | 1990 +++--- gpsbabel/garmin_xt.c | 661 +- gpsbabel/gbfile.c | 1188 ++-- gpsbabel/gbfile.h | 88 +- gpsbabel/gbser.c | 234 +- gpsbabel/gbser.h | 18 +- gpsbabel/gbser_posix.c | 612 +- gpsbabel/gbser_private.h | 2 +- gpsbabel/gbser_win.c | 621 +- gpsbabel/gbsleep.c | 12 +- gpsbabel/gcdb.c | 413 +- gpsbabel/gdb.c | 2731 +++++---- gpsbabel/geo.c | 340 +- gpsbabel/geoniche.c | 1302 ++-- gpsbabel/ggv_log.c | 403 +- gpsbabel/ggv_ovl.c | 567 +- gpsbabel/globals.c | 2 +- gpsbabel/glogbook.c | 110 +- gpsbabel/gnav_trl.c | 124 +- gpsbabel/google.c | 876 ++- gpsbabel/gopal.c | 561 +- gpsbabel/gpilots.c | 650 +- gpsbabel/gpspilot.c | 298 +- gpsbabel/gpssim.c | 230 +- gpsbabel/gpsutil.c | 225 +- gpsbabel/gpx.c | 3270 +++++----- gpsbabel/grtcirc.c | 324 +- gpsbabel/grtcirc.h | 22 +- gpsbabel/gtm.c | 1146 ++-- gpsbabel/gtrnctr.c | 566 +- gpsbabel/height.c | 187 +- gpsbabel/hiketech.c | 200 +- gpsbabel/holux.c | 413 +- gpsbabel/holux.h | 106 +- gpsbabel/hsa_ndv.c | 705 +-- gpsbabel/html.c | 452 +- gpsbabel/humminbird.c | 1387 +++-- gpsbabel/igc.c | 1369 ++--- gpsbabel/ignrando.c | 249 +- gpsbabel/igo8.c | 412 +- gpsbabel/ik3d.c | 206 +- gpsbabel/inifile.c | 514 +- gpsbabel/inifile.h | 15 +- gpsbabel/internal_styles.c | 2632 ++++---- gpsbabel/interpolate.c | 298 +- gpsbabel/itracku.c | 925 ++- gpsbabel/jeeps/garminusb.h | 44 +- gpsbabel/jeeps/gps.h | 163 +- gpsbabel/jeeps/gpsapp.c | 10164 ++++++++++++++++--------------- gpsbabel/jeeps/gpsapp.h | 212 +- gpsbabel/jeeps/gpscom.c | 1625 +++-- gpsbabel/jeeps/gpscom.h | 56 +- gpsbabel/jeeps/gpsdatum.h | 297 +- gpsbabel/jeeps/gpsdevice.c | 36 +- gpsbabel/jeeps/gpsdevice.h | 58 +- gpsbabel/jeeps/gpsdevice_ser.c | 18 +- gpsbabel/jeeps/gpsdevice_usb.c | 28 +- gpsbabel/jeeps/gpsfmt.c | 2025 +++--- gpsbabel/jeeps/gpsfmt.h | 16 +- gpsbabel/jeeps/gpsinput.c | 3838 ++++++------ gpsbabel/jeeps/gpsinput.h | 10 +- gpsbabel/jeeps/gpslibusb.c | 579 +- gpsbabel/jeeps/gpsmath.c | 2853 ++++----- gpsbabel/jeeps/gpsmath.h | 256 +- gpsbabel/jeeps/gpsmem.c | 333 +- gpsbabel/jeeps/gpsmem.h | 36 +- gpsbabel/jeeps/gpsproj.c | 7001 ++++++++++----------- gpsbabel/jeeps/gpsproj.h | 280 +- gpsbabel/jeeps/gpsprot.c | 598 +- gpsbabel/jeeps/gpsprot.h | 291 +- gpsbabel/jeeps/gpsread.c | 272 +- gpsbabel/jeeps/gpsread.h | 6 +- gpsbabel/jeeps/gpsrqst.c | 172 +- gpsbabel/jeeps/gpsrqst.h | 4 +- gpsbabel/jeeps/gpssend.c | 259 +- gpsbabel/jeeps/gpssend.h | 6 +- gpsbabel/jeeps/gpsserial.c | 589 +- gpsbabel/jeeps/gpsserial.h | 20 +- gpsbabel/jeeps/gpsusbcommon.c | 375 +- gpsbabel/jeeps/gpsusbcommon.h | 12 +- gpsbabel/jeeps/gpsusbread.c | 141 +- gpsbabel/jeeps/gpsusbsend.c | 22 +- gpsbabel/jeeps/gpsusbstub.c | 6 +- gpsbabel/jeeps/gpsusbwin.c | 360 +- gpsbabel/jeeps/gpsutil.c | 528 +- gpsbabel/jeeps/gpsutil.h | 62 +- gpsbabel/jeeps/main.c | 40 +- gpsbabel/jogmap.c | 96 +- gpsbabel/jtr.c | 446 +- gpsbabel/kml.c | 2116 ++++--- gpsbabel/lmx.c | 427 +- gpsbabel/lowranceusr.c | 1660 ++--- gpsbabel/mag_pdb.c | 323 +- gpsbabel/magellan.h | 24 +- gpsbabel/maggeo.c | 482 +- gpsbabel/magnav.c | 351 +- gpsbabel/magproto.c | 2477 ++++---- gpsbabel/main.c | 1263 ++-- gpsbabel/mapasia.c | 341 +- gpsbabel/mapopolis.c | 372 +- gpsbabel/mapsend.c | 875 +-- gpsbabel/mapsend.h | 26 +- gpsbabel/mapsource.c | 3232 +++++----- gpsbabel/mkicondoc.c | 70 +- gpsbabel/mkshort.c | 1129 ++-- gpsbabel/mmo.c | 2101 ++++--- gpsbabel/msroute.c | 1020 ++-- gpsbabel/mtk_logger.c | 2616 ++++---- gpsbabel/navicache.c | 331 +- gpsbabel/naviguide.c | 517 +- gpsbabel/navilink.c | 1550 ++--- gpsbabel/navilink.h | 92 +- gpsbabel/navitel.c | 116 +- gpsbabel/netstumbler.c | 514 +- gpsbabel/nmea.c | 2153 +++---- gpsbabel/nmn4.c | 443 +- gpsbabel/nukedata.c | 54 +- gpsbabel/osm.c | 1048 ++-- gpsbabel/overlay.c | 508 +- gpsbabel/ozi.c | 1411 ++--- gpsbabel/palmdoc.c | 954 +-- gpsbabel/parse.c | 472 +- gpsbabel/pathaway.c | 1221 ++-- gpsbabel/pcx.c | 728 +-- gpsbabel/pdbfile.c | 703 ++- gpsbabel/pdbfile.h | 54 +- gpsbabel/pocketfms_bc.c | 223 +- gpsbabel/pocketfms_fp.c | 180 +- gpsbabel/pocketfms_wp.c | 119 +- gpsbabel/polygon.c | 520 +- gpsbabel/position.c | 287 +- gpsbabel/psitrex.c | 1135 ++-- gpsbabel/psp.c | 535 +- gpsbabel/queue.c | 271 +- gpsbabel/queue.h | 6 +- gpsbabel/quovadis.c | 336 +- gpsbabel/quovadis.h | 20 +- gpsbabel/radius.c | 309 +- gpsbabel/random.c | 323 +- gpsbabel/raymarine.c | 705 +-- gpsbabel/reverse_route.c | 48 +- gpsbabel/rgbcolors.c | 394 +- gpsbabel/route.c | 803 +-- gpsbabel/saroute.c | 750 +-- gpsbabel/sbn.c | 377 +- gpsbabel/sbp.c | 121 +- gpsbabel/session.c | 72 +- gpsbabel/session.h | 20 +- gpsbabel/shape.c | 497 +- gpsbabel/skyforce.c | 492 +- gpsbabel/skytraq.c | 2147 +++---- gpsbabel/smplrout.c | 570 +- gpsbabel/sort.c | 96 +- gpsbabel/stackfilter.c | 384 +- gpsbabel/stmsdf.c | 1135 ++-- gpsbabel/stmwpp.c | 491 +- gpsbabel/strptime.c | 1434 +++-- gpsbabel/strptime.h | 4 +- gpsbabel/subrip.c | 328 +- gpsbabel/swapdata.c | 34 +- gpsbabel/tef_xml.c | 379 +- gpsbabel/teletype.c | 110 +- gpsbabel/text.c | 431 +- gpsbabel/tiger.c | 379 +- gpsbabel/tmpro.c | 367 +- gpsbabel/tomtom.c | 587 +- gpsbabel/tpg.c | 467 +- gpsbabel/tpo.c | 2378 ++++---- gpsbabel/trackfilter.c | 2027 +++--- gpsbabel/transform.c | 248 +- gpsbabel/unicsv.c | 3423 ++++++----- gpsbabel/units.c | 185 +- gpsbabel/util.c | 2416 ++++---- gpsbabel/util_crc.c | 115 +- gpsbabel/uuid.c | 20 +- gpsbabel/v900.c | 523 +- gpsbabel/vcf.c | 140 +- gpsbabel/vecs.c | 2630 ++++---- gpsbabel/vidaone.c | 135 +- gpsbabel/vitosmt.c | 565 +- gpsbabel/vitovtt.c | 154 +- gpsbabel/vmem.c | 51 +- gpsbabel/vpl.c | 156 +- gpsbabel/waypt.c | 889 +-- gpsbabel/wbt-200.c | 1529 ++--- gpsbabel/wfff_xml.c | 301 +- gpsbabel/wintec_tes.c | 130 +- gpsbabel/xcsv.c | 1012 +-- gpsbabel/xhtmlent.c | 1030 ++-- gpsbabel/xmlgeneric.c | 419 +- gpsbabel/xmlgeneric.h | 32 +- gpsbabel/xmltag.c | 238 +- gpsbabel/xol.c | 424 +- gpsbabel/yahoo.c | 78 +- 246 files changed, 91062 insertions(+), 85673 deletions(-) diff --git a/gpsbabel/GPSBabel.pro b/gpsbabel/GPSBabel.pro index ab1c66b31..6d4cd5fbd 100644 --- a/gpsbabel/GPSBabel.pro +++ b/gpsbabel/GPSBabel.pro @@ -6,7 +6,7 @@ CONFIG -= app_bundle TEMPLATE = app -MINIMAL_FMTS = magproto.cc gpx.c geo.c mapsend.c mapsource.c garmin.c \ +MINIMAL_FMTS = magproto.c gpx.c geo.c mapsend.c mapsource.c garmin.c \ garmin_device_xml.c garmin_tables.c internal_styles.c nmea.c \ kml.c wbt-200.c @@ -28,7 +28,7 @@ ALL_FMTS=$$MINIMAL_FMTS gtm.c gpsutil.c pcx.c cetus.c copilot.c \ jtr.c sbp.c sbn.c mmo.c skyforce.c itracku.c v900.c delbin.c \ pocketfms_bc.c pocketfms_fp.c pocketfms_wp.c naviguide.c enigma.c \ vpl.c teletype.c jogmap.c bushnell.c bushnell_trl.c wintec_tes.c \ - subrip.c garmin_xt.c explorist_ini.cc \ + subrip.c garmin_xt.c explorist_ini.c \ FILTERS=position.c radius.c duplicate.c arcdist.c polygon.c smplrout.c \ reverse_route.c sort.c stackfilter.c trackfilter.c discard.c \ diff --git a/gpsbabel/alan.c b/gpsbabel/alan.c index 19800f921..85a0ba47c 100644 --- a/gpsbabel/alan.c +++ b/gpsbabel/alan.c @@ -197,7 +197,8 @@ static arglist_t trl_args[] = { /**************************************************************************/ -static unsigned int byte_order(void) { +static unsigned int byte_order(void) +{ unsigned long test = BYTEORDER_TEST; unsigned char *ptr; unsigned int order; @@ -208,19 +209,22 @@ static unsigned int byte_order(void) { return order; } -static void sw_bytes(void *word) { +static void sw_bytes(void *word) +{ gbuint8 *p = word; gbuint16 *r = word; *r = (gbuint16)(p[1] << 8 | p[0]); } -static void sw_words(void *dword) { +static void sw_words(void *dword) +{ gbuint16 *p = dword; gbuint32 *r = dword; *r = (gbuint32)(p[0] << 16 | p[1]); } -static void rev_bytes(void *dword) { +static void rev_bytes(void *dword) +{ gbuint8 *p = dword; gbuint32 *r = dword; @@ -228,71 +232,79 @@ static void rev_bytes(void *dword) { } static void swap_wpthdr(struct wpthdr *wpthdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ int i; - if ( swap32_func != NULL ) { - swap32_func( &wpthdr->id ); + if (swap32_func != NULL) { + swap32_func(&wpthdr->id); } - if ( swap16_func != NULL ) { - swap16_func( &wpthdr->num ); - swap16_func( &wpthdr->next ); - for (i=0; iidx[i] ); + if (swap16_func != NULL) { + swap16_func(&wpthdr->num); + swap16_func(&wpthdr->next); + for (i=0; iidx[i]); + } } } static void swap_wpt(struct wpt *wpt, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { - if ( swap16_func != NULL ) { - swap16_func( &wpt->usecount ); + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ + if (swap16_func != NULL) { + swap16_func(&wpt->usecount); } - if ( swap32_func != NULL ) { - swap32_func( &wpt->pt.x ); - swap32_func( &wpt->pt.y ); - swap32_func( &wpt->date ); - swap32_func( &wpt->time ); + if (swap32_func != NULL) { + swap32_func(&wpt->pt.x); + swap32_func(&wpt->pt.y); + swap32_func(&wpt->date); + swap32_func(&wpt->time); } } static void swap_rtehdr(struct rtehdr *rtehdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ int i; - if ( swap16_func != NULL) { - swap16_func( &rtehdr->num ); - swap16_func( &rtehdr->next ); - for (i=0; iidx[i] ); - swap16_func( &rtehdr->rteno ); + if (swap16_func != NULL) { + swap16_func(&rtehdr->num); + swap16_func(&rtehdr->next); + for (i=0; iidx[i]); + } + swap16_func(&rtehdr->rteno); } - if ( swap32_func != NULL ) { - swap32_func( &rtehdr->id ); + if (swap32_func != NULL) { + swap32_func(&rtehdr->id); } } static void swap_rte(struct rte *rte, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ int i; if (swap16_func != NULL) { - swap16_func( &rte->wptnum ); - for (i=0; iwptidx[i] ); - swap16_func( &rte->reserved ); + swap16_func(&rte->wptnum); + for (i=0; iwptidx[i]); + } + swap16_func(&rte->reserved); } - if ( swap32_func != NULL ) { - swap32_func( &rte->date ); - swap32_func( &rte->time ); + if (swap32_func != NULL) { + swap32_func(&rte->date); + swap32_func(&rte->time); } } -static void wpr_swap(struct wprdata *wprdata) { +static void wpr_swap(struct wprdata *wprdata) +{ void (*swap16_func)(void *); void (*swap32_func)(void *); int i; - switch( byte_order() ) { + switch (byte_order()) { case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ return; break; @@ -311,69 +323,76 @@ static void wpr_swap(struct wprdata *wprdata) { default: return; /* never reached */ } - - swap_wpthdr( &(wprdata->wpthdr), swap16_func, swap32_func ); - for (i=0; i< MAXWPT; i++) - swap_wpt( &(wprdata->wpt[i]), swap16_func, swap32_func ); - swap_rtehdr( &(wprdata->rtehdr), swap16_func, swap32_func ); - for (i=0; irte[i]), swap16_func, swap32_func ); + + swap_wpthdr(&(wprdata->wpthdr), swap16_func, swap32_func); + for (i=0; i< MAXWPT; i++) { + swap_wpt(&(wprdata->wpt[i]), swap16_func, swap32_func); + } + swap_rtehdr(&(wprdata->rtehdr), swap16_func, swap32_func); + for (i=0; irte[i]), swap16_func, swap32_func); + } } static void swap_trkhdr(struct trkhdr *trkhdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { - if ( swap16_func != NULL ) { - swap16_func( &(trkhdr->totalpt) ); - swap16_func( &(trkhdr->next) ); + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ + if (swap16_func != NULL) { + swap16_func(&(trkhdr->totalpt)); + swap16_func(&(trkhdr->next)); } - if ( swap32_func != NULL ) { - swap32_func( &(trkhdr->occupied) ); - swap32_func( &(trkhdr->show) ); - swap32_func( &(trkhdr->fill) ); + if (swap32_func != NULL) { + swap32_func(&(trkhdr->occupied)); + swap32_func(&(trkhdr->show)); + swap32_func(&(trkhdr->fill)); } } static void swap_loghdr(struct loghdr *loghdr, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ int i; - if ( swap16_func != NULL ) { - swap16_func( &(loghdr->num) ); - swap16_func( &(loghdr->next) ); + if (swap16_func != NULL) { + swap16_func(&(loghdr->num)); + swap16_func(&(loghdr->next)); } - if ( swap32_func != NULL ) { - swap32_func( &(loghdr->id) ); - swap32_func( &(loghdr->date) ); - swap32_func( &(loghdr->time) ); + if (swap32_func != NULL) { + swap32_func(&(loghdr->id)); + swap32_func(&(loghdr->date)); + swap32_func(&(loghdr->time)); + } + for (i=0; itrkhdr[i]), swap16_func, swap32_func); } - for (i=0; itrkhdr[i]), swap16_func, swap32_func ); } static void swap_trklog(struct trklog *trklog, - void (*swap16_func)(void *), void (*swap32_func)(void *)) { + void (*swap16_func)(void *), void (*swap32_func)(void *)) +{ int i; - if ( swap16_func != NULL ) { + if (swap16_func != NULL) { for (i=0; ish[i].speed) ); - swap16_func( &(trklog->sh[i].height) ); + swap16_func(&(trklog->sh[i].speed)); + swap16_func(&(trklog->sh[i].height)); } } - if ( swap32_func != NULL ) { + if (swap32_func != NULL) { for (i=0; ipt[i].x) ); - swap32_func( &(trklog->pt[i].y) ); + swap32_func(&(trklog->pt[i].x)); + swap32_func(&(trklog->pt[i].y)); } } } -static void trl_swap(struct trldata *trldata) { +static void trl_swap(struct trldata *trldata) +{ void (*swap16_func)(void *); void (*swap32_func)(void *); int i; - switch( byte_order() ) { + switch (byte_order()) { case SWAP_NONE: /* same byte oder, LITTLE_ENDIAN */ return; break; @@ -393,33 +412,38 @@ static void trl_swap(struct trldata *trldata) { return; /* never reached */ } - swap_loghdr( &(trldata->loghdr), swap16_func, swap32_func); - for (i=0; itrklog[i]), swap16_func, swap32_func); + swap_loghdr(&(trldata->loghdr), swap16_func, swap32_func); + for (i=0; itrklog[i]), swap16_func, swap32_func); + } } /**************************************************************************/ -static void str2lab(char *dest, char *src, int len, char *fmt, int n) { +static void str2lab(char *dest, char *src, int len, char *fmt, int n) +{ int i,j; j = 0; if (src != NULL) { for (i=0; i> 16) & 0xffff; month = (date >> 8) & 0xff; /* 1-12 */ @@ -439,14 +464,15 @@ static time_t unpack_time(gbint32 date, gbint32 time) { month -= 1; /* fit struct tm */ year += month / 12; - + if (month < 0) { year -= 1; month += 12; } result = (year - 1970) * 365 + m_to_d[month]; - if (month <= 1) + if (month <= 1) { year -= 1; + } result += (year - 1968) / 4; result -= (year - 1900) / 100; result += (year - 1600) / 400; @@ -454,13 +480,14 @@ static time_t unpack_time(gbint32 date, gbint32 time) { result -= 1; result *= 86400; result += time; /* map500 time is inseconds of the day */ - + return result; } /**************************************************************************/ -static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) { +static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) +{ struct wpthdr *wpthdr; struct wpt *wpt; int j, idx; @@ -469,27 +496,30 @@ static waypoint * get_wpt(struct wprdata *wprdata, unsigned n) { wpthdr = &(wprdata->wpthdr); idx = wpthdr->idx[n]; - if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) + if (idx == WPT_IDX_NONE || wpthdr->used[idx] == WPT_UNUSED) { return NULL; + } wpt = &(wprdata->wpt[idx]); - + WP = waypt_new(); WP->latitude = -pt2deg(wpt->pt.y); WP->longitude = pt2deg(wpt->pt.x); WP->creation_time = unpack_time(wpt->date, wpt->time); - for(j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; + for (j=WPT_NAME_LEN-1; j >= 0 && wpt->name[j] == ' '; j--) {}; WP->shortname = xstrndup(wpt->name,j+1); - for(j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; - if (j >= 0) + for (j=WPT_COMMENT_LEN-1; j >= 0 && wpt->comment[j] == ' '; j--) {}; + if (j >= 0) { WP->description = xstrndup(wpt->comment, j+1); - else + } else { WP->description = xstrdup(""); + } WP->notes = xstrdup(""); return WP; } -static void wpr_read(void) { +static void wpr_read(void) +{ struct wprdata wprdata; struct rtehdr *rtehdr; struct rte *rte; @@ -497,50 +527,57 @@ static void wpr_read(void) { waypoint *WP; route_head *RT; - if ( gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1 ) + if (gbfread(&wprdata, sizeof(struct wprdata), 1, fin) != 1) { fatal(MYNAME ": Read error on %s\n", fin->name); + } wpr_swap(&wprdata); - if ( wprdata.wpthdr.id != WPT_HDR_ID || - wprdata.rtehdr.id != RTE_HDR_ID ) + if (wprdata.wpthdr.id != WPT_HDR_ID || + wprdata.rtehdr.id != RTE_HDR_ID) { fatal(MYNAME ": %s is not in Alan .wpr format.\n", fin->name); + } /* waypoints */ for (i=0; iidx[i]; - if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) + if (idx == RTE_IDX_NONE || rtehdr->used[idx] == RTE_UNUSED) { continue; + } rte = &(wprdata.rte[idx]); - + RT = route_head_alloc(); RT->rte_num = i; - for(j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; + for (j=RTE_NAME_LEN-1; j >= 0 && rte->name[j] == ' '; j--) {}; RT->rte_name = xstrndup(rte->name,j+1); - for(j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; - if (j >= 0) + for (j=RTE_COMMENT_LEN-1; j >= 0 && rte->comment[j] == ' '; j--) {}; + if (j >= 0) { RT->rte_desc = xstrndup(rte->comment,j+1); - else + } else { RT->rte_desc = xstrdup(""); + } - route_add_head(RT); + route_add_head(RT); /* route points */ - for(j=0; jwptnum; j++) { + for (j=0; jwptnum; j++) { WP = get_wpt(&wprdata, rte->wptidx[j]); - if ( WP != NULL ) - route_add_wpt(RT, WP); + if (WP != NULL) { + route_add_wpt(RT, WP); + } } } } -static void trl_read(void) { +static void trl_read(void) +{ struct trldata trldata; struct trkhdr *trkhdr; struct trklog *trklog; @@ -550,47 +587,52 @@ static void trl_read(void) { for (i=0; iname); + } } gbfseek(fin, 0x10000 * MAXTRK/2, SEEK_SET); - if ( gbfread( &(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) + if (gbfread(&(trldata.loghdr), sizeof(struct loghdr), 1, fin) != 1) { fatal(MYNAME ": Read error on %s\n", fin->name); + } trl_swap(&trldata); - if ( trldata.loghdr.id != TRL_HDR_ID ) + if (trldata.loghdr.id != TRL_HDR_ID) { fatal(MYNAME ": %s is not in Alan .trl format.\n", fin->name); + } - for(i=0; ioccupied == TRK_UNUSED) + if (trkhdr->occupied == TRK_UNUSED) { continue; + } TL = route_head_alloc(); - for(j=TRK_NAME_LEN-1; - j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); - j--) {}; + for (j=TRK_NAME_LEN-1; + j >= 0 && (trkhdr->name[j] == ' ' || trkhdr->name[j] == '\0'); + j--) {}; TL->rte_name = xstrndup(trkhdr->name,j+1); -/* TL->rte_name[TRK_NAME_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ - for(j=TRK_COMMENT_LEN-1; - j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); - j--) {}; + /* TL->rte_name[TRK_NAME_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ + for (j=TRK_COMMENT_LEN-1; + j >= 0 && (trkhdr->comment[j] == ' ' || trkhdr->comment[j] == '\0'); + j--) {}; TL->rte_desc = xstrndup(trkhdr->comment,j+1); -/* TL->rte_desc[TRK_COMMENT_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ + /* TL->rte_desc[TRK_COMMENT_LEN+1] = 0; */ /* MAYBE BAD ADDRESS (Valgrind) */ TL->rte_num = i; - track_add_head(TL); + track_add_head(TL); /* track points */ trklog = &(trldata.trklog[i]); - for(j=0; jtotalpt; j++) { + for (j=0; jtotalpt; j++) { WP = waypt_new(); WP->latitude = -pt2deg(trklog->pt[j].y); WP->longitude = pt2deg(trklog->pt[j].x); WP->altitude = hgt2m(trklog->sh[j].height); - if ( trklog->sh[j].speed >= 0 ) - WAYPT_SET(WP, speed, sp2mps(trklog->sh[j].speed)) - else /* bad speed < 0 - set to 0.0 */ - WAYPT_UNSET(WP, speed); + if (trklog->sh[j].speed >= 0) + WAYPT_SET(WP, speed, sp2mps(trklog->sh[j].speed)) + else { /* bad speed < 0 - set to 0.0 */ + WAYPT_UNSET(WP, speed); + } track_add_wpt(TL, WP); } } @@ -598,7 +640,8 @@ static void trl_read(void) { /**************************************************************************/ -static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { +static int find_wpt(struct wprdata *wprdata, const waypoint *WP) +{ struct wpt pattern, *wpt; int i, wpt_idx; @@ -608,20 +651,23 @@ static int find_wpt(struct wprdata *wprdata, const waypoint *WP) { wpt = wprdata->wpt; for (i=0; iwpthdr.idx[i]; - if ( wpt_idx == WPT_IDX_NONE || - wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED ) + wpt_idx = wprdata->wpthdr.idx[i]; + if (wpt_idx == WPT_IDX_NONE || + wprdata->wpthdr.used[wpt_idx] == WPT_UNUSED) { continue; - if ( strncmp( wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && - wpt[wpt_idx].pt.x == pattern.pt.x && - wpt[wpt_idx].pt.y == pattern.pt.y ) + } + if (strncmp(wpt[wpt_idx].name, pattern.name, WPT_NAME_LEN) == 0 && + wpt[wpt_idx].pt.x == pattern.pt.x && + wpt[wpt_idx].pt.y == pattern.pt.y) { return i; + } } return -1; } -static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { +static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) +{ struct wpthdr *wpthdr; int hdr_idx, wpt_idx; struct wpt *wpt; @@ -630,7 +676,7 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { wpthdr = &(wprdata->wpthdr); hdr_idx = find_wpt(wprdata, WP); - if ( hdr_idx >= 0 ) { + if (hdr_idx >= 0) { /* duplicate waypoint */ if (isroute) { wpt = &(wprdata->wpt[wpthdr->idx[hdr_idx]]); @@ -638,7 +684,7 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { } /* warning(MYNAME ": using duplicate waypoint '%s' at (%f°, %f°)\n", - WP->shortname, WP->latitude, WP->longitude); + WP->shortname, WP->latitude, WP->longitude); */ return hdr_idx; } @@ -647,8 +693,9 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { hdr_idx = i; for (i=0; iused[i] != WPT_UNUSED; i++) { } wpt_idx = i; - if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT ) + if (wpthdr->num >= MAXWPT || hdr_idx >= MAXWPT || wpt_idx >= MAXWPT) { fatal(MYNAME ": Can't store more than %u waypoints\n", MAXWPT); + } wpt = &(wprdata->wpt[wpt_idx]); str2lab(wpt->name, WP->shortname, WPT_NAME_LEN, "W%05d", wpt_idx); @@ -664,29 +711,33 @@ static int add_wpt(struct wprdata *wprdata, const waypoint *WP,int isroute) { wpthdr->used[wpt_idx] = WPT_USED; wpthdr->num++; wpthdr->next++; - if (wpthdr->next >= MAXWPT) /* overrun */ + if (wpthdr->next >= MAXWPT) { /* overrun */ wpthdr->next = 0; + } return hdr_idx; } -static void wpr_waypoint(const waypoint *WP) { +static void wpr_waypoint(const waypoint *WP) +{ add_wpt(&WPR, WP, 0); } -static void wpr_route_hdr(const route_head *RT) { +static void wpr_route_hdr(const route_head *RT) +{ struct rtehdr *rtehdr; int hdr_idx, rte_idx; struct rte *rte; int i; - + rtehdr = &(WPR.rtehdr); for (i=0; iidx[i] != RTE_IDX_NONE; i++) { } hdr_idx = i; for (i=0; iused[i] != RTE_UNUSED; i++) { } rte_idx = i; - if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE ) + if (rtehdr->num >= MAXRTE || hdr_idx >= MAXRTE || rte_idx >= MAXRTE) { fatal(MYNAME ": Can't store more than %u routes", MAXRTE); + } rte = &(WPR.rte[rte_idx]); str2lab(rte->name, RT->rte_name, RTE_NAME_LEN, "R%03d", rte_idx); @@ -697,20 +748,23 @@ static void wpr_route_hdr(const route_head *RT) { rtehdr->used[rte_idx] = RTE_USED; rtehdr->num++; rtehdr->next++; - if (rtehdr->next >= MAXRTE) /* overrun */ + if (rtehdr->next >= MAXRTE) { /* overrun */ rtehdr->next = 0; + } /* if you want the new route to be active, uncomment the next line */ /* rtehdr->rteno = rte_idx; */ } -static void wpr_route_wpt(const waypoint *WP) { +static void wpr_route_wpt(const waypoint *WP) +{ struct rte *rte; int wpt_idx; rte = &(WPR.rte[WPR.rtehdr.num -1]); - if ( rte->wptnum >= MAXWPTINRTE ) + if (rte->wptnum >= MAXWPTINRTE) { fatal(MYNAME ": Can't store more than %u waypoints per route", MAXWPTINRTE); + } wpt_idx = add_wpt(&WPR, WP, 1); @@ -718,11 +772,13 @@ static void wpr_route_wpt(const waypoint *WP) { rte->wptnum ++; } -static void wpr_route_trl(const route_head *RT) { +static void wpr_route_trl(const route_head *RT) +{ /* should we do some final sanity checks? */ } -static void wpr_write(void) { +static void wpr_write(void) +{ int i; WPR.wpthdr.id = WPT_HDR_ID; @@ -745,33 +801,39 @@ static void wpr_write(void) { route_disp_all(wpr_route_hdr, wpr_route_trl, wpr_route_wpt); wpr_swap(&WPR); - if ( gbfwrite(&WPR, sizeof(struct wprdata), 1, fout) != 1 ) + if (gbfwrite(&WPR, sizeof(struct wprdata), 1, fout) != 1) { fatal(MYNAME ": Write error on %s\n", fout->name); + } } /**************************************************************************/ -static void trl_track_hdr(const route_head *TL) { +static void trl_track_hdr(const route_head *TL) +{ struct trkhdr *trkhdr; int idx, l; trkhdr = TRL.loghdr.trkhdr; - + for (idx=0; idx< MAXTRK && trkhdr[idx].occupied != TRK_UNUSED; idx++) {}; - if (idx >= MAXTRK) + if (idx >= MAXTRK) { fatal(MYNAME ": Can't store more than %u tracklogs", MAXTRK); + } - if ( TL->rte_name != NULL ) + if (TL->rte_name != NULL) { strncpy(trkhdr[idx].name, TL->rte_name, TRK_NAME_LEN); - if ( *(trkhdr[idx].name) == '\0' ) + } + if (*(trkhdr[idx].name) == '\0') { sprintf(trkhdr[idx].name, "T%03d", idx); + } trkhdr[idx].name[TRK_NAME_LEN-1] = '\0'; - if ( TL->rte_desc != NULL ) { + if (TL->rte_desc != NULL) { strncpy(trkhdr[idx].comment, TL->rte_desc, TRK_COMMENT_LEN); l = strlen(TL->rte_desc); - if ( l < TRK_COMMENT_LEN-1 ) + if (l < TRK_COMMENT_LEN-1) { memset(trkhdr[idx].comment + l, ' ', TRK_COMMENT_LEN - l); + } } trkhdr[idx].comment[TRK_COMMENT_LEN-1] = '\0'; @@ -783,44 +845,51 @@ static void trl_track_hdr(const route_head *TL) { TRL.loghdr.num = idx; } -static void trl_track_wpt(const waypoint *WP) { +static void trl_track_wpt(const waypoint *WP) +{ struct trklog *trklog; struct trkhdr *trkhdr; int trk_idx, log_idx; - + trk_idx = TRL.loghdr.num; trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); - if ( trkhdr->totalpt >= MAXPTINTRK ) + if (trkhdr->totalpt >= MAXPTINTRK) { fatal(MYNAME ": Can't store more than %u points per track", MAXPTINTRK); + } log_idx = trkhdr->next; trklog = &(TRL.trklog[trk_idx]); - trklog->pt[log_idx].x = deg2pt( WP->longitude); + trklog->pt[log_idx].x = deg2pt(WP->longitude); trklog->pt[log_idx].y = deg2pt(-WP->latitude); - if WAYPT_HAS(WP, speed) + if WAYPT_HAS(WP, speed) { trklog->sh[log_idx].speed = mps2sp(WP->speed); - if ( WP->altitude != unknown_alt ) + } + if (WP->altitude != unknown_alt) { trklog->sh[log_idx].height = m2hgt(WP->altitude); + } trkhdr->totalpt ++; trkhdr->next = trkhdr->totalpt; } -static void trl_track_tlr(const route_head *TL) { +static void trl_track_tlr(const route_head *TL) +{ struct trkhdr *trkhdr; int trk_idx; trk_idx = TRL.loghdr.num; trkhdr = &(TRL.loghdr.trkhdr[trk_idx]); - if ( trkhdr->totalpt == 0 ) + if (trkhdr->totalpt == 0) { trkhdr->occupied = TRK_UNUSED; + } TRL.loghdr.num = -1; } -static void trl_write(void) { +static void trl_write(void) +{ struct trkhdr *trkhdr; void *buf; int i; @@ -845,96 +914,105 @@ static void trl_write(void) { track_disp_all(trl_track_hdr, trl_track_tlr, trl_track_wpt); trl_swap(&TRL); - + fill = 0x10000 - 2 * sizeof(struct trklog); buf = xmalloc(fill); - if (buf == NULL) + if (buf == NULL) { fatal(MYNAME ": Not enough memory\n"); + } memset(buf, 0xff, fill); for (i=0; iname); + } } xfree(buf); fill = 0x1000 - sizeof(struct loghdr); buf = xmalloc(fill); - if (buf == NULL) + if (buf == NULL) { fatal(MYNAME ": Not enough memory\n"); + } memset(buf, 0xff, fill); - if ( gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || - gbfwrite(buf, fill, 1, fout) != 1 ) + if (gbfwrite(&(TRL.loghdr), sizeof(struct loghdr), 1, fout) != 1 || + gbfwrite(buf, fill, 1, fout) != 1) { fatal(MYNAME ": Write error on %s\n", fout->name); + } xfree(buf); } /**************************************************************************/ -static void alan_rd_init(const char *fname) { +static void alan_rd_init(const char *fname) +{ fin = gbfopen(fname, "rb", MYNAME); } -static void alan_rd_deinit(void) { +static void alan_rd_deinit(void) +{ gbfclose(fin); fin = NULL; } -static void alan_wr_init(const char *fname) { +static void alan_wr_init(const char *fname) +{ fout = gbfopen(fname, "wb", MYNAME); } -static void alan_wr_deinit(void) { +static void alan_wr_deinit(void) +{ gbfclose(fout); fout = NULL; } -static void alan_exit(void) { +static void alan_exit(void) +{ return; } /**************************************************************************/ ff_vecs_t alanwpr_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - alan_rd_init, - alan_wr_init, - alan_rd_deinit, - alan_wr_deinit, - wpr_read, - wpr_write, - alan_exit, - wpr_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command - line parameter */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + wpr_read, + wpr_write, + alan_exit, + wpr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ }; ff_vecs_t alantrl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - alan_rd_init, - alan_wr_init, - alan_rd_deinit, - alan_wr_deinit, - trl_read, - trl_write, - alan_exit, - trl_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command - line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + alan_rd_init, + alan_wr_init, + alan_rd_deinit, + alan_wr_deinit, + trl_read, + trl_write, + alan_exit, + trl_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command + line parameter */ }; diff --git a/gpsbabel/an1.c b/gpsbabel/an1.c index a0460fd72..ea87f6d8b 100644 --- a/gpsbabel/an1.c +++ b/gpsbabel/an1.c @@ -51,40 +51,58 @@ static long serial=10000; static long rtserial=1; typedef struct roadchange { - long type; - char *name; + long type; + char *name; } roadchange; roadchange *roadchanges = NULL; static arglist_t an1_args[] = { - {"type", &output_type, "Type of .an1 file", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"road", &road_changes, "Road type changes", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"nogc", &nogc, "Do not add geocache data to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nourl", &nourl, "Do not add URLs to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"deficon", &opt_symbol, "Symbol to use for point data", - "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX }, - {"color", &opt_color, "Color for lines or mapnotes", - "red", ARGTYPE_STRING, ARG_NOMINMAX }, - {"zoom", &opt_zoom, "Zoom level to reduce points", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"wpt_type", &opt_wpt_type, - "Waypoint type", - "", ARGTYPE_STRING, ARG_NOMINMAX }, - {"radius", &opt_radius, "Radius for circles", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "type", &output_type, "Type of .an1 file", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "road", &road_changes, "Road type changes", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "nogc", &nogc, "Do not add geocache data to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nourl", &nourl, "Do not add URLs to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "deficon", &opt_symbol, "Symbol to use for point data", + "Red Flag", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "color", &opt_color, "Color for lines or mapnotes", + "red", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "zoom", &opt_zoom, "Zoom level to reduce points", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "wpt_type", &opt_wpt_type, + "Waypoint type", + "", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "radius", &opt_radius, "Radius for circles", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct guid { - unsigned long l; - unsigned short s[3]; - unsigned char c[6]; + unsigned long l; + unsigned short s[3]; + unsigned char c[6]; } GUID; #include "an1sym.h" @@ -97,1135 +115,1141 @@ typedef struct guid { #define WriteDouble(f,d) gbfputdbl((d),f) static char * -ReadString( gbfile * f, short len ) +ReadString(gbfile * f, short len) { - char *result = NULL; - result = (char *)xcalloc( 1, len + 1 ); - if ( len ) { - gbfread( result, 1, len, f ); - } - return result; + char *result = NULL; + result = (char *)xcalloc(1, len + 1); + if (len) { + gbfread(result, 1, len, f); + } + return result; } #define ReadChar(f) (unsigned char) gbfgetc(f) #define WriteChar(f,c) gbfputc((unsigned char)(c),f) #define WriteString(f,s) gbfputs((s),f) -static void -ReadGuid( gbfile *f, GUID *guid ) +static void +ReadGuid(gbfile *f, GUID *guid) { - int i = 0; - guid->l = ReadLong( f ); - for ( i = 0; i < 3; i++ ) { - guid->s[i] = ReadShort( f ); - } - for ( i = 0; i < 6; i++ ) { - guid->c[i] = ReadChar( f ); - } + int i = 0; + guid->l = ReadLong(f); + for (i = 0; i < 3; i++) { + guid->s[i] = ReadShort(f); + } + for (i = 0; i < 6; i++) { + guid->c[i] = ReadChar(f); + } } -static void -WriteGuid( gbfile *f, GUID *guid ) +static void +WriteGuid(gbfile *f, GUID *guid) { - int i = 0; - WriteLong( f, guid->l ); - for ( i = 0; i < 3; i++ ) { - WriteShort( f, guid->s[i] ); - } - for ( i = 0; i < 6; i++ ) { - WriteChar( f, guid->c[i] ); - } -} + int i = 0; + WriteLong(f, guid->l); + for (i = 0; i < 3; i++) { + WriteShort(f, guid->s[i]); + } + for (i = 0; i < 6; i++) { + WriteChar(f, guid->c[i]); + } +} static void Skip(gbfile * f, unsigned long distance) { - gbfseek(f, distance, SEEK_CUR); + gbfseek(f, distance, SEEK_CUR); } static double -DecodeOrd( long ord ) +DecodeOrd(long ord) { - return (double)((gbint32)(0x80000000 - ord)) / 0x800000; + return (double)((gbint32)(0x80000000 - ord)) / 0x800000; } static long -EncodeOrd( double ord ) +EncodeOrd(double ord) { - return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); + return (gbint32)(0x80000000 - (gbint32)(ord * 0x800000)); } typedef struct { - short hotspotxhi; - long hotspoty; - long unk1; - GUID guid; - char *name; + short hotspotxhi; + long hotspoty; + long unk1; + GUID guid; + char *name; } an1_symbol_record; typedef struct { - format_specific_data fs; - short magic; - long unk1; - long lon; - long lat; - short type; - long height; - long width; - short unk2; - short unk3; - short serial; - short unk4; - unsigned char create_zoom; - unsigned char visible_zoom; - short unk5; - double radius; /* in km */ - char *name; - char *fontname; - GUID guid; - long fontcolor; - long fontstyle; - long fontsize; - long outlineweight; - long outlinecolor; - long outlineflags; - long fillcolor; - long unk6; - long fillflags; - - /* Added in SA2006/Topo 6.0 */ - short unk6_1; - char *url; - char *comment; - long creation_time; - long modification_time; - char *image_name; + format_specific_data fs; + short magic; + long unk1; + long lon; + long lat; + short type; + long height; + long width; + short unk2; + short unk3; + short serial; + short unk4; + unsigned char create_zoom; + unsigned char visible_zoom; + short unk5; + double radius; /* in km */ + char *name; + char *fontname; + GUID guid; + long fontcolor; + long fontstyle; + long fontsize; + long outlineweight; + long outlinecolor; + long outlineflags; + long fillcolor; + long unk6; + long fillflags; + + /* Added in SA2006/Topo 6.0 */ + short unk6_1; + char *url; + char *comment; + long creation_time; + long modification_time; + char *image_name; } an1_waypoint_record; typedef struct { - format_specific_data fs; - short magic; - long unk0; - long lon; - long lat; - short unk1; + format_specific_data fs; + short magic; + long unk0; + long lon; + long lat; + short unk1; } an1_vertex_record; typedef struct { - format_specific_data fs; - long roadtype; - short serial; - long unk2; - short unk3; - short type; - long unk4; - char *name; - long lineweight; - long linestyle; - long linecolor; - long opacity; - long polyfillcolor; - long unk6; - long unk7; - short unk8; - long pointcount; + format_specific_data fs; + long roadtype; + short serial; + long unk2; + short unk3; + short type; + long unk4; + char *name; + long lineweight; + long linestyle; + long linecolor; + long opacity; + long polyfillcolor; + long unk6; + long unk7; + short unk8; + long pointcount; } an1_line_record; -static an1_waypoint_record *Alloc_AN1_Waypoint( ); - -void Destroy_AN1_Waypoint( void *vwpt ) { - - an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; - xfree( wpt->name ); - xfree( wpt->fontname ); - if ( wpt->url ) xfree( wpt->url ); - if ( wpt->comment ) xfree( wpt->comment ); - if ( wpt->image_name ) xfree( wpt->image_name ); - xfree( vwpt ); +static an1_waypoint_record *Alloc_AN1_Waypoint(); + +void Destroy_AN1_Waypoint(void *vwpt) +{ + + an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; + xfree(wpt->name); + xfree(wpt->fontname); + if (wpt->url) { + xfree(wpt->url); + } + if (wpt->comment) { + xfree(wpt->comment); + } + if (wpt->image_name) { + xfree(wpt->image_name); + } + xfree(vwpt); } -void Copy_AN1_Waypoint( void **vdwpt, void *vwpt ) { - an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; - an1_waypoint_record *dwpt = Alloc_AN1_Waypoint(); - memcpy( dwpt, wpt, sizeof( an1_waypoint_record )); - dwpt->name = xstrdup( wpt->name ); - dwpt->fontname = xstrdup( wpt->fontname ); - dwpt->url = xstrdup( wpt->url ); - dwpt->comment = xstrdup( wpt->comment ); - dwpt->image_name = xstrdup( wpt->image_name ); - *vdwpt = (void *)dwpt; +void Copy_AN1_Waypoint(void **vdwpt, void *vwpt) +{ + an1_waypoint_record *wpt = (an1_waypoint_record *)vwpt; + an1_waypoint_record *dwpt = Alloc_AN1_Waypoint(); + memcpy(dwpt, wpt, sizeof(an1_waypoint_record)); + dwpt->name = xstrdup(wpt->name); + dwpt->fontname = xstrdup(wpt->fontname); + dwpt->url = xstrdup(wpt->url); + dwpt->comment = xstrdup(wpt->comment); + dwpt->image_name = xstrdup(wpt->image_name); + *vdwpt = (void *)dwpt; } -static an1_waypoint_record *Alloc_AN1_Waypoint( ) { - an1_waypoint_record *result = NULL; - result = (an1_waypoint_record *)xcalloc( sizeof(*result), 1 ); - result->fs.type = FS_AN1W; - result->fs.copy = Copy_AN1_Waypoint; - result->fs.destroy = Destroy_AN1_Waypoint; - result->fs.convert = NULL; - return result; +static an1_waypoint_record *Alloc_AN1_Waypoint() +{ + an1_waypoint_record *result = NULL; + result = (an1_waypoint_record *)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1W; + result->fs.copy = Copy_AN1_Waypoint; + result->fs.destroy = Destroy_AN1_Waypoint; + result->fs.convert = NULL; + return result; } - + static an1_vertex_record *Alloc_AN1_Vertex(); -void Destroy_AN1_Vertex( void *vvertex ) { - xfree( vvertex ); +void Destroy_AN1_Vertex(void *vvertex) +{ + xfree(vvertex); } -void Copy_AN1_Vertex( void **vdvert, void *vvert ) { - an1_vertex_record *vert = (an1_vertex_record *)vvert; - an1_vertex_record *dvert = Alloc_AN1_Vertex(); - memcpy( dvert, vert, sizeof( an1_vertex_record )); - *vdvert = (void *)dvert; +void Copy_AN1_Vertex(void **vdvert, void *vvert) +{ + an1_vertex_record *vert = (an1_vertex_record *)vvert; + an1_vertex_record *dvert = Alloc_AN1_Vertex(); + memcpy(dvert, vert, sizeof(an1_vertex_record)); + *vdvert = (void *)dvert; } -static an1_vertex_record *Alloc_AN1_Vertex() { - an1_vertex_record *result = NULL; - result = (an1_vertex_record *)xcalloc( sizeof( *result), 1 ); - result->fs.type = FS_AN1V; - result->fs.copy = Copy_AN1_Vertex; - result->fs.destroy = Destroy_AN1_Vertex; - result->fs.convert = NULL; - return result; +static an1_vertex_record *Alloc_AN1_Vertex() +{ + an1_vertex_record *result = NULL; + result = (an1_vertex_record *)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1V; + result->fs.copy = Copy_AN1_Vertex; + result->fs.destroy = Destroy_AN1_Vertex; + result->fs.convert = NULL; + return result; } - + static an1_line_record *Alloc_AN1_Line(); -void Destroy_AN1_Line( void *vline ) { - an1_line_record *line = (an1_line_record *)vline; - xfree( line->name ); - xfree( vline ); +void Destroy_AN1_Line(void *vline) +{ + an1_line_record *line = (an1_line_record *)vline; + xfree(line->name); + xfree(vline); } -void Copy_AN1_Line( void **vdline, void *vline ) { - an1_line_record *line = (an1_line_record *)vline; - an1_line_record *dline = Alloc_AN1_Line(); - memcpy( dline, line, sizeof( an1_line_record )); - dline->name = xstrdup( line->name ); - *vdline = (void *)dline; +void Copy_AN1_Line(void **vdline, void *vline) +{ + an1_line_record *line = (an1_line_record *)vline; + an1_line_record *dline = Alloc_AN1_Line(); + memcpy(dline, line, sizeof(an1_line_record)); + dline->name = xstrdup(line->name); + *vdline = (void *)dline; } -static an1_line_record *Alloc_AN1_Line( ) { - an1_line_record *result = NULL; - result = (an1_line_record *)xcalloc( sizeof(*result), 1 ); - result->fs.type = FS_AN1L; - result->fs.copy = Copy_AN1_Line; - result->fs.destroy = Destroy_AN1_Line; - result->fs.convert = NULL; - return result; +static an1_line_record *Alloc_AN1_Line() +{ + an1_line_record *result = NULL; + result = (an1_line_record *)xcalloc(sizeof(*result), 1); + result->fs.type = FS_AN1L; + result->fs.copy = Copy_AN1_Line; + result->fs.destroy = Destroy_AN1_Line; + result->fs.convert = NULL; + return result; } -static void Destroy_AN1_Symbol( an1_symbol_record *symbol ) { - xfree( symbol->name ); +static void Destroy_AN1_Symbol(an1_symbol_record *symbol) +{ + xfree(symbol->name); } -static void Read_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { - short len; - - wpt->magic = ReadShort( f ); - wpt->unk1 = ReadLong( f ); - wpt->lon = ReadLong( f ); - wpt->lat = ReadLong( f ); - wpt->type = ReadShort( f ); - wpt->height = ReadLong( f ); - wpt->width = ReadLong( f ); - wpt->unk2 = ReadShort( f ); - wpt->unk3 = ReadShort( f ); - wpt->serial = ReadShort( f ); - wpt->unk4 = ReadShort( f ); - wpt->create_zoom = ReadChar( f ); - wpt->visible_zoom = ReadChar( f ); - wpt->unk5 = ReadShort( f ); - wpt->radius = ReadDouble( f ); - len = ReadShort( f ); - wpt->name = ReadString( f, len ); - - if ( len != strlen(wpt->name)) { - /* This happens in 06/6.0 files that put extra data in the - * name record for backward compatibility's sake */ - char *ofs = wpt->name + strlen( wpt->name ) + 1; - wpt->unk6_1 = le_read16( ofs ); - ofs += 2; - - len = le_read16( ofs ); - ofs += 2; - - if ( len ) { - char *oldurlstr; - /* - * Trust URL encoded in new format over one in - * old format if both are present. Whack the - * name starting at '{URL='. - */ - oldurlstr = strstr(wpt->name, "{URL="); - if (oldurlstr) { - *oldurlstr = 0; - } - - wpt->url = xcalloc( len+1, 1 ); - memcpy( wpt->url, ofs, len ); - ofs += len; - } - - len = le_read16( ofs ); - ofs += 2; - - if ( len ) { - wpt->comment = xcalloc( len+1, 1 ); - memcpy( wpt->comment, ofs, len ); - ofs += len; - } - - /* these are quadwords, presumably for year-2038 compat. */ - wpt->creation_time = le_read32( ofs ); - ofs += 8; - - wpt->modification_time = le_read32( ofs ); - ofs += 8; - } - - if ( wpt->type == 0x12 ) { - /* 'image' type */ - ReadShort( f ); /* length of font + filename */ - len = ReadShort( f ); - wpt->fontname = ReadString( f, len ); - len = ReadShort( f ); - wpt->image_name = ReadString( f, len ); - } - else { - len = ReadShort( f ); - wpt->fontname = ReadString( f, len ); - wpt->image_name = NULL; - } - ReadGuid( f, &wpt->guid ); - wpt->fontcolor = ReadLong( f ); - wpt->fontstyle = ReadLong( f ); - wpt->fontsize = ReadLong( f ); - wpt->outlineweight = ReadLong( f ); - wpt->outlinecolor = ReadLong( f ); - wpt->outlineflags = ReadLong( f ); - wpt->fillcolor = ReadLong( f ); - wpt->unk6 = ReadLong( f ); - wpt->fillflags = ReadLong( f ); +static void Read_AN1_Waypoint(gbfile *f, an1_waypoint_record *wpt) +{ + short len; + + wpt->magic = ReadShort(f); + wpt->unk1 = ReadLong(f); + wpt->lon = ReadLong(f); + wpt->lat = ReadLong(f); + wpt->type = ReadShort(f); + wpt->height = ReadLong(f); + wpt->width = ReadLong(f); + wpt->unk2 = ReadShort(f); + wpt->unk3 = ReadShort(f); + wpt->serial = ReadShort(f); + wpt->unk4 = ReadShort(f); + wpt->create_zoom = ReadChar(f); + wpt->visible_zoom = ReadChar(f); + wpt->unk5 = ReadShort(f); + wpt->radius = ReadDouble(f); + len = ReadShort(f); + wpt->name = ReadString(f, len); + + if (len != strlen(wpt->name)) { + /* This happens in 06/6.0 files that put extra data in the + * name record for backward compatibility's sake */ + char *ofs = wpt->name + strlen(wpt->name) + 1; + wpt->unk6_1 = le_read16(ofs); + ofs += 2; + + len = le_read16(ofs); + ofs += 2; + + if (len) { + char *oldurlstr; + /* + * Trust URL encoded in new format over one in + * old format if both are present. Whack the + * name starting at '{URL='. + */ + oldurlstr = strstr(wpt->name, "{URL="); + if (oldurlstr) { + *oldurlstr = 0; + } + + wpt->url = xcalloc(len+1, 1); + memcpy(wpt->url, ofs, len); + ofs += len; + } + + len = le_read16(ofs); + ofs += 2; + + if (len) { + wpt->comment = xcalloc(len+1, 1); + memcpy(wpt->comment, ofs, len); + ofs += len; + } + + /* these are quadwords, presumably for year-2038 compat. */ + wpt->creation_time = le_read32(ofs); + ofs += 8; + + wpt->modification_time = le_read32(ofs); + ofs += 8; + } + + if (wpt->type == 0x12) { + /* 'image' type */ + ReadShort(f); /* length of font + filename */ + len = ReadShort(f); + wpt->fontname = ReadString(f, len); + len = ReadShort(f); + wpt->image_name = ReadString(f, len); + } else { + len = ReadShort(f); + wpt->fontname = ReadString(f, len); + wpt->image_name = NULL; + } + ReadGuid(f, &wpt->guid); + wpt->fontcolor = ReadLong(f); + wpt->fontstyle = ReadLong(f); + wpt->fontsize = ReadLong(f); + wpt->outlineweight = ReadLong(f); + wpt->outlinecolor = ReadLong(f); + wpt->outlineflags = ReadLong(f); + wpt->fillcolor = ReadLong(f); + wpt->unk6 = ReadLong(f); + wpt->fillflags = ReadLong(f); } -static void Write_AN1_Waypoint( gbfile *f, an1_waypoint_record *wpt ) { - short len; - - WriteShort( f, wpt->magic ); - WriteLong( f, wpt->unk1 ); - WriteLong( f, wpt->lon ); - WriteLong( f, wpt->lat ); - WriteShort( f, wpt->type ); - WriteLong( f, wpt->height ); - WriteLong( f, wpt->width ); - WriteShort( f, wpt->unk2 ); - WriteShort( f, wpt->unk3 ); - WriteShort( f, wpt->serial ); - WriteShort( f, wpt->unk4 ); - WriteChar( f, wpt->create_zoom ); - WriteChar( f, wpt->visible_zoom ); - WriteShort( f, wpt->unk5 ); - WriteDouble( f, wpt->radius ); - - len = strlen( wpt->name ) + 1 + 2 + 2 + - (wpt->url ? strlen( wpt->url ) : 0) + 2 + - (wpt->comment ? strlen( wpt->comment ) : 0) + 8 + 8; - WriteShort( f, len ); - WriteString( f, wpt->name ); - WriteChar( f, 0 ); /* name string terminator */ - - WriteShort( f, wpt->unk6_1 ); - - if ( wpt->url ) { - WriteShort( f, strlen(wpt->url)); - WriteString( f, wpt->url ); - } - else { - WriteShort( f, 0 ); - } - - if ( wpt->comment ) { - WriteShort( f, strlen(wpt->comment)); - WriteString( f, wpt->comment ); - } - else { - WriteShort( f, 0 ); - } - - WriteLong( f, wpt->creation_time ); - WriteLong( f, 0 ); - - WriteLong( f, wpt->modification_time ); - WriteLong( f, 0 ); - - if ( wpt->type == 0x12 ) { /* image */ - len = 2 + (wpt->fontname ? strlen( wpt->fontname ) : 0 ) + - 2 + (wpt->image_name ? strlen( wpt->image_name ) : 0 ); - WriteShort( f, len ); - if ( wpt->fontname ) { - len = strlen( wpt->fontname ); - WriteShort( f, len ); - WriteString( f, wpt->fontname ); - } - else { - WriteShort( f, 0 ); - } - if ( wpt->image_name ) { - len = strlen( wpt->image_name ); - WriteShort( f, len ); - WriteString( f, wpt->image_name ); - } - else { - WriteShort( f, 0 ); - } - } - else { - len = strlen( wpt->fontname ); - WriteShort( f, len ); - WriteString( f, wpt->fontname ); - } - WriteGuid( f, &wpt->guid ); - WriteLong( f, wpt->fontcolor ); - WriteLong( f, wpt->fontstyle ); - WriteLong( f, wpt->fontsize ); - WriteLong( f, wpt->outlineweight ); - WriteLong( f, wpt->outlinecolor ); - WriteLong( f, wpt->outlineflags ); - WriteLong( f, wpt->fillcolor ); - WriteLong( f, wpt->unk6 ); - WriteLong( f, wpt->fillflags ); +static void Write_AN1_Waypoint(gbfile *f, an1_waypoint_record *wpt) +{ + short len; + + WriteShort(f, wpt->magic); + WriteLong(f, wpt->unk1); + WriteLong(f, wpt->lon); + WriteLong(f, wpt->lat); + WriteShort(f, wpt->type); + WriteLong(f, wpt->height); + WriteLong(f, wpt->width); + WriteShort(f, wpt->unk2); + WriteShort(f, wpt->unk3); + WriteShort(f, wpt->serial); + WriteShort(f, wpt->unk4); + WriteChar(f, wpt->create_zoom); + WriteChar(f, wpt->visible_zoom); + WriteShort(f, wpt->unk5); + WriteDouble(f, wpt->radius); + + len = strlen(wpt->name) + 1 + 2 + 2 + + (wpt->url ? strlen(wpt->url) : 0) + 2 + + (wpt->comment ? strlen(wpt->comment) : 0) + 8 + 8; + WriteShort(f, len); + WriteString(f, wpt->name); + WriteChar(f, 0); /* name string terminator */ + + WriteShort(f, wpt->unk6_1); + + if (wpt->url) { + WriteShort(f, strlen(wpt->url)); + WriteString(f, wpt->url); + } else { + WriteShort(f, 0); + } + + if (wpt->comment) { + WriteShort(f, strlen(wpt->comment)); + WriteString(f, wpt->comment); + } else { + WriteShort(f, 0); + } + + WriteLong(f, wpt->creation_time); + WriteLong(f, 0); + + WriteLong(f, wpt->modification_time); + WriteLong(f, 0); + + if (wpt->type == 0x12) { /* image */ + len = 2 + (wpt->fontname ? strlen(wpt->fontname) : 0) + + 2 + (wpt->image_name ? strlen(wpt->image_name) : 0); + WriteShort(f, len); + if (wpt->fontname) { + len = strlen(wpt->fontname); + WriteShort(f, len); + WriteString(f, wpt->fontname); + } else { + WriteShort(f, 0); + } + if (wpt->image_name) { + len = strlen(wpt->image_name); + WriteShort(f, len); + WriteString(f, wpt->image_name); + } else { + WriteShort(f, 0); + } + } else { + len = strlen(wpt->fontname); + WriteShort(f, len); + WriteString(f, wpt->fontname); + } + WriteGuid(f, &wpt->guid); + WriteLong(f, wpt->fontcolor); + WriteLong(f, wpt->fontstyle); + WriteLong(f, wpt->fontsize); + WriteLong(f, wpt->outlineweight); + WriteLong(f, wpt->outlinecolor); + WriteLong(f, wpt->outlineflags); + WriteLong(f, wpt->fillcolor); + WriteLong(f, wpt->unk6); + WriteLong(f, wpt->fillflags); } -static void Read_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { - - vertex->magic = ReadShort( f ); - vertex->unk0 = ReadLong( f ); - vertex->lon = ReadLong( f ); - vertex->lat = ReadLong( f ); - vertex->unk1 = ReadShort( f ); +static void Read_AN1_Vertex(gbfile *f, an1_vertex_record *vertex) +{ + + vertex->magic = ReadShort(f); + vertex->unk0 = ReadLong(f); + vertex->lon = ReadLong(f); + vertex->lat = ReadLong(f); + vertex->unk1 = ReadShort(f); } -static void Write_AN1_Vertex( gbfile *f, an1_vertex_record *vertex ) { - WriteShort( f, vertex->magic ); - WriteLong( f, vertex->unk0 ); - WriteLong( f, vertex->lon ); - WriteLong( f, vertex->lat ); - WriteShort( f, vertex->unk1 ); +static void Write_AN1_Vertex(gbfile *f, an1_vertex_record *vertex) +{ + WriteShort(f, vertex->magic); + WriteLong(f, vertex->unk0); + WriteLong(f, vertex->lon); + WriteLong(f, vertex->lat); + WriteShort(f, vertex->unk1); } -static void Read_AN1_Line( gbfile *f, an1_line_record *line ) { - - short len; - - line->roadtype = ReadLong( f ); - line->serial = ReadShort( f ); - line->unk2 = ReadLong( f ); - line->unk3 = ReadShort( f ); - line->type = ReadShort( f ); - line->unk4 = ReadLong( f ); - len = ReadShort( f ); - line->name = ReadString( f, len ); - line->lineweight = ReadShort( f ); - line->linestyle = ReadLong( f ); - line->linecolor = ReadLong( f ); - line->opacity = ReadLong( f ); - line->polyfillcolor = ReadLong( f ); - line->unk6 = ReadLong( f ); - line->unk7 = ReadLong( f ); - line->unk8 = ReadShort( f ); - line->pointcount = ReadLong( f ); +static void Read_AN1_Line(gbfile *f, an1_line_record *line) +{ + + short len; + + line->roadtype = ReadLong(f); + line->serial = ReadShort(f); + line->unk2 = ReadLong(f); + line->unk3 = ReadShort(f); + line->type = ReadShort(f); + line->unk4 = ReadLong(f); + len = ReadShort(f); + line->name = ReadString(f, len); + line->lineweight = ReadShort(f); + line->linestyle = ReadLong(f); + line->linecolor = ReadLong(f); + line->opacity = ReadLong(f); + line->polyfillcolor = ReadLong(f); + line->unk6 = ReadLong(f); + line->unk7 = ReadLong(f); + line->unk8 = ReadShort(f); + line->pointcount = ReadLong(f); } -static void Write_AN1_Line( gbfile *f, an1_line_record *line ) { - short len; - - WriteLong( f, line->roadtype ); - WriteShort( f, line->serial ); - WriteLong( f, line->unk2 ); - WriteShort( f, line->unk3 ); - WriteShort( f, line->type ); - WriteLong( f, line->unk4 ); - len = strlen( line->name ); - WriteShort( f, len ); - WriteString( f, line->name ); - WriteShort( f, (short) line->lineweight ); - WriteLong( f, line->linestyle ); - WriteLong( f, line->linecolor ); - WriteLong( f, line->opacity ); - WriteLong( f, line->polyfillcolor ); - WriteLong( f, line->unk6 ); - WriteLong( f, line->unk7 ); - WriteShort( f, line->unk8 ); - WriteLong( f, line->pointcount ); -} - -static void Skip_AN1_IL( gbfile *f ) { - Skip( f, 26 ); +static void Write_AN1_Line(gbfile *f, an1_line_record *line) +{ + short len; + + WriteLong(f, line->roadtype); + WriteShort(f, line->serial); + WriteLong(f, line->unk2); + WriteShort(f, line->unk3); + WriteShort(f, line->type); + WriteLong(f, line->unk4); + len = strlen(line->name); + WriteShort(f, len); + WriteString(f, line->name); + WriteShort(f, (short) line->lineweight); + WriteLong(f, line->linestyle); + WriteLong(f, line->linecolor); + WriteLong(f, line->opacity); + WriteLong(f, line->polyfillcolor); + WriteLong(f, line->unk6); + WriteLong(f, line->unk7); + WriteShort(f, line->unk8); + WriteLong(f, line->pointcount); } -static void Skip_AN1_BM( gbfile *f ) { - unsigned long bmsize; - unsigned long palettesize; - unsigned long bmisize; - unsigned long bitoffset; - - Skip( f, 8 ); /* BITMAPFILEHEADER fields 1-3 */ - bitoffset = ReadLong( f ); - - bmisize = ReadLong( f ); - Skip( f, 16 ); /* BITMAPINFOHEADER fields 2-6 */ - bmsize = ReadLong( f ); - Skip( f, 16 ); /* BITMAPINFOHEADER fields 8-11 */ - - palettesize = bitoffset - bmisize - 14; - Skip( f, bmsize + palettesize ); +static void Skip_AN1_IL(gbfile *f) +{ + Skip(f, 26); } -static void Read_AN1_Symbol( gbfile *f, an1_symbol_record *symbol ) { - short len; - - /* This is just the high word of a long; we ate the low - * word in the caller. Fortunately, we don't care. */ - symbol->hotspotxhi = ReadShort( f ); - symbol->hotspoty = ReadLong( f ); - symbol->unk1 = ReadLong( f ); - ReadGuid( f, &symbol->guid ); - len = ReadChar( f ); - symbol->name = ReadString( f, len ); +static void Skip_AN1_BM(gbfile *f) +{ + unsigned long bmsize; + unsigned long palettesize; + unsigned long bmisize; + unsigned long bitoffset; + + Skip(f, 8); /* BITMAPFILEHEADER fields 1-3 */ + bitoffset = ReadLong(f); + + bmisize = ReadLong(f); + Skip(f, 16); /* BITMAPINFOHEADER fields 2-6 */ + bmsize = ReadLong(f); + Skip(f, 16); /* BITMAPINFOHEADER fields 8-11 */ + + palettesize = bitoffset - bmisize - 14; + Skip(f, bmsize + palettesize); } -static void Read_AN1_Header( gbfile *f ) { - unsigned short magic; - unsigned short type; - - magic = ReadShort( f ); - type = ReadShort( f ); - - last_read_type = type; +static void Read_AN1_Symbol(gbfile *f, an1_symbol_record *symbol) +{ + short len; + + /* This is just the high word of a long; we ate the low + * word in the caller. Fortunately, we don't care. */ + symbol->hotspotxhi = ReadShort(f); + symbol->hotspoty = ReadLong(f); + symbol->unk1 = ReadLong(f); + ReadGuid(f, &symbol->guid); + len = ReadChar(f); + symbol->name = ReadString(f, len); } -static void Write_AN1_Header( gbfile *f ) { - WriteShort( f, 11557 ); - WriteShort( f, output_type_num ); +static void Read_AN1_Header(gbfile *f) +{ + unsigned short magic; + unsigned short type; + + magic = ReadShort(f); + type = ReadShort(f); + + last_read_type = type; } -static void Read_AN1_Bitmaps( gbfile *f ) { - long count; - unsigned short magic; - an1_symbol_record symbol; - - count = ReadLong( f ); - - while ( count ) { - magic = ReadShort( f ); - switch (magic) { - case 0x4d42: - Skip_AN1_BM( f ); - break; - case 0x4c49: - Skip_AN1_IL( f ); - break; - default: - Read_AN1_Symbol( f, &symbol ); - Destroy_AN1_Symbol( &symbol ); - count--; - break; - } - } - - /* Read the symbol table */ +static void Write_AN1_Header(gbfile *f) +{ + WriteShort(f, 11557); + WriteShort(f, output_type_num); } -static void Write_AN1_Bitmaps( gbfile *f ) { - /* On write, we don't output any bitmaps, so writing them - * is just a matter of writing a count of zero */ - WriteLong( f, 0 ); +static void Read_AN1_Bitmaps(gbfile *f) +{ + long count; + unsigned short magic; + an1_symbol_record symbol; + + count = ReadLong(f); + + while (count) { + magic = ReadShort(f); + switch (magic) { + case 0x4d42: + Skip_AN1_BM(f); + break; + case 0x4c49: + Skip_AN1_IL(f); + break; + default: + Read_AN1_Symbol(f, &symbol); + Destroy_AN1_Symbol(&symbol); + count--; + break; + } + } + + /* Read the symbol table */ } -static void Read_AN1_Waypoints( gbfile *f ) { - unsigned long count = 0; - unsigned long i = 0; - an1_waypoint_record *rec = NULL; - waypoint *wpt_tmp; - char *icon = NULL; - char *url = NULL; - ReadShort( f ); - count = ReadLong( f ); - for (i = 0; i < count; i++ ) { - rec = Alloc_AN1_Waypoint(); - Read_AN1_Waypoint( f, rec ); - wpt_tmp = waypt_new(); - - if ( rec->creation_time ) { - wpt_tmp->creation_time = rec->creation_time; - } - wpt_tmp->longitude = -DecodeOrd( rec->lon ); - wpt_tmp->latitude = DecodeOrd( rec->lat ); - wpt_tmp->notes = xstrdup( rec->comment ); - wpt_tmp->description = xstrdup( rec->name ); - if ( rec->url ) { - wpt_tmp->url = xstrdup( rec->url ); - } - else if ( NULL != (url=strstr(wpt_tmp->description, "{URL="))) { - *url = '\0'; - url += 5; - url[strlen(url)-1] = '\0'; - wpt_tmp->url = xstrdup( url ); - } - - if ( rec->image_name ) { - wpt_tmp->icon_descr = xstrdup( rec->image_name ); - } - else if (FindIconByGuid(&rec->guid, &icon)) { - wpt_tmp->icon_descr = icon; - } - - fs_chain_add( &(wpt_tmp->fs), (format_specific_data *)rec); - rec = NULL; - waypt_add( wpt_tmp ); - } +static void Write_AN1_Bitmaps(gbfile *f) +{ + /* On write, we don't output any bitmaps, so writing them + * is just a matter of writing a count of zero */ + WriteLong(f, 0); +} + +static void Read_AN1_Waypoints(gbfile *f) +{ + unsigned long count = 0; + unsigned long i = 0; + an1_waypoint_record *rec = NULL; + waypoint *wpt_tmp; + char *icon = NULL; + char *url = NULL; + ReadShort(f); + count = ReadLong(f); + for (i = 0; i < count; i++) { + rec = Alloc_AN1_Waypoint(); + Read_AN1_Waypoint(f, rec); + wpt_tmp = waypt_new(); + + if (rec->creation_time) { + wpt_tmp->creation_time = rec->creation_time; + } + wpt_tmp->longitude = -DecodeOrd(rec->lon); + wpt_tmp->latitude = DecodeOrd(rec->lat); + wpt_tmp->notes = xstrdup(rec->comment); + wpt_tmp->description = xstrdup(rec->name); + if (rec->url) { + wpt_tmp->url = xstrdup(rec->url); + } else if (NULL != (url=strstr(wpt_tmp->description, "{URL="))) { + *url = '\0'; + url += 5; + url[strlen(url)-1] = '\0'; + wpt_tmp->url = xstrdup(url); + } + + if (rec->image_name) { + wpt_tmp->icon_descr = xstrdup(rec->image_name); + } else if (FindIconByGuid(&rec->guid, &icon)) { + wpt_tmp->icon_descr = icon; + } + + fs_chain_add(&(wpt_tmp->fs), (format_specific_data *)rec); + rec = NULL; + waypt_add(wpt_tmp); + } } static void -Write_One_AN1_Waypoint( const waypoint *wpt ) +Write_One_AN1_Waypoint(const waypoint *wpt) { - an1_waypoint_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( wpt->fs, FS_AN1W ); - if ( fs ) { - rec = (an1_waypoint_record *)fs; - xfree( rec->name ); - local = 0; - if ( opt_zoom ) - rec->visible_zoom = opt_zoom_num; - } - else { - rec = Alloc_AN1_Waypoint(); - local = 1; - rec->magic = 1; - rec->type = wpt_type_num; - rec->unk2 = 3; - rec->unk3 = 18561; - rec->radius = radius; - rec->fillcolor = opt_color_num; - rec->fillflags = 3; - if ( wpt_type_num == 5 ) rec->fillflags = 0x8200; - rec->height = -50; - rec->width = 20; - rec->fontname = xstrdup( "Arial" ); - FindIconByName( opt_symbol, &rec->guid ); - rec->fontsize = 10; - rec->visible_zoom = opt_zoom?opt_zoom_num:10; - rec->unk6_1 = 1; - } - rec->name = xstrdup( wpt->description ); - - if ( !nogc && wpt->gc_data->id ) { - char *extra = xmalloc( 25 + strlen(wpt->gc_data->placer) + strlen( wpt->shortname )); - sprintf( extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", - wpt->gc_data->placer, - wpt->shortname, wpt->gc_data->diff/10.0, - wpt->gc_data->terr/10.0); - rec->name = xstrappend( rec->name, extra ); - xfree( extra ); - } - - if ( !nourl && wpt->url ) { - int len = 7+strlen(wpt->url); - char *extra = (char *)xmalloc( len ); - sprintf( extra, "{URL=%s}", wpt->url ); - rec->name = xstrappend( rec->name, extra ); - xfree( extra ); - rec->url = xstrdup( wpt->url ); - } - - if ( wpt->notes ) { - if ( rec->comment ) { - xfree( rec->comment ); - } - rec->comment = xstrdup( wpt->notes ); - } - - - rec->creation_time = rec->modification_time = wpt->creation_time; - rec->lat = EncodeOrd( wpt->latitude ); - rec->lon = EncodeOrd( -wpt->longitude ); - rec->serial = serial++; - - if ( rec->type == 0x12 ) { /* image */ - if ( strstr( wpt->icon_descr, ":\\" )) { - rec->image_name = xstrdup( wpt->icon_descr ); - rec->height = -244; - rec->width = -1; - } - } - if ( !rec->image_name && wpt->icon_descr ) { - FindIconByName( (char *)(void *)wpt->icon_descr, &rec->guid ); - } - - Write_AN1_Waypoint( outfile, rec ); - if ( local ) { - Destroy_AN1_Waypoint( rec ); - } + an1_waypoint_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find(wpt->fs, FS_AN1W); + if (fs) { + rec = (an1_waypoint_record *)fs; + xfree(rec->name); + local = 0; + if (opt_zoom) { + rec->visible_zoom = opt_zoom_num; + } + } else { + rec = Alloc_AN1_Waypoint(); + local = 1; + rec->magic = 1; + rec->type = wpt_type_num; + rec->unk2 = 3; + rec->unk3 = 18561; + rec->radius = radius; + rec->fillcolor = opt_color_num; + rec->fillflags = 3; + if (wpt_type_num == 5) { + rec->fillflags = 0x8200; + } + rec->height = -50; + rec->width = 20; + rec->fontname = xstrdup("Arial"); + FindIconByName(opt_symbol, &rec->guid); + rec->fontsize = 10; + rec->visible_zoom = opt_zoom?opt_zoom_num:10; + rec->unk6_1 = 1; + } + rec->name = xstrdup(wpt->description); + + if (!nogc && wpt->gc_data->id) { + char *extra = xmalloc(25 + strlen(wpt->gc_data->placer) + strlen(wpt->shortname)); + sprintf(extra, "\r\nBy %s\r\n%s (%1.1f/%1.1f)", + wpt->gc_data->placer, + wpt->shortname, wpt->gc_data->diff/10.0, + wpt->gc_data->terr/10.0); + rec->name = xstrappend(rec->name, extra); + xfree(extra); + } + + if (!nourl && wpt->url) { + int len = 7+strlen(wpt->url); + char *extra = (char *)xmalloc(len); + sprintf(extra, "{URL=%s}", wpt->url); + rec->name = xstrappend(rec->name, extra); + xfree(extra); + rec->url = xstrdup(wpt->url); + } + + if (wpt->notes) { + if (rec->comment) { + xfree(rec->comment); + } + rec->comment = xstrdup(wpt->notes); + } + + + rec->creation_time = rec->modification_time = wpt->creation_time; + rec->lat = EncodeOrd(wpt->latitude); + rec->lon = EncodeOrd(-wpt->longitude); + rec->serial = serial++; + + if (rec->type == 0x12) { /* image */ + if (strstr(wpt->icon_descr, ":\\")) { + rec->image_name = xstrdup(wpt->icon_descr); + rec->height = -244; + rec->width = -1; + } + } + if (!rec->image_name && wpt->icon_descr) { + FindIconByName((char *)(void *)wpt->icon_descr, &rec->guid); + } + + Write_AN1_Waypoint(outfile, rec); + if (local) { + Destroy_AN1_Waypoint(rec); + } } -static void Write_AN1_Waypoints( gbfile *f ) { - WriteShort( f, 2 ); - WriteLong( f, waypt_count() ); - waypt_disp_all( Write_One_AN1_Waypoint ); +static void Write_AN1_Waypoints(gbfile *f) +{ + WriteShort(f, 2); + WriteLong(f, waypt_count()); + waypt_disp_all(Write_One_AN1_Waypoint); } -static void Read_AN1_Lines( gbfile *f ) { - unsigned long count = 0; - unsigned long i = 0; - unsigned long j = 0; - an1_line_record *rec = NULL; - an1_vertex_record *vert = NULL; - route_head *rte_head; - waypoint *wpt_tmp; - - ReadShort( f ); - count = ReadLong( f ); - for (i = 0; i < count; i++ ) { - rec = Alloc_AN1_Line(); - Read_AN1_Line( f, rec ); - /* create route rec */ - rte_head = route_head_alloc(); - rte_head->line_color.bbggrr = rec->linecolor; - if (rec->opacity == 0x8200) - rte_head->line_color.opacity = 128; - // lineweight isn't set for dashed/dotted lines - // Since we don't have a way to represent this internally yet, - // use leave line_width at the default. - if(rec->lineweight) - rte_head->line_width = rec->lineweight; - rte_head->rte_name = xstrdup(rec->name); - fs_chain_add( &rte_head->fs, (format_specific_data *)rec ); - route_add_head(rte_head); - for (j = 0; j < (unsigned) rec->pointcount; j++ ) { - vert = Alloc_AN1_Vertex(); - Read_AN1_Vertex( f, vert ); - - /* create route point */ - wpt_tmp = waypt_new(); - wpt_tmp->latitude = DecodeOrd( vert->lat ); - wpt_tmp->longitude = -DecodeOrd( vert->lon ); - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5lx", rtserial++ ); - fs_chain_add( &wpt_tmp->fs, - (format_specific_data *)vert ); - route_add_wpt(rte_head, wpt_tmp); - } - } +static void Read_AN1_Lines(gbfile *f) +{ + unsigned long count = 0; + unsigned long i = 0; + unsigned long j = 0; + an1_line_record *rec = NULL; + an1_vertex_record *vert = NULL; + route_head *rte_head; + waypoint *wpt_tmp; + + ReadShort(f); + count = ReadLong(f); + for (i = 0; i < count; i++) { + rec = Alloc_AN1_Line(); + Read_AN1_Line(f, rec); + /* create route rec */ + rte_head = route_head_alloc(); + rte_head->line_color.bbggrr = rec->linecolor; + if (rec->opacity == 0x8200) { + rte_head->line_color.opacity = 128; + } + // lineweight isn't set for dashed/dotted lines + // Since we don't have a way to represent this internally yet, + // use leave line_width at the default. + if (rec->lineweight) { + rte_head->line_width = rec->lineweight; + } + rte_head->rte_name = xstrdup(rec->name); + fs_chain_add(&rte_head->fs, (format_specific_data *)rec); + route_add_head(rte_head); + for (j = 0; j < (unsigned) rec->pointcount; j++) { + vert = Alloc_AN1_Vertex(); + Read_AN1_Vertex(f, vert); + + /* create route point */ + wpt_tmp = waypt_new(); + wpt_tmp->latitude = DecodeOrd(vert->lat); + wpt_tmp->longitude = -DecodeOrd(vert->lon); + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5lx", rtserial++); + fs_chain_add(&wpt_tmp->fs, + (format_specific_data *)vert); + route_add_wpt(rte_head, wpt_tmp); + } + } } static void -Make_Road_Changes( an1_line_record *rec ) { - int i = 0; - - if ( !rec ) { - return; - } - - if ( !roadchanges ) { - return; - } - - while ( roadchanges[i].name ) { - if ( !case_ignore_strcmp(roadchanges[i].name, rec->name )) { - rec->roadtype = roadchanges[i].type; - break; - } - i++; - } +Make_Road_Changes(an1_line_record *rec) +{ + int i = 0; + + if (!rec) { + return; + } + + if (!roadchanges) { + return; + } + + while (roadchanges[i].name) { + if (!case_ignore_strcmp(roadchanges[i].name, rec->name)) { + rec->roadtype = roadchanges[i].type; + break; + } + i++; + } } - + static void -Write_One_AN1_Line( const route_head *rte ) +Write_One_AN1_Line(const route_head *rte) { - an1_line_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( rte->fs, FS_AN1L ); - - if ( fs ) { - rec = (an1_line_record *)(void *)fs; - local = 0; - switch (output_type_num) { - case 1: - if ( rec->type != 14 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->roadtype = 0x11100541; - rec->unk2 = 655360; - rec->type = 14; - rec->unk8 = 2; - } // end if - Make_Road_Changes( rec ); - break; - case 2: - if ( rec->type != 15 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->type = 15; - } // end if - break; - case 4: - if ( rec->type != 16 ) { - rec = Alloc_AN1_Line(); - memcpy( rec, fs, sizeof(an1_line_record)); - local = 1; - rec->type = 16; - } // end if - break; - } - } - else { - rec = Alloc_AN1_Line(); - local = 1; - rec->name = NULL; - switch (output_type_num) { - /* drawing road trail waypoint track */ - case 1: /* road */ - rec->roadtype = 0x11100541; - rec->unk2 = 655360; - rec->type = 14; - rec->unk8 = 2; - rec->name = xstrdup( rte->rte_name ); - break; - - case 2: /* trail */ - rec->roadtype = 0x11071c50; - rec->unk2 = 917504; - rec->type = 15; - rec->unk8 = 2; - break; - - case 4: /* track */ - rec->roadtype = 0x48800015; - rec->unk2 = 917504; - rec->type = 16; - rec->unk4 = 2; - rec->unk8 = 2; - break; - - case 0: /* drawing */ - case 3: /* waypoint - shouldn't have lines */ - default: - rec->roadtype = 0x48800015; - rec->unk2 = 1048576; - rec->type = 2; - rec->unk4 = 2; - rec->lineweight = 6; - rec->linecolor = opt_color_num; /* red */ - rec->opacity = 3; - rec->unk8 = 2; - break; - } - if ( !rec->name ) { - rec->name = xstrdup( "" ); - } - - } - rec->serial = serial++; - rec->pointcount = rte->rte_waypt_ct; - Write_AN1_Line( outfile, rec ); - if ( local ) { - Destroy_AN1_Line( rec ); - } + an1_line_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find(rte->fs, FS_AN1L); + + if (fs) { + rec = (an1_line_record *)(void *)fs; + local = 0; + switch (output_type_num) { + case 1: + if (rec->type != 14) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + } // end if + Make_Road_Changes(rec); + break; + case 2: + if (rec->type != 15) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 15; + } // end if + break; + case 4: + if (rec->type != 16) { + rec = Alloc_AN1_Line(); + memcpy(rec, fs, sizeof(an1_line_record)); + local = 1; + rec->type = 16; + } // end if + break; + } + } else { + rec = Alloc_AN1_Line(); + local = 1; + rec->name = NULL; + switch (output_type_num) { + /* drawing road trail waypoint track */ + case 1: /* road */ + rec->roadtype = 0x11100541; + rec->unk2 = 655360; + rec->type = 14; + rec->unk8 = 2; + rec->name = xstrdup(rte->rte_name); + break; + + case 2: /* trail */ + rec->roadtype = 0x11071c50; + rec->unk2 = 917504; + rec->type = 15; + rec->unk8 = 2; + break; + + case 4: /* track */ + rec->roadtype = 0x48800015; + rec->unk2 = 917504; + rec->type = 16; + rec->unk4 = 2; + rec->unk8 = 2; + break; + + case 0: /* drawing */ + case 3: /* waypoint - shouldn't have lines */ + default: + rec->roadtype = 0x48800015; + rec->unk2 = 1048576; + rec->type = 2; + rec->unk4 = 2; + rec->lineweight = 6; + rec->linecolor = opt_color_num; /* red */ + rec->opacity = 3; + rec->unk8 = 2; + break; + } + if (!rec->name) { + rec->name = xstrdup(""); + } + + } + rec->serial = serial++; + rec->pointcount = rte->rte_waypt_ct; + Write_AN1_Line(outfile, rec); + if (local) { + Destroy_AN1_Line(rec); + } } static void -Write_One_AN1_Vertex( const waypoint *wpt ) +Write_One_AN1_Vertex(const waypoint *wpt) { - an1_vertex_record *rec; - int local; - format_specific_data *fs = NULL; - - fs = fs_chain_find( wpt->fs, FS_AN1V ); - - if ( fs ) { - rec = (an1_vertex_record *)(void *)fs; - local = 0; - } - else { - rec = Alloc_AN1_Vertex(); - local = 1; - rec->magic = 1; - } - rec->lat = EncodeOrd( wpt->latitude ); - rec->lon = EncodeOrd( -wpt->longitude ); - - Write_AN1_Vertex( outfile, rec ); - if ( local ) { - Destroy_AN1_Vertex( rec ); - } + an1_vertex_record *rec; + int local; + format_specific_data *fs = NULL; + + fs = fs_chain_find(wpt->fs, FS_AN1V); + + if (fs) { + rec = (an1_vertex_record *)(void *)fs; + local = 0; + } else { + rec = Alloc_AN1_Vertex(); + local = 1; + rec->magic = 1; + } + rec->lat = EncodeOrd(wpt->latitude); + rec->lon = EncodeOrd(-wpt->longitude); + + Write_AN1_Vertex(outfile, rec); + if (local) { + Destroy_AN1_Vertex(rec); + } } -static void Write_AN1_Lines( gbfile *f ) { - WriteShort( f, 2 ); - WriteLong( f, route_count()+track_count() ); - - route_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); - track_disp_all( Write_One_AN1_Line, NULL, Write_One_AN1_Vertex ); +static void Write_AN1_Lines(gbfile *f) +{ + WriteShort(f, 2); + WriteLong(f, route_count()+track_count()); + + route_disp_all(Write_One_AN1_Line, NULL, Write_One_AN1_Vertex); + track_disp_all(Write_One_AN1_Line, NULL, Write_One_AN1_Vertex); } -static void -Init_Wpt_Type( void ) +static void +Init_Wpt_Type(void) { - if ( !opt_wpt_type || !opt_wpt_type[0] ) { - wpt_type_num = 1; /* marker */ - return; - } - if ((opt_wpt_type[0] & 0xf0) == 0x30) { - wpt_type_num = atoi( opt_wpt_type ); - } - else { - wpt_type_num = 1; /* marker */ - if ( !case_ignore_strcmp( opt_wpt_type, "marker" )) { - wpt_type_num = 1; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "symbol" )) { - wpt_type_num = 1; /* symbol and marker are synonyms */ - } - else if ( !case_ignore_strcmp( opt_wpt_type, "text" )) { - wpt_type_num = 4; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "mapnote" )) { - wpt_type_num = 6; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "circle" )) { - wpt_type_num = 5; - } - else if ( !case_ignore_strcmp( opt_wpt_type, "image" )) { - wpt_type_num = 18; - } - else { - fatal( MYNAME ": wpt_type must be " - "symbol, text, mapnote, circle, or image\n" ); - } - } + if (!opt_wpt_type || !opt_wpt_type[0]) { + wpt_type_num = 1; /* marker */ + return; + } + if ((opt_wpt_type[0] & 0xf0) == 0x30) { + wpt_type_num = atoi(opt_wpt_type); + } else { + wpt_type_num = 1; /* marker */ + if (!case_ignore_strcmp(opt_wpt_type, "marker")) { + wpt_type_num = 1; + } else if (!case_ignore_strcmp(opt_wpt_type, "symbol")) { + wpt_type_num = 1; /* symbol and marker are synonyms */ + } else if (!case_ignore_strcmp(opt_wpt_type, "text")) { + wpt_type_num = 4; + } else if (!case_ignore_strcmp(opt_wpt_type, "mapnote")) { + wpt_type_num = 6; + } else if (!case_ignore_strcmp(opt_wpt_type, "circle")) { + wpt_type_num = 5; + } else if (!case_ignore_strcmp(opt_wpt_type, "image")) { + wpt_type_num = 18; + } else { + fatal(MYNAME ": wpt_type must be " + "symbol, text, mapnote, circle, or image\n"); + } + } } static void -Init_Output_Type( void ) +Init_Output_Type(void) { - if ( !output_type || !output_type[0]) { - output_type_num = last_read_type; - return; - } - if ( (output_type[0] & 0xf0 ) == 0x30) { - output_type_num = atoi( output_type ); - } - else { - output_type_num = 0; - if ( !case_ignore_strcmp(output_type, "drawing")) { - output_type_num = 0; - } - else if ( !case_ignore_strcmp(output_type, "road")) { - output_type_num = 1; - } - else if ( !case_ignore_strcmp(output_type, "trail")) { - output_type_num = 2; - } - else if ( !case_ignore_strcmp(output_type, "waypoint")) { - output_type_num = 3; - } - else if ( !case_ignore_strcmp(output_type, "track")) { - output_type_num = 4; - } - else { - fatal(MYNAME ": type must be " - "drawing, road, trail, waypoint, or track\n"); - } - } - last_read_type = output_type_num; + if (!output_type || !output_type[0]) { + output_type_num = last_read_type; + return; + } + if ((output_type[0] & 0xf0) == 0x30) { + output_type_num = atoi(output_type); + } else { + output_type_num = 0; + if (!case_ignore_strcmp(output_type, "drawing")) { + output_type_num = 0; + } else if (!case_ignore_strcmp(output_type, "road")) { + output_type_num = 1; + } else if (!case_ignore_strcmp(output_type, "trail")) { + output_type_num = 2; + } else if (!case_ignore_strcmp(output_type, "waypoint")) { + output_type_num = 3; + } else if (!case_ignore_strcmp(output_type, "track")) { + output_type_num = 4; + } else { + fatal(MYNAME ": type must be " + "drawing, road, trail, waypoint, or track\n"); + } + } + last_read_type = output_type_num; } -static long -Parse_Change_Type( char *type ) { - long retval = 0x11100541; - - if ( !case_ignore_strcmp( type, "limited" )) { - retval = 0x11070430; - } - else if ( !case_ignore_strcmp( type, "toll" )) { - retval = 0x11070470; - } - else if ( !case_ignore_strcmp( type, "us" )) { - retval = 0x11070870; - } - else if ( !case_ignore_strcmp( type, "state" )) { - retval = 0x11070c10; - } - else if ( !case_ignore_strcmp( type, "primary" )) { - /* primary state/provincial routes */ - retval = 0x11070840; - } - else if ( !case_ignore_strcmp( type, "major" )) { - retval = 0x11070c30; - } - else if ( !case_ignore_strcmp( type, "local" )) { - retval = 0x11071010; - } - else if ( !case_ignore_strcmp( type, "ramp" )) { - retval = 0x11070cb0; - } - else if ( !case_ignore_strcmp( type, "ferry" )) { - retval = 0x11070ca0; - } - else if ( !case_ignore_strcmp( type, "editable" )) { - retval = 0x11100541; - } - else { - fatal( MYNAME ": unknown road type for road changes\n" ); - } - return retval; +static long +Parse_Change_Type(char *type) +{ + long retval = 0x11100541; + + if (!case_ignore_strcmp(type, "limited")) { + retval = 0x11070430; + } else if (!case_ignore_strcmp(type, "toll")) { + retval = 0x11070470; + } else if (!case_ignore_strcmp(type, "us")) { + retval = 0x11070870; + } else if (!case_ignore_strcmp(type, "state")) { + retval = 0x11070c10; + } else if (!case_ignore_strcmp(type, "primary")) { + /* primary state/provincial routes */ + retval = 0x11070840; + } else if (!case_ignore_strcmp(type, "major")) { + retval = 0x11070c30; + } else if (!case_ignore_strcmp(type, "local")) { + retval = 0x11071010; + } else if (!case_ignore_strcmp(type, "ramp")) { + retval = 0x11070cb0; + } else if (!case_ignore_strcmp(type, "ferry")) { + retval = 0x11070ca0; + } else if (!case_ignore_strcmp(type, "editable")) { + retval = 0x11100541; + } else { + fatal(MYNAME ": unknown road type for road changes\n"); + } + return retval; } -static void -Free_Road_Changes( void ) +static void +Free_Road_Changes(void) { - int i = 0; - if ( roadchanges ) { - while ( roadchanges[i].name ) { - xfree(roadchanges[i].name ); - i++; - } - xfree( roadchanges ); - } - roadchanges = NULL; -} + int i = 0; + if (roadchanges) { + while (roadchanges[i].name) { + xfree(roadchanges[i].name); + i++; + } + xfree(roadchanges); + } + roadchanges = NULL; +} static void -Init_Road_Changes( void ) +Init_Road_Changes(void) { - int count = 0; - char *strType = NULL; - char *name = NULL; - char *bar = NULL; - char *copy = NULL; - Free_Road_Changes(); - - if ( !road_changes || !road_changes[0] ) { - return; - } - bar = strchr( road_changes, '!' ); - while ( bar ) { - count++; - bar = strchr( bar+1, '!' ); - } - if ( !(count&1)) { - fatal( MYNAME ": invalid format for road changes\n" ); - } - count = 1 + count / 2; - roadchanges = (roadchange *)xmalloc( (count+1) * sizeof(roadchange)); - - roadchanges[count].type = 0; - roadchanges[count].name = NULL; - - copy = xstrdup( road_changes ); - bar = copy; - - while ( count ) { - count--; - name = bar; - bar = strchr( name, '!' ); - *bar = '\0'; - bar++; - strType = bar; - bar = strchr( strType, '!' ); - if ( bar ) { - *bar = '\0'; - bar++; - } - roadchanges[count].name = xstrdup( name ); - roadchanges[count].type = Parse_Change_Type( strType ); - } - - xfree( copy ); + int count = 0; + char *strType = NULL; + char *name = NULL; + char *bar = NULL; + char *copy = NULL; + Free_Road_Changes(); + + if (!road_changes || !road_changes[0]) { + return; + } + bar = strchr(road_changes, '!'); + while (bar) { + count++; + bar = strchr(bar+1, '!'); + } + if (!(count&1)) { + fatal(MYNAME ": invalid format for road changes\n"); + } + count = 1 + count / 2; + roadchanges = (roadchange *)xmalloc((count+1) * sizeof(roadchange)); + + roadchanges[count].type = 0; + roadchanges[count].name = NULL; + + copy = xstrdup(road_changes); + bar = copy; + + while (count) { + count--; + name = bar; + bar = strchr(name, '!'); + *bar = '\0'; + bar++; + strType = bar; + bar = strchr(strType, '!'); + if (bar) { + *bar = '\0'; + bar++; + } + roadchanges[count].name = xstrdup(name); + roadchanges[count].type = Parse_Change_Type(strType); + } + + xfree(copy); } static void rd_init(const char *fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void my_read(void) { - Read_AN1_Header( infile ); - Read_AN1_Bitmaps( infile ); - Read_AN1_Waypoints( infile ); - Read_AN1_Lines( infile ); + Read_AN1_Header(infile); + Read_AN1_Bitmaps(infile); + Read_AN1_Waypoints(infile); + Read_AN1_Lines(infile); } static void wr_init(const char *fname) { - outfile = gbfopen_le( fname, "wb", MYNAME ); - Init_Output_Type(); - Init_Road_Changes(); - opt_color_num = color_to_bbggrr(opt_color); - Init_Wpt_Type(); - if ( opt_zoom ) { - opt_zoom_num = atoi(opt_zoom); - } - radius = .1609344; /* 1/10 mi */ - if ( opt_radius ) { - radius = atof(opt_radius); - if ( !strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { - radius *= 5280*12*2.54/100000; - } - } + outfile = gbfopen_le(fname, "wb", MYNAME); + Init_Output_Type(); + Init_Road_Changes(); + opt_color_num = color_to_bbggrr(opt_color); + Init_Wpt_Type(); + if (opt_zoom) { + opt_zoom_num = atoi(opt_zoom); + } + radius = .1609344; /* 1/10 mi */ + if (opt_radius) { + radius = atof(opt_radius); + if (!strchr(opt_radius,'k') && !strchr(opt_radius,'K')) { + radius *= 5280*12*2.54/100000; + } + } } static void -wr_deinit( void ) +wr_deinit(void) { - Free_Road_Changes(); - gbfclose(outfile); + Free_Road_Changes(); + gbfclose(outfile); } static void -my_write( void ) +my_write(void) { - Write_AN1_Header( outfile ); - Write_AN1_Bitmaps( outfile ); - Write_AN1_Waypoints( outfile ); - Write_AN1_Lines( outfile ); + Write_AN1_Header(outfile); + Write_AN1_Bitmaps(outfile); + Write_AN1_Waypoints(outfile); + Write_AN1_Lines(outfile); } ff_vecs_t an1_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_write /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - my_read, - my_write, - NULL, - an1_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_write /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + my_read, + my_write, + NULL, + an1_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/an1sym.h b/gpsbabel/an1sym.h index bf25c9303..22d0a9af1 100644 --- a/gpsbabel/an1sym.h +++ b/gpsbabel/an1sym.h @@ -1,4 +1,4 @@ -/* +/* @@ -41,7 +41,7 @@ /* Read DeLorme drawing files (.an1) - supplemental (included by an1.c) - + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -61,459 +61,673 @@ */ struct defguid { - GUID guid; - char *name; + GUID guid; + char *name; } default_guids[] = { - {{0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Hiker"}, - {{0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Canoe"}, - {{0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Kayak"}, - {{0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Bike"}, - {{0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Four wheeler"}, - {{0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Jeep"}, - {{0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Snowmobile"}, - {{0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Rec Vehicle"}, - {{0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Fire"}, - {{0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Fishing"}, - {{0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Tree"}, - {{0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Pine Tree"}, - {{0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Birch"}, - {{0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Deer"}, - {{0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Moose"}, - {{0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Mud"}, - {{0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Tractor"}, - {{0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Combine Harvester"}, - {{0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Front-End Loader"}, - {{0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Power Shovel"}, - {{0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Road Grader"}, - {{0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Road Roller"}, - {{0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dump Truck"}, - {{0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Skid-Steer Loader"}, - {{0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}}, - "Highway Sign"}, - {{0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}}, - "Orange Cone"}, - {{0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}}, - "Barricade"}, - {{0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}}, - "Flagger"}, - {{0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}}, - "Construction Sign"}, - {{0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}}, - "Construction Flasher"}, - {{0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}}, - "Transit"}, - {{0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Left"}, - {{0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Right"}, - {{0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up"}, - {{0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down"}, - {{0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up Left"}, - {{0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Up Right"}, - {{0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down Left"}, - {{0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Arrow Down Right"}, - {{0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Left"}, - {{0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Right"}, - {{0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up"}, - {{0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down"}, - {{0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up Left"}, - {{0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Up Right"}, - {{0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down Left"}, - {{0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Arrow Down Right"}, - {{0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Left"}, - {{0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Right"}, - {{0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up"}, - {{0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down"}, - {{0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down Right"}, - {{0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Down Left"}, - {{0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up Left"}, - {{0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Large Arrow Up Right"}, - {{0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}}, - "Accommodation"}, - {{0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}}, - "Australia"}, - {{0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}}, - "Blue Dome Cross"}, - {{0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}}, - "Green Dome Cross"}, - {{0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}}, - "Business"}, - {{0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}}, - "Airplane"}, - {{0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}}, - "Amusement Recreation"}, - {{0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}}, - "Green Square"}, - {{0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}}, - "Red Triangle"}, - {{0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}}, - "Red Triangle and Green Square"}, - {{0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}}, - "City 4"}, - {{0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}}, - "White Square"}, - {{0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}}, - "White Triangle"}, - {{0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}}, - "Red Black Diamond Flag"}, - {{0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}}, - "Yellow Diamond Flag"}, - {{0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}}, - "Small Pink Square"}, - {{0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}}, - "Store"}, - {{0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}}, - "Camping"}, - {{0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}}, - "Green Diamond Flag"}, - {{0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}}, - "Red Diamond Flag"}, - {{0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}}, - "Red Green Diamond Flag"}, - {{0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}}, - "White Globe"}, - {{0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}}, - "Yellow Globe"}, - {{0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}}, - ""}, - {{0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}}, - "Black Cross"}, - {{0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}}, - "Church"}, - {{0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}}, - "Small Dark Green Square"}, - {{0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}}, - "Small Black Square"}, - {{0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}}, - "Danger"}, - {{0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}}, - "Construction Business"}, - {{0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}}, - "Airport"}, - {{0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}}, - "City 5"}, - {{0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}}, - "USA"}, - {{0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}}, - "Diver Down"}, - {{0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}}, - "Light Yellow Square"}, - {{0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}}, - "Education Technology"}, - {{0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}}, - "Computer"}, - {{0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}}, - "Amusement Recreation Red"}, - {{0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}}, - "Telephone Red"}, - {{0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}}, - "Exit"}, - {{0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}}, - "Exit with Services"}, - {{0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}}, - "Pizza"}, - {{0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}}, - "Financial Services"}, - {{0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}}, - "City 3"}, - {{0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}}, - "Food Store"}, - {{0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}}, - ""}, - {{0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}}, - ""}, - {{0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}}, - "Driving Range"}, - {{0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}}, - "Golf Municipal"}, - {{0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}}, - "Golf Private"}, - {{0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}}, - "Golf Public"}, - {{0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}}, - "Golf Resort"}, - {{0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}}, - "Golf Semi Private"}, - {{0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}}, - "Medical Service"}, - {{0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}}, - "Home Furnishings"}, - {{0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}}, - "Industrial"}, - {{0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}}, - ""}, - {{0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}}, - ""}, - {{0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}}, - ""}, - {{0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}}, - "Manufacturing"}, - {{0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}}, - "Note"}, - {{0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}}, - "City"}, - {{0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}}, - "Air Base"}, - {{0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}}, - "Battlefield"}, - {{0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}}, - "Mining"}, - {{0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}}, - "Mountain"}, - {{0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}}, - "Capital"}, - {{0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}}, - "Route"}, - {{0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}}, - "Overnight"}, - {{0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}}, - "Route End Active"}, - {{0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}}, - "Route End Inactive"}, - {{0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}}, - "Fuel Stop"}, - {{0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}}, - "Route Start Active"}, - {{0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}}, - "Route Start Inactive"}, - {{0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}}, - "Route Stop Active"}, - {{0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}}, - "Route Stop Inactive"}, - {{0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}}, - "Route Via"}, - {{0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}}, - "Radiation Green"}, - {{0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}}, - "Radiation Red"}, - {{0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}}, - "Electricity"}, - {{0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}}, - "Personal Furnishings"}, - {{0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}}, - "Personal Services"}, - {{0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}}, - "Telephone Black"}, - {{0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}}, - "Government Light"}, - {{0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}}, - "Airport Red Square"}, - {{0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}}, - "Propeller Aircraft"}, - {{0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}}, - "Jet Aircraft"}, - {{0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}}, - "Government"}, - {{0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}}, - "USA Regional"}, - {{0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}}, - "House 2"}, - {{0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}}, - "Picnic"}, - {{0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}}, - "Restaurant"}, - {{0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}}, - "Store 2"}, - {{0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}}, - ""}, - {{0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}}, - "Blue Star"}, - {{0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}}, - ""}, - {{0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}}, - "Running"}, - {{0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, - "Transportation"}, - {{0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, - "Fishing 2"}, - {{0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, - "Automotive"}, - {{0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, - "Cloudy"}, - {{0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}}, - "Partly Cloudy"}, - {{0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, - "Mostly Cloudy"}, - {{0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, - "Hurricane"}, - {{0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, - "Lightning"}, - {{0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, - "Rain"}, - {{0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Flag"}, - {{0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Blue Flag"}, - {{0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Flag"}, - {{0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Flag"}, - {{0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Flag 2"}, - {{0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Flag"}, - {{0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Flag"}, - {{0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Flag"}, - {{0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue-Green Flag"}, - {{0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Light Blue Flag"}, - {{0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Dark Blue Map Pin"}, - {{0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Map Pin"}, - {{0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Map Pin"}, - {{0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Map Pin"}, - {{0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Map Pin"}, - {{0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Map Pin"}, - {{0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Map Pin"}, - {{0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Map Pin"}, - {{0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Gray Map Pin"}, - {{0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Gray Map Pin"}, - {{0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Green Dot"}, - {{0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Green Dot"}, - {{0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue Dot"}, - {{0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Blue Dot"}, - {{0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Red Dot"}, - {{0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Dark Red Dot"}, - {{0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Yellow Dot"}, - {{0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Brown Dot"}, - {{0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Light Blue Dot"}, - {{0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Blue-Green Dot"}, - {{0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Green Dot"}, - {{0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Green Dot"}, - {{0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Blue Dot"}, - {{0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Blue Dot"}, - {{0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Red Dot"}, - {{0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Dark Red Dot"}, - {{0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Yellow Dot"}, - {{0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Brown Dot"}, - {{0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Light Blue Dot"}, - {{0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, - "Small Blue-Green Dot"}, - {{0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Red Flag"}, - {{0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Map Pin"}, - {{0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Yellow Square"}, - {{0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Red X"}, - {{0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Blue Circle"}, - {{0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "House"}, - {{0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Triangle"}, - {{0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, - "Green Star"}, - {{0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}}, - "Geocache"}, - {{0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}}, - "Geocache Found"}, - {{0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}}, - "Tent"}, - {{0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}}, - "Tipup Up"}, - {{0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}}, - "Topup Down"}, + { {0xb610bc70,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Hiker" + }, + { {0xb610bc71,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Canoe" + }, + { {0xb610bc72,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Kayak" + }, + { {0xb610bc73,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Bike" + }, + { {0xb610bc74,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Four wheeler" + }, + { {0xb610bc75,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Jeep" + }, + { {0xb610bc76,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Snowmobile" + }, + { {0xb610bc78,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Rec Vehicle" + }, + { {0xb610bc79,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fire" + }, + { {0xb610bc7a,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Fishing" + }, + { {0xb610bc7b,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tree" + }, + { {0xb610bc7c,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Pine Tree" + }, + { {0xb610bc7d,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Birch" + }, + { {0xb610bc7e,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Deer" + }, + { {0xb610bc7f,{0x377e, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Moose" + }, + { {0x99d8c163,{0x7622, 0x11d5, 0xe8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Mud" + }, + { {0x012dfac2,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Tractor" + }, + { {0x012dfac3,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Combine Harvester" + }, + { {0x012dfac7,{0xade8, 0x11d5, 0x0fb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Front-End Loader" + }, + { {0xfd163780,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Power Shovel" + }, + { {0xfd163781,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Grader" + }, + { {0xfd163784,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Road Roller" + }, + { {0xfd163787,{0xb10a, 0x11d5, 0x11b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dump Truck" + }, + { {0x5673d712,{0xb28d, 0x11d5, 0x13b3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Skid-Steer Loader" + }, + { {0xb86045ac,{0x390f, 0x420f, 0x91a7}, {0x76, 0x2f, 0x48, 0xea, 0xe2, 0xd7}}, + "Highway Sign" + }, + { {0x1e129e95,{0x13b6, 0x48d8, 0x3fa3}, {0x9c, 0xc8, 0x20, 0x8e, 0x1d, 0x9d}}, + "Orange Cone" + }, + { {0xadee7d54,{0xf7c9, 0x4ab6, 0xfb93}, {0x99, 0xc3, 0xbc, 0x9d, 0x15, 0x47}}, + "Barricade" + }, + { {0xa170000f,{0x8bd8, 0x4574, 0x58ac}, {0x55, 0x41, 0x67, 0xef, 0x64, 0x62}}, + "Flagger" + }, + { {0xa425f90e,{0x6ab6, 0x4ca9, 0x8997}, {0xbf, 0xca, 0xe0, 0xc2, 0x2b, 0x53}}, + "Construction Sign" + }, + { {0x0805b240,{0x6b26, 0x4300, 0xebb1}, {0xea, 0x9b, 0xcf, 0x68, 0xc6, 0x18}}, + "Construction Flasher" + }, + { {0x56721a6c,{0x8e77, 0x4b62, 0x09aa}, {0xce, 0xdc, 0x69, 0x4a, 0x16, 0x05}}, + "Transit" + }, + { {0x623e1ee9,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Left" + }, + { {0x623e1eea,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Right" + }, + { {0x623e1eeb,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up" + }, + { {0x623e1eec,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down" + }, + { {0x623e1eed,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Left" + }, + { {0x623e1eee,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Up Right" + }, + { {0x623e1eef,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Left" + }, + { {0x623e1ef0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Arrow Down Right" + }, + { {0x83f91421,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Left" + }, + { {0x83f91422,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Right" + }, + { {0x83f91423,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up" + }, + { {0x83f91424,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down" + }, + { {0x83f91425,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Left" + }, + { {0x83f91426,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Up Right" + }, + { {0x83f91427,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Left" + }, + { {0x83f91428,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Arrow Down Right" + }, + { {0x83f91429,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Left" + }, + { {0x83f9142a,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Right" + }, + { {0x83f9142b,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up" + }, + { {0x83f9142c,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down" + }, + { {0x83f9142d,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Right" + }, + { {0x83f9142e,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Down Left" + }, + { {0x83f9142f,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Left" + }, + { {0x83f91430,{0x3772, 0x11d6, 0xaeb3}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Large Arrow Up Right" + }, + { {0x8ff0aad1,{0xc53d, 0x4998, 0x7ebd}, {0x06, 0x60, 0x25, 0x6c, 0x4f, 0x6d}}, + "Accommodation" + }, + { {0xaf7bf199,{0x6a8b, 0x49fe, 0xae92}, {0xa3, 0x09, 0x7b, 0xb8, 0x81, 0x6a}}, + "Australia" + }, + { {0x6bbcc9d1,{0x6a19, 0x4c7b, 0xc6a2}, {0x3e, 0x17, 0x02, 0xd6, 0xee, 0x3a}}, + "Blue Dome Cross" + }, + { {0xfff920fe,{0xd780, 0x49d4, 0x1bad}, {0x55, 0x2e, 0xc7, 0xdf, 0xa2, 0xaa}}, + "Green Dome Cross" + }, + { {0x57e75924,{0xd6fa, 0x4666, 0x84bf}, {0x5b, 0x76, 0xa1, 0xd0, 0x14, 0x5f}}, + "Business" + }, + { {0xb09ef4a7,{0x95e4, 0x4e5e, 0x5e84}, {0xbe, 0x2b, 0x86, 0xdd, 0x50, 0x65}}, + "Airplane" + }, + { {0xf2833c22,{0x3592, 0x4a8a, 0x5693}, {0xee, 0x6c, 0x83, 0xb6, 0x3c, 0x19}}, + "Amusement Recreation" + }, + { {0x6f0317d6,{0x7fa3, 0x4dcc, 0x6187}, {0x7e, 0xca, 0xcb, 0x65, 0x49, 0x12}}, + "Green Square" + }, + { {0x18a6d3c0,{0x45cb, 0x4d19, 0xf5b9}, {0xc7, 0x9c, 0xbf, 0x8f, 0x6d, 0x46}}, + "Red Triangle" + }, + { {0x86e68ea7,{0xb9ab, 0x4bc8, 0xa1bf}, {0xc1, 0x22, 0x13, 0x97, 0x95, 0xe8}}, + "Red Triangle and Green Square" + }, + { {0x6afd74bf,{0x0ea5, 0x4680, 0xcd88}, {0x15, 0x87, 0x2f, 0x6c, 0xd2, 0xd8}}, + "City 4" + }, + { {0x49dfeb74,{0xbb09, 0x4df1, 0x5687}, {0xd8, 0xa0, 0xff, 0x36, 0x89, 0x3d}}, + "White Square" + }, + { {0x3eed62c6,{0xdab9, 0x42b0, 0xe4a3}, {0xd2, 0xf1, 0x7d, 0x54, 0xbf, 0x77}}, + "White Triangle" + }, + { {0x6b521940,{0x4492, 0x4c48, 0x58a0}, {0xfc, 0xd1, 0x1f, 0x5e, 0x0c, 0xea}}, + "Red Black Diamond Flag" + }, + { {0xbb8ebaa3,{0xac59, 0x4411, 0x9c94}, {0x30, 0xd4, 0xe1, 0x21, 0x25, 0x46}}, + "Yellow Diamond Flag" + }, + { {0x8e118862,{0xf6aa, 0x4b34, 0x2b82}, {0x8f, 0x3b, 0x5a, 0x2b, 0x59, 0xeb}}, + "Small Pink Square" + }, + { {0xd0ef64c2,{0xe319, 0x4876, 0x1b85}, {0x0e, 0x90, 0x50, 0x89, 0xb7, 0xc5}}, + "Store" + }, + { {0xa22b08fb,{0x6193, 0x4f5c, 0xdaa4}, {0xfa, 0xdf, 0xa7, 0x6e, 0x23, 0xe1}}, + "Camping" + }, + { {0x27f57c69,{0x575b, 0x4b56, 0x288c}, {0xe8, 0xe1, 0xc7, 0x05, 0x1f, 0x1f}}, + "Green Diamond Flag" + }, + { {0xe07abb38,{0x219f, 0x4b52, 0x868b}, {0x45, 0x0f, 0xbc, 0xc1, 0x4f, 0x6a}}, + "Red Diamond Flag" + }, + { {0x3a124ac9,{0x3973, 0x4e27, 0x4b82}, {0xa6, 0x3a, 0x94, 0x5c, 0xf8, 0xb3}}, + "Red Green Diamond Flag" + }, + { {0x64ed669b,{0x0db8, 0x4ec9, 0xd181}, {0x98, 0x50, 0xb3, 0x8b, 0x2f, 0x2e}}, + "White Globe" + }, + { {0x3cb10adc,{0xb090, 0x4960, 0x9f8a}, {0xec, 0xaf, 0x6c, 0xd7, 0xaa, 0x8b}}, + "Yellow Globe" + }, + { {0x2779347d,{0x17d4, 0x4021, 0xa6a8}, {0x51, 0x9a, 0xb6, 0xf8, 0x21, 0xff}}, + "" + }, + { {0x3ad63f7b,{0x4339, 0x427d, 0x5797}, {0xce, 0xa9, 0x96, 0x33, 0x8b, 0x3c}}, + "Black Cross" + }, + { {0x3e89481e,{0x35ff, 0x48b6, 0xc7ae}, {0xb0, 0x75, 0xf6, 0x43, 0xc4, 0xc7}}, + "Church" + }, + { {0x68622c10,{0x79b6, 0x466d, 0xa8a3}, {0x27, 0xc6, 0x25, 0x34, 0xfa, 0xa9}}, + "Small Dark Green Square" + }, + { {0x42c6a873,{0x2d0c, 0x46e7, 0x9989}, {0xdd, 0x86, 0x01, 0x6e, 0xa4, 0xc9}}, + "Small Black Square" + }, + { {0x50e3b06e,{0xbe81, 0x4b2c, 0x1f92}, {0x80, 0xa5, 0x72, 0x9b, 0x33, 0x05}}, + "Danger" + }, + { {0x369d0b22,{0xed07, 0x421f, 0x8780}, {0x33, 0x0e, 0xbd, 0x27, 0x4f, 0x3c}}, + "Construction Business" + }, + { {0x10603b6c,{0xb02e, 0x49ee, 0x60b9}, {0xed, 0x7e, 0x31, 0x16, 0x27, 0x89}}, + "Airport" + }, + { {0x8328aab7,{0xfe04, 0x46dc, 0x7bbf}, {0x29, 0x34, 0x30, 0xd3, 0x4d, 0xeb}}, + "City 5" + }, + { {0x96411287,{0xda33, 0x40e3, 0xaa9c}, {0x75, 0x83, 0x78, 0x2d, 0xa6, 0xf3}}, + "USA" + }, + { {0xb2f98627,{0x1211, 0x40e8, 0xb287}, {0x6d, 0x66, 0xfd, 0x15, 0x1e, 0xd4}}, + "Diver Down" + }, + { {0x3fce26d0,{0xfec6, 0x4f8b, 0x55a2}, {0x89, 0x3a, 0x8e, 0x59, 0x08, 0x0a}}, + "Light Yellow Square" + }, + { {0xb4b68597,{0x1aed, 0x4918, 0xd492}, {0x1f, 0xd1, 0x5e, 0xf2, 0x55, 0xc1}}, + "Education Technology" + }, + { {0x35d2e6a8,{0xda88, 0x4edb, 0x4b80}, {0x2b, 0x1b, 0xcf, 0xc0, 0xd4, 0x6d}}, + "Computer" + }, + { {0x4ddc4e96,{0x8d19, 0x4079, 0x4488}, {0xc0, 0x8f, 0x0f, 0x8e, 0xb5, 0xd7}}, + "Amusement Recreation Red" + }, + { {0x79f58929,{0x46c6, 0x4337, 0xc0b1}, {0xf0, 0x09, 0x55, 0xbb, 0x1f, 0xc3}}, + "Telephone Red" + }, + { {0x0083b377,{0xfb80, 0x4a83, 0x3593}, {0x56, 0xe5, 0xfe, 0xc4, 0xcd, 0x43}}, + "Exit" + }, + { {0x0c232891,{0xab4d, 0x440e, 0x7083}, {0x05, 0x63, 0x3a, 0xf5, 0x66, 0x11}}, + "Exit with Services" + }, + { {0xaf63e7c2,{0x03fa, 0x418e, 0xc68b}, {0x02, 0xb8, 0xf5, 0x61, 0xb6, 0x61}}, + "Pizza" + }, + { {0xd419c693,{0x39e6, 0x43db, 0xa1b8}, {0x7f, 0xcc, 0x2c, 0xb8, 0x51, 0x4a}}, + "Financial Services" + }, + { {0x70740a81,{0xe4ca, 0x4ac2, 0xa498}, {0x21, 0xc8, 0x5b, 0xc0, 0xb7, 0xae}}, + "City 3" + }, + { {0x9a582ff6,{0x34c4, 0x41c6, 0xf0a3}, {0x99, 0x69, 0x9d, 0xbe, 0x2e, 0x08}}, + "Food Store" + }, + { {0x3cd31689,{0x2f8f, 0x4fb0, 0xcb88}, {0x34, 0x84, 0xfc, 0x8b, 0x03, 0xe4}}, + "" + }, + { {0x952557a6,{0xe29e, 0x4512, 0x1184}, {0x1a, 0x3c, 0x9c, 0xd4, 0x83, 0x7d}}, + "" + }, + { {0x03dc278c,{0xe8ff, 0x46ac, 0x3daa}, {0x9f, 0xe9, 0x1e, 0xcf, 0x10, 0x35}}, + "Driving Range" + }, + { {0xacd28bab,{0x0ec0, 0x4393, 0xaf8b}, {0xbb, 0x5e, 0x74, 0xb3, 0x87, 0x12}}, + "Golf Municipal" + }, + { {0x984e7139,{0xeab8, 0x49f6, 0x55a0}, {0x8d, 0x51, 0xe6, 0xdd, 0xcc, 0xf4}}, + "Golf Private" + }, + { {0xec5828ab,{0x2a9d, 0x48f8, 0xd79b}, {0xc9, 0xc3, 0x30, 0x8e, 0xe4, 0xea}}, + "Golf Public" + }, + { {0xb0120d99,{0x683a, 0x4ecc, 0x129a}, {0x29, 0x94, 0x1f, 0x04, 0xae, 0x10}}, + "Golf Resort" + }, + { {0x2ce7685a,{0x6eaf, 0x4061, 0x29a5}, {0x87, 0x5e, 0xfa, 0x41, 0x75, 0x1a}}, + "Golf Semi Private" + }, + { {0x10397049,{0x9fc9, 0x4380, 0x5680}, {0x81, 0xd9, 0xe7, 0x43, 0x1f, 0x11}}, + "Medical Service" + }, + { {0x2fc28df6,{0xe806, 0x436e, 0xe0b9}, {0x46, 0x1d, 0xeb, 0xad, 0x56, 0x60}}, + "Home Furnishings" + }, + { {0x910313db,{0xafce, 0x4019, 0x1aa4}, {0xe6, 0x2c, 0xe6, 0xd1, 0xfd, 0xf7}}, + "Industrial" + }, + { {0x9e442c6e,{0xe12a, 0x4407, 0xd68a}, {0x1c, 0x5e, 0x19, 0xe7, 0xfe, 0x01}}, + "" + }, + { {0x37e2fe4a,{0xcd71, 0x413f, 0x0cad}, {0x81, 0xc5, 0x2c, 0xf4, 0x78, 0x79}}, + "" + }, + { {0x3c756e09,{0xb2dc, 0x48a6, 0x04a9}, {0x20, 0xb7, 0xc9, 0x9d, 0x14, 0x51}}, + "" + }, + { {0xa1245b1c,{0x156a, 0x48fc, 0x6f96}, {0xa5, 0xa3, 0x22, 0x54, 0x13, 0x97}}, + "Manufacturing" + }, + { {0x5bddbd7a,{0xf3cb, 0x454c, 0x06af}, {0x46, 0x1a, 0x68, 0xea, 0x60, 0x1a}}, + "Note" + }, + { {0xcb6777e1,{0xe0e0, 0x45ce, 0x309f}, {0x8d, 0x61, 0x7a, 0xd9, 0x89, 0xf5}}, + "City" + }, + { {0xbc168c08,{0x2b7f, 0x44be, 0x3883}, {0x81, 0x31, 0x4a, 0x09, 0xf5, 0x78}}, + "Air Base" + }, + { {0xa8857b0f,{0xfc3b, 0x4cd1, 0x9e91}, {0xf5, 0x3b, 0x21, 0xa8, 0x3b, 0xb9}}, + "Battlefield" + }, + { {0x06db55c1,{0xf687, 0x4840, 0x7c80}, {0x95, 0x58, 0x77, 0x8e, 0x5a, 0xdd}}, + "Mining" + }, + { {0xcc61b277,{0xa48c, 0x445a, 0xd9b9}, {0xe5, 0x91, 0x36, 0x18, 0x4e, 0x09}}, + "Mountain" + }, + { {0xfde13186,{0xb6cb, 0x4374, 0xc880}, {0x56, 0x99, 0xeb, 0x51, 0x68, 0x87}}, + "Capital" + }, + { {0xb14d90d1,{0xd943, 0x40ff, 0x9fb7}, {0x9b, 0x92, 0xd1, 0x23, 0xca, 0xef}}, + "Route" + }, + { {0x7eabc63f,{0x05d0, 0x4465, 0xb1b0}, {0x61, 0x2a, 0xf7, 0x4d, 0x0f, 0x4e}}, + "Overnight" + }, + { {0xac39d8b9,{0xfcdc, 0x4b50, 0x9ca6}, {0xea, 0x6c, 0x4b, 0xb5, 0x96, 0x0f}}, + "Route End Active" + }, + { {0xe1b9d86b,{0x95e6, 0x4bd8, 0xd880}, {0x7b, 0x6c, 0xc6, 0xd2, 0x00, 0x34}}, + "Route End Inactive" + }, + { {0x98712315,{0x7e1e, 0x4024, 0x8392}, {0xe3, 0xb8, 0x5a, 0x51, 0x45, 0xb4}}, + "Fuel Stop" + }, + { {0xe5ea5b38,{0x7b80, 0x4b42, 0x0aba}, {0x3d, 0x38, 0xf0, 0xe1, 0x17, 0x9a}}, + "Route Start Active" + }, + { {0x18fd0d49,{0x0a29, 0x433a, 0xd584}, {0xe5, 0xb7, 0x5b, 0xe8, 0x25, 0xbc}}, + "Route Start Inactive" + }, + { {0x2f52144b,{0x903e, 0x4dd9, 0x79af}, {0xe1, 0x66, 0x9b, 0xfc, 0xa9, 0xc1}}, + "Route Stop Active" + }, + { {0xfaf8d826,{0xd27d, 0x4316, 0x0e92}, {0xce, 0x8d, 0x85, 0x93, 0x4c, 0xf5}}, + "Route Stop Inactive" + }, + { {0xff44cae2,{0x707c, 0x4a1c, 0x43af}, {0x8b, 0xb6, 0xb1, 0x19, 0x9c, 0xf2}}, + "Route Via" + }, + { {0x5a50d59b,{0xc15b, 0x49c4, 0x9faa}, {0xc4, 0x1c, 0x4f, 0xe2, 0x95, 0x2a}}, + "Radiation Green" + }, + { {0x19556023,{0xb1e5, 0x4c9c, 0x49ba}, {0x08, 0x52, 0xa1, 0x24, 0x3d, 0x9f}}, + "Radiation Red" + }, + { {0xa54be251,{0x6688, 0x49fb, 0x60b3}, {0x89, 0x56, 0x37, 0x68, 0xc5, 0xb0}}, + "Electricity" + }, + { {0xd793ff0c,{0xfbe0, 0x4383, 0x3183}, {0xcf, 0x4f, 0x04, 0xb7, 0xee, 0x0a}}, + "Personal Furnishings" + }, + { {0x00f90733,{0x7ab5, 0x42cf, 0x468c}, {0xbf, 0x91, 0x27, 0xd3, 0xa8, 0x9c}}, + "Personal Services" + }, + { {0xea677f24,{0xbbe8, 0x4238, 0xee9c}, {0x6c, 0x0a, 0xec, 0x0e, 0x34, 0xf4}}, + "Telephone Black" + }, + { {0x2d8a05b5,{0x8baf, 0x4f28, 0xf58b}, {0xfb, 0x7f, 0x37, 0x34, 0x28, 0xa7}}, + "Government Light" + }, + { {0x40c64dfc,{0xc2d0, 0x4b0e, 0x6582}, {0x3f, 0x26, 0x9c, 0xcb, 0x6f, 0x1d}}, + "Airport Red Square" + }, + { {0xf27adb5d,{0x3629, 0x44c7, 0x95a2}, {0x25, 0x2c, 0x95, 0x24, 0x98, 0x2f}}, + "Propeller Aircraft" + }, + { {0x5a718e13,{0x3547, 0x42c5, 0x6d9d}, {0xb2, 0x82, 0xa5, 0x53, 0xbd, 0x3a}}, + "Jet Aircraft" + }, + { {0x0a471039,{0x2dfe, 0x447e, 0x54be}, {0xa3, 0x93, 0xae, 0x9a, 0xdd, 0xac}}, + "Government" + }, + { {0x4a59da2f,{0xe1c3, 0x42c3, 0x6ca1}, {0x06, 0xb9, 0x14, 0x1b, 0x89, 0x99}}, + "USA Regional" + }, + { {0xf16500a9,{0xa845, 0x4293, 0xae89}, {0x5c, 0x29, 0xbb, 0x0d, 0x06, 0xf7}}, + "House 2" + }, + { {0x7b05524d,{0xcb5a, 0x456f, 0x96b3}, {0x03, 0x61, 0x24, 0x54, 0x6a, 0x54}}, + "Picnic" + }, + { {0xb88ad7a1,{0xb94d, 0x42e8, 0x2b9d}, {0xf5, 0x4c, 0x2b, 0xff, 0x57, 0xdc}}, + "Restaurant" + }, + { {0xdc48a20a,{0x54a2, 0x4c61, 0x1fbe}, {0x02, 0x74, 0x5b, 0xe9, 0x18, 0x99}}, + "Store 2" + }, + { {0x6b5ab040,{0x96df, 0x46ae, 0xacb8}, {0xe4, 0x47, 0x66, 0x3f, 0xec, 0x9b}}, + "" + }, + { {0x153b2cff,{0x6232, 0x4294, 0xd59a}, {0xc5, 0xa0, 0x7b, 0xe0, 0x16, 0xeb}}, + "Blue Star" + }, + { {0xf276f6b3,{0x586a, 0x4bf8, 0x2f82}, {0xf2, 0x69, 0xe3, 0x76, 0x7e, 0xd5}}, + "" + }, + { {0x91d242c8,{0x0986, 0x4fad, 0x8286}, {0xec, 0x79, 0x79, 0xcd, 0xab, 0x02}}, + "Running" + }, + { {0x8b0078db,{0x6ee0, 0x4caa, 0xd3b5}, {0xfe, 0xe1, 0xc2, 0xbf, 0x94, 0x7d}}, + "Transportation" + }, + { {0x0599f6c9,{0x478e, 0x4f63, 0x78a5}, {0xed, 0x31, 0xb5, 0xae, 0xda, 0x89}}, + "Fishing 2" + }, + { {0x7389128c,{0x0e78, 0x4d5d, 0x4189}, {0xb8, 0xf3, 0xb5, 0xbd, 0x70, 0xb1}}, + "Automotive" + }, + { {0x0362b593,{0x3df6, 0x48ed, 0xc489}, {0x85, 0x13, 0xc1, 0xc0, 0xb9, 0x0d}}, + "Cloudy" + }, + { {0xf0717a94,{0xd048, 0x4770, 0x9bab}, {0x80, 0x09, 0xbd, 0x4b, 0x1e, 0x75}}, + "Partly Cloudy" + }, + { {0x14486bbc,{0xae6b, 0x44ea, 0xd6b9}, {0xbf, 0x9a, 0x39, 0x7a, 0x51, 0x6c}}, + "Mostly Cloudy" + }, + { {0x7a258c70,{0xabec, 0x4cff, 0x4983}, {0x84, 0xdc, 0x2f, 0x2e, 0xff, 0x28}}, + "Hurricane" + }, + { {0xeff260d4,{0x46d5, 0x4fb5, 0xc79c}, {0x5e, 0x06, 0xc8, 0xab, 0x7a, 0x2b}}, + "Lightning" + }, + { {0xc3d70220,{0x5154, 0x4766, 0xf0af}, {0xdf, 0x86, 0x74, 0x40, 0x5f, 0x8c}}, + "Rain" + }, + { {0xf2dfbc91,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Flag" + }, + { {0xf2dfbc92,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Flag" + }, + { {0xf2dfbc93,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Flag" + }, + { {0xf2dfbc94,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Flag" + }, + { {0xf2dfbc95,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Flag 2" + }, + { {0xf2dfbc96,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Flag" + }, + { {0xf2dfbc97,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Flag" + }, + { {0xf2dfbc98,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Flag" + }, + { {0xf2dfbc99,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Flag" + }, + { {0xf2dfbc9a,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Flag" + }, + { {0x623e1ee1,{0xaf27, 0x100f, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Dark Blue Map Pin" + }, + { {0xf2dfbc9d,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Map Pin" + }, + { {0xf2dfbc9e,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Map Pin" + }, + { {0xf2dfbc9f,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Map Pin" + }, + { {0xf2dfbca0,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Map Pin" + }, + { {0xf2dfbca1,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Map Pin" + }, + { {0xf2dfbca2,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Map Pin" + }, + { {0xf2dfbca3,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Map Pin" + }, + { {0xf2dfbca4,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Gray Map Pin" + }, + { {0xf2dfbca5,{0x7ae6, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Gray Map Pin" + }, + { {0xd1703de0,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Green Dot" + }, + { {0xd1703de1,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Green Dot" + }, + { {0xd1703de2,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue Dot" + }, + { {0xd1703de3,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Blue Dot" + }, + { {0xd1703de5,{0x5c45, 0x11d5, 0xb8ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Red Dot" + }, + { {0x45c088e0,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Dark Red Dot" + }, + { {0x45c088e1,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Yellow Dot" + }, + { {0x45c088e2,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Brown Dot" + }, + { {0x45c088e3,{0x672d, 0x11d5, 0xcbae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Light Blue Dot" + }, + { {0xbde3a8a1,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Blue-Green Dot" + }, + { {0xbde3a8a2,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Green Dot" + }, + { {0xbde3a8a3,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Green Dot" + }, + { {0xbde3a8a4,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue Dot" + }, + { {0xbde3a8a5,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Blue Dot" + }, + { {0xbde3a8a6,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Red Dot" + }, + { {0xbde3a8a7,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Dark Red Dot" + }, + { {0xbde3a8a8,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Yellow Dot" + }, + { {0xbde3a8a9,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Brown Dot" + }, + { {0xbde3a8aa,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Light Blue Dot" + }, + { {0xbde3a8ab,{0x7aeb, 0x11d5, 0xf3ae}, {0x00, 0x01, 0x02, 0x31, 0x5f, 0xfd}}, + "Small Blue-Green Dot" + }, + { {0x623e1ee0,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red Flag" + }, + { {0x623e1ee1,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Map Pin" + }, + { {0x623e1ee2,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Yellow Square" + }, + { {0x623e1ee3,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Red X" + }, + { {0x623e1ee4,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Blue Circle" + }, + { {0x623e1ee5,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "House" + }, + { {0x623e1ee7,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Triangle" + }, + { {0x623e1ee8,{0xaf27, 0x11d3, 0x29bc}, {0x00, 0x50, 0x04, 0x02, 0xf5, 0x32}}, + "Green Star" + }, + { {0x9d277805,{0xe2f8, 0x4f43, 0x3f97}, {0x35, 0x0d, 0x40, 0xae, 0x5c, 0xd3}}, + "Geocache" + }, + { {0xcb8aad04,{0xcc2d, 0x47f2, 0x428a}, {0x80, 0xf7, 0xd6, 0x68, 0xed, 0x32}}, + "Geocache Found" + }, + { {0x7341c1f4,{0xdecd, 0x4d35, 0x45a5}, {0x52, 0x25, 0x5e, 0xbf, 0xe6, 0x51}}, + "Tent" + }, + { {0x835b84e2,{0xf10c, 0x45cb, 0x958f}, {0x18, 0x3a, 0xc2, 0x2a, 0xe5, 0x28}}, + "Tipup Up" + }, + { {0xce06fc92,{0xbb0c, 0x4ec1, 0xda93}, {0x64, 0x4a, 0x60, 0xbe, 0x40, 0x90}}, + "Topup Down" + }, }; -int FindIconByName( const char *name, GUID *guid ) { - int i = 0; - for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) - { - if ( !case_ignore_strcmp(name, default_guids[i].name)) { - memcpy( guid, &(default_guids[i].guid), sizeof(GUID)); - return 1; - } - } - return 0; +int FindIconByName(const char *name, GUID *guid) +{ + int i = 0; + for (i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++) { + if (!case_ignore_strcmp(name, default_guids[i].name)) { + memcpy(guid, &(default_guids[i].guid), sizeof(GUID)); + return 1; + } + } + return 0; } -int FindIconByGuid( GUID *guid, char **name ) { - int i = 0; - for ( i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++ ) - { - if ( !memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { - *name = default_guids[i].name; - return 1; - } - } - return 0; +int FindIconByGuid(GUID *guid, char **name) +{ + int i = 0; + for (i = 0; i < (sizeof(default_guids)/sizeof(struct defguid)); i++) { + if (!memcmp(guid, &default_guids[i].guid, sizeof(GUID))) { + *name = default_guids[i].name; + return 1; + } + } + return 0; } diff --git a/gpsbabel/arcdist.c b/gpsbabel/arcdist.c index ecbc75db2..f7b493e3a 100644 --- a/gpsbabel/arcdist.c +++ b/gpsbabel/arcdist.c @@ -32,139 +32,146 @@ static char *exclopt = NULL; static char *ptsopt = NULL; typedef struct { - double distance; + double distance; } extra_data; static arglist_t arcdist_args[] = { - {"file", &arcfileopt, "File containing vertices of arc", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - {"distance", &distopt, "Maximum distance from arc", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - {"exclude", &exclopt, "Exclude points close to the arc", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX}, - {"points", &ptsopt, "Use distance from vertices not lines", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "file", &arcfileopt, "File containing vertices of arc", + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "distance", &distopt, "Maximum distance from arc", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points close to the arc", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "points", &ptsopt, "Use distance from vertices not lines", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define BADVAL 999999 -void +void arcdist_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - double dist; - extra_data *ed; - double lat1, lon1, lat2, lon2; - int fileline = 0; - char *line; - gbfile *file_in; - - file_in = gbfopen(arcfileopt, "r", MYNAME); - - lat1 = lon1 = lat2 = lon2 = BADVAL; - while ((line = gbfgetstr(file_in))) { - char *pound = NULL; - int argsfound = 0; - - fileline++; - - pound = strchr( line, '#' ); - if ( pound ) { - if ( 0 == strncmp( pound, "#break", 6)) { - lat1 = lon1 = BADVAL; - } - *pound = '\0'; - } - - lat2 = lon2 = BADVAL; - argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); - - if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { - warning(MYNAME ": Warning: Arc file contains unusable vertex on line %d.\n", fileline ); - } - else if ( lat2 != BADVAL && lon2 != BADVAL && - (ptsopt || (lat1 != BADVAL && lon1 != BADVAL ))) { - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - - waypointp = (waypoint *)elem; - if ( waypointp->extra_data ) { - ed = (extra_data *) waypointp->extra_data; - } - else { - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->distance = BADVAL; - } - if ( ed->distance == BADVAL || ed->distance >= pos_dist ) { - if ( ptsopt ) { - dist = gcdist( RAD(lat2), RAD(lon2), - RAD(waypointp->latitude), - RAD(waypointp->longitude) ); - } - else { - dist = linedist(lat1, lon1, lat2, lon2, - waypointp->latitude, - waypointp->longitude ); - } - - /* convert radians to float point statute miles */ - dist = radtomiles(dist); - - if ( ed->distance > dist ) { - ed->distance = dist; - } - waypointp->extra_data = ed; - } - } - } - lat1 = lat2; - lon1 = lon2; - } - - gbfclose(file_in); - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - ed = (extra_data *) wp->extra_data; - wp->extra_data = NULL; - if ( ed ) { - if ((ed->distance >= pos_dist) == (exclopt == NULL)) { - waypt_del(wp); - waypt_free(wp); - } - xfree( ed ); - } - } + queue * elem, * tmp; + waypoint * waypointp; + double dist; + extra_data *ed; + double lat1, lon1, lat2, lon2; + int fileline = 0; + char *line; + gbfile *file_in; + + file_in = gbfopen(arcfileopt, "r", MYNAME); + + lat1 = lon1 = lat2 = lon2 = BADVAL; + while ((line = gbfgetstr(file_in))) { + char *pound = NULL; + int argsfound = 0; + + fileline++; + + pound = strchr(line, '#'); + if (pound) { + if (0 == strncmp(pound, "#break", 6)) { + lat1 = lon1 = BADVAL; + } + *pound = '\0'; + } + + lat2 = lon2 = BADVAL; + argsfound = sscanf(line, "%lf %lf", &lat2, &lon2); + + if (argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME ": Warning: Arc file contains unusable vertex on line %d.\n", fileline); + } else if (lat2 != BADVAL && lon2 != BADVAL && + (ptsopt || (lat1 != BADVAL && lon1 != BADVAL))) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint *)elem; + if (waypointp->extra_data) { + ed = (extra_data *) waypointp->extra_data; + } else { + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = BADVAL; + } + if (ed->distance == BADVAL || ed->distance >= pos_dist) { + if (ptsopt) { + dist = gcdist(RAD(lat2), RAD(lon2), + RAD(waypointp->latitude), + RAD(waypointp->longitude)); + } else { + dist = linedist(lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude); + } + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if (ed->distance > dist) { + ed->distance = dist; + } + waypointp->extra_data = ed; + } + } + } + lat1 = lat2; + lon1 = lon2; + } + + gbfclose(file_in); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + ed = (extra_data *) wp->extra_data; + wp->extra_data = NULL; + if (ed) { + if ((ed->distance >= pos_dist) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + } + xfree(ed); + } + } } void -arcdist_init(const char *args) { - char *fm; +arcdist_init(const char *args) +{ + char *fm; - pos_dist = 0; + pos_dist = 0; - if (distopt) { - pos_dist = strtod(distopt, &fm); + if (distopt) { + pos_dist = strtod(distopt, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to feet */ - pos_dist *= .6214; - } - } + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } } void -arcdist_deinit(void) { - /* do nothing */ +arcdist_deinit(void) +{ + /* do nothing */ } filter_vecs_t arcdist_vecs = { - arcdist_init, - arcdist_process, - arcdist_deinit, - NULL, - arcdist_args + arcdist_init, + arcdist_process, + arcdist_deinit, + NULL, + arcdist_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/avltree.c b/gpsbabel/avltree.c index 08c6c6e87..121277f39 100644 --- a/gpsbabel/avltree.c +++ b/gpsbabel/avltree.c @@ -25,7 +25,7 @@ #define MYNAME "avltree" #ifdef DEBUG_MEM -# define AVLTREE_MAGIC 0x41564c53 +# define AVLTREE_MAGIC 0x41564c53 /* ((((((0L | 'A') << 8) | 'V') << 8) | 'L') << 8) | 'T'; */ #endif @@ -62,29 +62,31 @@ static void avltree_save_key(avltree_t *tree, const char *key); avltree_t * avltree_init(const int options, const char *module) { - avltree_t *tree; - - if ((module == NULL) || (*module == '\0')) - fatal(MYNAME ": 'avltree_init' should be called with a valid module name!\n"); - - tree = (avltree_t*) xcalloc(1, sizeof(*tree)); - tree->options = options; - tree->module = module; - - if (options & AVLTREE_NON_CASE_SENSITIVE) { - if (options & AVLTREE_DESCENDING) - tree->compare = avltree_case_ignore_strcmpr; /* descending, non-case-sensitive */ - else - tree->compare = case_ignore_strcmp; /* ascending, non-case-sensitive */ - } - else { - if (options & AVLTREE_DESCENDING) - tree->compare = avltree_strcmpr; /* descending, case-sensitive */ - else - tree->compare = strcmp; /* ascending, case-sensitive */ - } - - return tree; + avltree_t *tree; + + if ((module == NULL) || (*module == '\0')) { + fatal(MYNAME ": 'avltree_init' should be called with a valid module name!\n"); + } + + tree = (avltree_t*) xcalloc(1, sizeof(*tree)); + tree->options = options; + tree->module = module; + + if (options & AVLTREE_NON_CASE_SENSITIVE) { + if (options & AVLTREE_DESCENDING) { + tree->compare = avltree_case_ignore_strcmpr; /* descending, non-case-sensitive */ + } else { + tree->compare = case_ignore_strcmp; /* ascending, non-case-sensitive */ + } + } else { + if (options & AVLTREE_DESCENDING) { + tree->compare = avltree_strcmpr; /* descending, case-sensitive */ + } else { + tree->compare = strcmp; /* ascending, case-sensitive */ + } + } + + return tree; } /* Delete all items of tree [tree] */ @@ -92,19 +94,19 @@ avltree_init(const int options, const char *module) int avltree_clear(avltree_t *tree) { - int res; - - AVLTREE_CHECK_HANDLE(tree); - - res = tree->count; - avltree_save_key(tree, NULL); - if (res) { - avltree_node_free(tree, tree->root); - /* avltree_node_free doesn't touch 'count' */ - tree->count = 0; - tree->root = NULL; - } - return res; + int res; + + AVLTREE_CHECK_HANDLE(tree); + + res = tree->count; + avltree_save_key(tree, NULL); + if (res) { + avltree_node_free(tree, tree->root); + /* avltree_node_free doesn't touch 'count' */ + tree->count = 0; + tree->root = NULL; + } + return res; } /* Destroy an AVL Tree */ @@ -112,8 +114,8 @@ avltree_clear(avltree_t *tree) void avltree_done(avltree_t *tree) { - avltree_clear(tree); - xfree(tree); + avltree_clear(tree); + xfree(tree); } @@ -122,9 +124,9 @@ avltree_done(avltree_t *tree) int avltree_count(const avltree_t *tree) { - AVLTREE_CHECK_HANDLE(tree); + AVLTREE_CHECK_HANDLE(tree); - return tree->count; + return tree->count; } @@ -133,15 +135,15 @@ avltree_count(const avltree_t *tree) int avltree_delete(avltree_t *tree, const char *key) { - int changed = 0; - - AVLTREE_CHECK_HANDLE(tree); + int changed = 0; - if (key == NULL) - fatal("%s/%s.%d: Attempt to delete a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); + AVLTREE_CHECK_HANDLE(tree); - return avltree_delete_node(tree, key, &tree->root, &changed); + if (key == NULL) + fatal("%s/%s.%d: Attempt to delete a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); + + return avltree_delete_node(tree, key, &tree->root, &changed); } @@ -150,15 +152,16 @@ avltree_delete(avltree_t *tree, const char *key) avltree_t * avltree_dupe(const avltree_t *tree, const char *module) { - avltree_t *dupe; - - AVLTREE_CHECK_HANDLE(tree); - - dupe = avltree_init(tree->options, module); - if ((dupe->count = tree->count)) - dupe->root = avltree_dupe_node(tree, tree->root); - - return dupe; + avltree_t *dupe; + + AVLTREE_CHECK_HANDLE(tree); + + dupe = avltree_init(tree->options, module); + if ((dupe->count = tree->count)) { + dupe->root = avltree_dupe_node(tree, tree->root); + } + + return dupe; } @@ -167,26 +170,27 @@ avltree_dupe(const avltree_t *tree, const char *module) int avltree_find(const avltree_t *tree, const char *key, const void **data) { - avlnode_t *node; - - AVLTREE_CHECK_HANDLE(tree); - - node = tree->root; - while (node) { - int compare = tree->compare(key, node->key); - - if (compare < 0) - node = node->left; - else if (compare > 0) - node = node->right; - else { - if (data) - (*data) = node->data; - break; - } - } - - return (node) ? 1 : 0; + avlnode_t *node; + + AVLTREE_CHECK_HANDLE(tree); + + node = tree->root; + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) { + node = node->left; + } else if (compare > 0) { + node = node->right; + } else { + if (data) { + (*data) = node->data; + } + break; + } + } + + return (node) ? 1 : 0; } @@ -195,18 +199,24 @@ avltree_find(const avltree_t *tree, const char *key, const void **data) const char * avltree_first(const avltree_t *tree, const void **data) { - avlnode_t *node; + avlnode_t *node; + + AVLTREE_CHECK_HANDLE(tree); - AVLTREE_CHECK_HANDLE(tree); + node = tree->root; + if (! node) { + return NULL; + } - node = tree->root; - if (! node) return NULL; - - while (node->left) node = node->left; - avltree_save_key((avltree_t *)tree, node->key); - if (data) (*data) = node->data; + while (node->left) { + node = node->left; + } + avltree_save_key((avltree_t *)tree, node->key); + if (data) { + (*data) = node->data; + } - return tree->key; + return tree->key; } @@ -215,12 +225,13 @@ avltree_first(const avltree_t *tree, const void **data) int avltree_height(const avltree_t *tree) { - AVLTREE_CHECK_HANDLE(tree); + AVLTREE_CHECK_HANDLE(tree); - if (tree->count) - return avltree_node_height(tree->root); - else - return 0; + if (tree->count) { + return avltree_node_height(tree->root); + } else { + return 0; + } } @@ -229,17 +240,17 @@ avltree_height(const avltree_t *tree) int avltree_insert(avltree_t *tree, const char *key, const void *data) { - int count; - - AVLTREE_CHECK_HANDLE(tree); + int count; + + AVLTREE_CHECK_HANDLE(tree); - if (key == NULL) - fatal("%s/%s.%d: Attempt to insert a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); + if (key == NULL) + fatal("%s/%s.%d: Attempt to insert a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); - count = tree->count; - avltree_insert_node(tree, &tree->root, key, data); - return (count != tree->count) ? 1 : 0; + count = tree->count; + avltree_insert_node(tree, &tree->root, key, data); + return (count != tree->count) ? 1 : 0; } @@ -248,26 +259,29 @@ avltree_insert(avltree_t *tree, const char *key, const void *data) const char * avltree_next(const avltree_t *tree, const char *key, const void **data) { - avlnode_t *node; - - AVLTREE_CHECK_HANDLE(tree); - - if (key == NULL) - fatal("%s/%s.%d: Attempt to look for a NULL-pointer!\n", - tree->module, MYNAME, __LINE__); - - node = tree->root; - if (! node) return NULL; - - if ((node = avltree_find_next(tree, node, key))) { - avltree_save_key((avltree_t *)tree, node->key); - if (data) - (*data) = node->data; - } - else - avltree_save_key((avltree_t *)tree, NULL); + avlnode_t *node; + + AVLTREE_CHECK_HANDLE(tree); + + if (key == NULL) + fatal("%s/%s.%d: Attempt to look for a NULL-pointer!\n", + tree->module, MYNAME, __LINE__); - return tree->key; + node = tree->root; + if (! node) { + return NULL; + } + + if ((node = avltree_find_next(tree, node, key))) { + avltree_save_key((avltree_t *)tree, node->key); + if (data) { + (*data) = node->data; + } + } else { + avltree_save_key((avltree_t *)tree, NULL); + } + + return tree->key; } @@ -279,236 +293,243 @@ avltree_next(const avltree_t *tree, const char *key, const void **data) void avltree_check_handle(const avltree_t *tree) { - if (! tree) - fatal(MYNAME ": Invalid (NULL-) pointer!\n"); - if (tree->magic != AVLTREE_MAGIC) - fatal(MYNAME ": Invalid (no AVL tree object) pointer!\n"); + if (! tree) { + fatal(MYNAME ": Invalid (NULL-) pointer!\n"); + } + if (tree->magic != AVLTREE_MAGIC) { + fatal(MYNAME ": Invalid (no AVL tree object) pointer!\n"); + } } -#endif +#endif -static void +static void avltree_node_free(const avltree_t *tree, avlnode_t *node) { - if ((! (tree->options & AVLTREE_STATIC_KEYS)) && node->key) - xfree((char *)node->key); - if (node->left) - avltree_node_free(tree, node->left); - if (node->right) - avltree_node_free(tree, node->right); - xfree(node); + if ((!(tree->options & AVLTREE_STATIC_KEYS)) && node->key) { + xfree((char *)node->key); + } + if (node->left) { + avltree_node_free(tree, node->left); + } + if (node->right) { + avltree_node_free(tree, node->right); + } + xfree(node); } static int avltree_node_height(avlnode_t *node) { - int height = 1; - - if (node->balance < 0) - height += avltree_node_height(node->left); - else if (node->right) - height += avltree_node_height(node->right); - - return height; + int height = 1; + + if (node->balance < 0) { + height += avltree_node_height(node->left); + } else if (node->right) { + height += avltree_node_height(node->right); + } + + return height; } static avlnode_t * avltree_right_rotation(avlnode_t *A) { -/* -> A B -> / \ / \ -> \ / \ -> B -->> A . -> / \ / \ / \ -> \ -> . -> / \ -*/ - avlnode_t *B; - - B = A->right; - A->right = B->left; - B->left = A; - - /* update balance of all touched nodes */ - /* reference: */ - - B->balance--; - A->balance = -(B->balance); - - return B; + /* + > A B + > / \ / \ + > \ / \ + > B -->> A . + > / \ / \ / \ + > \ + > . + > / \ + */ + avlnode_t *B; + + B = A->right; + A->right = B->left; + B->left = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance--; + A->balance = -(B->balance); + + return B; } static avlnode_t * avltree_left_rotation(avlnode_t *A) { -/* -> A B -> / \ / \ -> / / \ -> B -->> . A -> / \ / \ / \ -> / -> . -> / \ -*/ - avlnode_t *B; - - B = A->left; - A->left = B->right; - B->right = A; - - /* update balance of all touched nodes */ - /* reference: */ - - B->balance++; - A->balance = -(B->balance); - - return B; + /* + > A B + > / \ / \ + > / / \ + > B -->> . A + > / \ / \ / \ + > / + > . + > / \ + */ + avlnode_t *B; + + B = A->left; + A->left = B->right; + B->right = A; + + /* update balance of all touched nodes */ + /* reference: */ + + B->balance++; + A->balance = -(B->balance); + + return B; } - - + + static avlnode_t * avltree_left_right_rotation(avlnode_t *A) { -/* -> A C -> / \ / \ -> / / \ -> B -->> B A -> / \ / \ / \ -> \ -> C -*/ - avlnode_t *B, *C; - - B = A->left; - C = B->right; - A->left = C->right; - B->right = C->left; - C->right = A; - C->left = B; - - /* update balance of all touched nodes */ - /* reference: */ - - A->balance = (C->balance > 0) ? 0 : -(C->balance); - B->balance = (C->balance < 0) ? 0 : -(C->balance); - C->balance = 0; - - return C; + /* + > A C + > / \ / \ + > / / \ + > B -->> B A + > / \ / \ / \ + > \ + > C + */ + avlnode_t *B, *C; + + B = A->left; + C = B->right; + A->left = C->right; + B->right = C->left; + C->right = A; + C->left = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance > 0) ? 0 : -(C->balance); + B->balance = (C->balance < 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; } static avlnode_t * avltree_right_left_rotation(avlnode_t *A) { -/* -> A C -> / \ / \ -> \ / \ -> B -->> B A -> / \ / \ / \ -> / -> C -*/ - avlnode_t *B, *C; - - B = A->right; - C = B->left; - A->right = C->left; - B->left = C->right; - C->left = A; - C->right = B; - - /* update balance of all touched nodes */ - /* reference: */ - - A->balance = (C->balance < 0) ? 0 : -(C->balance); - B->balance = (C->balance > 0) ? 0 : -(C->balance); - C->balance = 0; - - return C; + /* + > A C + > / \ / \ + > \ / \ + > B -->> B A + > / \ / \ / \ + > / + > C + */ + avlnode_t *B, *C; + + B = A->right; + C = B->left; + A->right = C->left; + B->left = C->right; + C->left = A; + C->right = B; + + /* update balance of all touched nodes */ + /* reference: */ + + A->balance = (C->balance < 0) ? 0 : -(C->balance); + B->balance = (C->balance > 0) ? 0 : -(C->balance); + C->balance = 0; + + return C; } static int avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const void *data) { - int changed = 0; - int compare; - avlnode_t *node = (*root); - - if (node == NULL) { - (*root) = node = (avlnode_t*) xcalloc(1, sizeof(*node)); - if (tree->options & AVLTREE_STATIC_KEYS) - node->key = key; - else - node->key = xstrdup(key); - node->data = data; - tree->count++; - return 1; /* anyway, our tree has been changed */ - } - - compare = tree->compare(key, node->key); - - if (compare < 0) { - if (avltree_insert_node(tree, &node->left, key, data)) { - changed = (--node->balance != 0); - switch(node->balance) { - case -2: - if (node->left->balance < 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - case 0: - changed = 0; - case -1: - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - else - changed = 0; - } - else if (compare > 0) { - if (avltree_insert_node(tree, &node->right, key, data)) { - changed = (++node->balance != 0); - switch(node->balance) { - case +2: - if (node->right->balance > 0) - node = avltree_right_rotation(node); - else - node = avltree_right_left_rotation(node); - (*root) = node; - case 0: - changed = 0; - case +1: - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - else - changed = 0; - } - else { - if (tree->options & AVLTREE_PARANOIAC) - fatal("%s/%s.%d: Duplicate keys are not allowed (\"%s\")!\n", - tree->module, MYNAME, __LINE__, key); - changed = 0; - } - - return changed; + int changed = 0; + int compare; + avlnode_t *node = (*root); + + if (node == NULL) { + (*root) = node = (avlnode_t*) xcalloc(1, sizeof(*node)); + if (tree->options & AVLTREE_STATIC_KEYS) { + node->key = key; + } else { + node->key = xstrdup(key); + } + node->data = data; + tree->count++; + return 1; /* anyway, our tree has been changed */ + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + if (avltree_insert_node(tree, &node->left, key, data)) { + changed = (--node->balance != 0); + switch (node->balance) { + case -2: + if (node->left->balance < 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + case 0: + changed = 0; + case -1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } else { + changed = 0; + } + } else if (compare > 0) { + if (avltree_insert_node(tree, &node->right, key, data)) { + changed = (++node->balance != 0); + switch (node->balance) { + case +2: + if (node->right->balance > 0) { + node = avltree_right_rotation(node); + } else { + node = avltree_right_left_rotation(node); + } + (*root) = node; + case 0: + changed = 0; + case +1: + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } else { + changed = 0; + } + } else { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Duplicate keys are not allowed (\"%s\")!\n", + tree->module, MYNAME, __LINE__, key); + changed = 0; + } + + return changed; } @@ -516,202 +537,212 @@ avltree_insert_node(avltree_t *tree, avlnode_t **root, const char *key, const vo static int avltree_delete_node(avltree_t *tree, const char *key, avlnode_t **root, int *changed) { - avlnode_t *node = (*root); - int deleted = 0; - int compare; - - if (node == NULL) { - if (tree->options & AVLTREE_PARANOIAC) - fatal("%s/%s.%d: Key to delete \"%s\" not found!\n", - tree->module, MYNAME, __LINE__, key); - return 0; - } - - compare = tree->compare(key, node->key); - - if (compare < 0) { - deleted = avltree_delete_node(tree, key, &node->left, changed); - if (*changed) { - node->balance++; /* shift weight to right */ - switch(node->balance) { - case +1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case +2: - if (node->right->balance >= 0) - node = avltree_right_rotation(node); - else - node = avltree_right_left_rotation(node); - (*root) = node; - if (node->balance == -1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - } - else if (compare > 0) { - deleted = avltree_delete_node(tree, key, &node->right, changed); - if (*changed) { - node->balance--; /* shift weight to left */ - switch(node->balance) { - case -1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case -2: - if (node->left->balance <= 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - if (node->balance == +1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - } - else { - if (node->left) { - if (node->right) { - const char *temp_key; - const void *temp_data; - avlnode_t *succ = node->right; - - while (succ->left) succ = succ->left; /* find successor */ - - temp_key = succ->key; /* swap contents */ - temp_data = succ->data; - succ->key = node->key; - succ->data = node->data; - node->key = temp_key; - node->data = temp_data; - - deleted = avltree_delete_node(tree, key, &node->right, changed); - - if (*changed) { - node->balance--; /* shift weight to left */ - switch(node->balance) { - case -1: - (*changed) = 0; /* stop rebalancing */ - case 0: - break; - case -2: - if (node->left->balance <= 0) - node = avltree_left_rotation(node); - else - node = avltree_left_right_rotation(node); - (*root) = node; - if (node->balance == +1) - (*changed) = 0; - break; - default: - /* should be impossible :-) */ - fatal(AVLTREE_INVALID_BALANCE); - } - } - return deleted; - } - else { /* only left branch */ - (*root) = node->left; - node->left = NULL; - } - } - else if (node->right) { /* only right branch */ - (*root) = node->right; - node->right = NULL; - } - else /* only a simple leaf */ - (*root) = NULL; - - avltree_node_free(tree, node); - tree->count--; - (*changed) = 1; - deleted = 1; - } - - return deleted; + avlnode_t *node = (*root); + int deleted = 0; + int compare; + + if (node == NULL) { + if (tree->options & AVLTREE_PARANOIAC) + fatal("%s/%s.%d: Key to delete \"%s\" not found!\n", + tree->module, MYNAME, __LINE__, key); + return 0; + } + + compare = tree->compare(key, node->key); + + if (compare < 0) { + deleted = avltree_delete_node(tree, key, &node->left, changed); + if (*changed) { + node->balance++; /* shift weight to right */ + switch (node->balance) { + case +1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case +2: + if (node->right->balance >= 0) { + node = avltree_right_rotation(node); + } else { + node = avltree_right_left_rotation(node); + } + (*root) = node; + if (node->balance == -1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } else if (compare > 0) { + deleted = avltree_delete_node(tree, key, &node->right, changed); + if (*changed) { + node->balance--; /* shift weight to left */ + switch (node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + if (node->balance == +1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + } else { + if (node->left) { + if (node->right) { + const char *temp_key; + const void *temp_data; + avlnode_t *succ = node->right; + + while (succ->left) { + succ = succ->left; /* find successor */ + } + + temp_key = succ->key; /* swap contents */ + temp_data = succ->data; + succ->key = node->key; + succ->data = node->data; + node->key = temp_key; + node->data = temp_data; + + deleted = avltree_delete_node(tree, key, &node->right, changed); + + if (*changed) { + node->balance--; /* shift weight to left */ + switch (node->balance) { + case -1: + (*changed) = 0; /* stop rebalancing */ + case 0: + break; + case -2: + if (node->left->balance <= 0) { + node = avltree_left_rotation(node); + } else { + node = avltree_left_right_rotation(node); + } + (*root) = node; + if (node->balance == +1) { + (*changed) = 0; + } + break; + default: + /* should be impossible :-) */ + fatal(AVLTREE_INVALID_BALANCE); + } + } + return deleted; + } else { /* only left branch */ + (*root) = node->left; + node->left = NULL; + } + } else if (node->right) { /* only right branch */ + (*root) = node->right; + node->right = NULL; + } else { /* only a simple leaf */ + (*root) = NULL; + } + + avltree_node_free(tree, node); + tree->count--; + (*changed) = 1; + deleted = 1; + } + + return deleted; } static avlnode_t * avltree_dupe_node(const avltree_t *tree, const avlnode_t *node) { - avlnode_t *res = (avlnode_t*) xcalloc(1, sizeof(*res)); - - if (tree->options & AVLTREE_STATIC_KEYS) - res->key = node->key; - else - res->key = xstrdup(node->key); - - res->balance = node->balance; - if (node->left) - res->left = avltree_dupe_node(tree, node->left); - if (node->right) - res->right = avltree_dupe_node(tree, node->right); - - return res; + avlnode_t *res = (avlnode_t*) xcalloc(1, sizeof(*res)); + + if (tree->options & AVLTREE_STATIC_KEYS) { + res->key = node->key; + } else { + res->key = xstrdup(node->key); + } + + res->balance = node->balance; + if (node->left) { + res->left = avltree_dupe_node(tree, node->left); + } + if (node->right) { + res->right = avltree_dupe_node(tree, node->right); + } + + return res; } static int avltree_strcmpr(const char *s1, const char *s2) { - return -(strcmp(s1, s2)); + return -(strcmp(s1, s2)); } static int avltree_case_ignore_strcmpr(const char *s1, const char *s2) { - return -(case_ignore_strcmp(s1, s2)); + return -(case_ignore_strcmp(s1, s2)); } static avlnode_t * avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key) { - avlnode_t *prev = NULL; - - if (key == NULL) { - if ((node = tree->root)) { - while (node->left) - node = node->left; - } - return node; - } - - while (node) { - int compare = tree->compare(key, node->key); - - if (compare < 0) { - prev = node; - node = node->left; - } - else if (compare > 0) - node = node->right; - else { - if ((node = node->right)) - while (node->left) node = node->left; - else - node = prev; - return node; - } - } - /* The previous node was deleted and we could not find it. */ - return prev; + avlnode_t *prev = NULL; + + if (key == NULL) { + if ((node = tree->root)) { + while (node->left) { + node = node->left; + } + } + return node; + } + + while (node) { + int compare = tree->compare(key, node->key); + + if (compare < 0) { + prev = node; + node = node->left; + } else if (compare > 0) { + node = node->right; + } else { + if ((node = node->right)) + while (node->left) { + node = node->left; + } + else { + node = prev; + } + return node; + } + } + /* The previous node was deleted and we could not find it. */ + return prev; } /* Save [key] for a possible delete before next op. Now we have no problem with: - + curr = NULL; while ((curr = avtree_next(tree, curr, NULL))) { avltree_delete(tree, curr); @@ -720,30 +751,30 @@ avltree_find_next(const avltree_t *tree, avlnode_t *node, const char *key) static void avltree_save_key(avltree_t *tree, const char *key) { - if (tree->options & AVLTREE_STATIC_KEYS) - tree->key = key; - else { - if (key == NULL) { - if (tree->key_sz) { - xfree((char *)tree->key); - tree->key_sz = 0; - } - tree->key = NULL; - } - else { - int n, n8; - - n = strlen(key) + 1; - n8 = ((n + 7) / 8) * 8; - - if (n8 > tree->key_sz) { - if (tree->key_sz == 0) - tree->key = xmalloc(n8); - else - tree->key = xrealloc((char *)tree->key, n8); - tree->key_sz = n8; - } - strncpy((char *)tree->key, key, n); - } - } + if (tree->options & AVLTREE_STATIC_KEYS) { + tree->key = key; + } else { + if (key == NULL) { + if (tree->key_sz) { + xfree((char *)tree->key); + tree->key_sz = 0; + } + tree->key = NULL; + } else { + int n, n8; + + n = strlen(key) + 1; + n8 = ((n + 7) / 8) * 8; + + if (n8 > tree->key_sz) { + if (tree->key_sz == 0) { + tree->key = xmalloc(n8); + } else { + tree->key = xrealloc((char *)tree->key, n8); + } + tree->key_sz = n8; + } + strncpy((char *)tree->key, key, n); + } + } } diff --git a/gpsbabel/avltree.h b/gpsbabel/avltree.h index 8df8ffb67..e1e73277d 100644 --- a/gpsbabel/avltree.h +++ b/gpsbabel/avltree.h @@ -1,7 +1,7 @@ /* AVL tree implementation. - + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -27,28 +27,27 @@ #include #include -typedef int (*avltree_compare_cb) (const char *, const char *); +typedef int (*avltree_compare_cb)(const char *, const char *); -typedef struct avltree_s -{ +typedef struct avltree_s { #ifdef MEM_DEBUG - const int magic; + const int magic; #endif - struct avlnode_s *root; - const char *module; - int count; /* number of items in tree */ - int options; - const char *key; - int key_sz; - avltree_compare_cb compare; + struct avlnode_s *root; + const char *module; + int count; /* number of items in tree */ + int options; + const char *key; + int key_sz; + avltree_compare_cb compare; } avltree_t; typedef struct avlnode_s { - int balance; - const char *key; - const void *data; - struct avlnode_s *left; - struct avlnode_s *right; + int balance; + const char *key; + const void *data; + struct avlnode_s *left; + struct avlnode_s *right; } avlnode_t; /* options for avltree_init */ diff --git a/gpsbabel/axim_gpb.c b/gpsbabel/axim_gpb.c index a931ba033..4621f3873 100644 --- a/gpsbabel/axim_gpb.c +++ b/gpsbabel/axim_gpb.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include #include @@ -33,88 +33,88 @@ static gbfile *fin; static arglist_t axim_gpb_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static float le_read32_float(const void *src) { - float f; - gbint32 i; - - i = le_read32(src); - memcpy(&f, &i, 4); - - return f; + float f; + gbint32 i; + + i = le_read32(src); + memcpy(&f, &i, 4); + + return f; } static void decode_buff(const char *buff, route_head *track) { - struct tm tm; - double lat, lon, alt, dir; - float vdop, hdop, pdop, spd, Uf1; - int sats; - waypoint *wpt; - - wpt = waypt_new(); - - memset(&tm, '\0', sizeof(tm)); - - tm.tm_year = le_read16((void *) (buff + 16)); - tm.tm_mon = le_read16((void *) (buff + 18)); - tm.tm_mday = le_read16((void *) (buff + 22)); - tm.tm_hour = le_read16((void *) (buff + 24)); - tm.tm_min = le_read16((void *) (buff + 26)); - tm.tm_sec = le_read16((void *) (buff + 28)); - lat = le_read_double( (void *) (buff + 32)); - lon = le_read_double( (void *) (buff + 40)); - spd = le_read32_float((void *) (buff + 48)); - dir = le_read32_float((void *) (buff + 52)); - - alt = le_read32_float((void *) (buff + 64)); - Uf1 = le_read32_float((void *) (buff + 68)); - - hdop = le_read32_float((void *) (buff + 84)); - vdop = le_read32_float((void *) (buff + 88)); - pdop = le_read32_float((void *) (buff + 92)); - sats = le_read16((void *) (buff + 96)); - - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; + struct tm tm; + double lat, lon, alt, dir; + float vdop, hdop, pdop, spd, Uf1; + int sats; + waypoint *wpt; + + wpt = waypt_new(); + + memset(&tm, '\0', sizeof(tm)); + + tm.tm_year = le_read16((void *)(buff + 16)); + tm.tm_mon = le_read16((void *)(buff + 18)); + tm.tm_mday = le_read16((void *)(buff + 22)); + tm.tm_hour = le_read16((void *)(buff + 24)); + tm.tm_min = le_read16((void *)(buff + 26)); + tm.tm_sec = le_read16((void *)(buff + 28)); + lat = le_read_double((void *)(buff + 32)); + lon = le_read_double((void *)(buff + 40)); + spd = le_read32_float((void *)(buff + 48)); + dir = le_read32_float((void *)(buff + 52)); + + alt = le_read32_float((void *)(buff + 64)); + Uf1 = le_read32_float((void *)(buff + 68)); + + hdop = le_read32_float((void *)(buff + 84)); + vdop = le_read32_float((void *)(buff + 88)); + pdop = le_read32_float((void *)(buff + 92)); + sats = le_read16((void *)(buff + 96)); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; #if 0 - /* These values can be, but must not be right. */ - /* Further checks are needed to verify that. */ - /* (!!! reference data !!!) */ - WAYPT_SET(wpt, course, dir); - wpt->hdop = hdop; - wpt->vdop = vdop; - wpt->pdop = pdop; - wpt->sat = sats; - WAYPT_SET(wpt, speed, spd * 10); + /* These values can be, but must not be right. */ + /* Further checks are needed to verify that. */ + /* (!!! reference data !!!) */ + WAYPT_SET(wpt, course, dir); + wpt->hdop = hdop; + wpt->vdop = vdop; + wpt->pdop = pdop; + wpt->sat = sats; + WAYPT_SET(wpt, speed, spd * 10); #endif - /* We don't have a header with some magic fixed numbers or strings. */ - /* So let us check the range for some basic values */ - - is_fatal( - (tm.tm_year < 2005) || - (tm.tm_mon < 1) || (tm.tm_mon > 12) || - (tm.tm_mday < 1) || (tm.tm_mday > 31) || - (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), - MYNAME ": Invalid or unsupported file (invalid time-stamp)."); - is_fatal( - (fabs(wpt->latitude) > 90) || - (fabs(wpt->longitude) > 180), - MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); - - /* post work */ - - tm.tm_year-=1900; - tm.tm_mon--; - wpt->creation_time = mkgmtime(&tm); - - track_add_wpt(track, wpt); + /* We don't have a header with some magic fixed numbers or strings. */ + /* So let us check the range for some basic values */ + + is_fatal( + (tm.tm_year < 2005) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_hour > 23) || (tm.tm_min > 60) || (tm.tm_sec > 60), + MYNAME ": Invalid or unsupported file (invalid time-stamp)."); + is_fatal( + (fabs(wpt->latitude) > 90) || + (fabs(wpt->longitude) > 180), + MYNAME ": Invalid or unsupported file (lat or/and lon out of range)."); + + /* post work */ + + tm.tm_year-=1900; + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + + track_add_wpt(track, wpt); } /******************************************************************************* @@ -124,51 +124,49 @@ decode_buff(const char *buff, route_head *track) static void axim_gpb_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void axim_gpb_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void axim_gpb_read(void) { - char buff[RECORD_LEN]; - route_head *track = NULL; - size_t bytes; - - while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) - { - is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); - if (track == NULL) - { - track = route_head_alloc(); - track_add_head(track); - } - decode_buff(buff, track); - } + char buff[RECORD_LEN]; + route_head *track = NULL; + size_t bytes; + + while ((bytes = gbfread(buff, 1, RECORD_LEN, fin))) { + is_fatal((bytes != RECORD_LEN), MYNAME ": Invalid or unsupported file (filesize)."); + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + decode_buff(buff, track); + } } /**************************************************************************/ ff_vecs_t axim_gpb_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */, - }, - axim_gpb_rd_init, - NULL, - axim_gpb_rd_deinit, - NULL, - axim_gpb_read, - NULL, - NULL, - axim_gpb_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */, + }, + axim_gpb_rd_init, + NULL, + axim_gpb_rd_deinit, + NULL, + axim_gpb_read, + NULL, + NULL, + axim_gpb_args, + CET_CHARSET_ASCII, 0 }; /**************************************************************************/ diff --git a/gpsbabel/bcr.c b/gpsbabel/bcr.c index 6694a6b7b..859221b7e 100644 --- a/gpsbabel/bcr.c +++ b/gpsbabel/bcr.c @@ -39,15 +39,15 @@ #define MYNAME "bcr" #undef BCR_DEBUG - + #define R_EARTH 6371000 /* radius of our big blue ball */ #define BCR_DEF_ICON "Standort" #define BCR_DEF_MPS_ICON "Waypoint" #define BCR_UNKNOWN (double) 999999999 -/* +/* 6371014 would be a better value when converting to f.e. to mapsoure, - but this seems to be used by Map&Guide when exporting to XML. + but this seems to be used by Map&Guide when exporting to XML. */ static gbfile *fout; @@ -65,135 +65,148 @@ static char *prefer_shortnames_opt; static arglist_t bcr_args[] = { - {"index", &rtenum_opt, "Index of route to write (if more than one in source)", - NULL, ARGTYPE_INT, "1", NULL }, - {"name", &rtename_opt, "New name for the route", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", - ARGTYPE_FLOAT, ARG_NOMINMAX }, - {"prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "index", &rtenum_opt, "Index of route to write (if more than one in source)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "name", &rtename_opt, "New name for the route", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "radius", &radius_opt, "Radius of our big earth (default 6371000 meters)", "6371000", + ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "prefer_shortnames", &prefer_shortnames_opt, "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct { - const char *bcr_name; - const char *mps_name; - const char *symbol_DE; - int warned; + const char *bcr_name; + const char *mps_name; + const char *symbol_DE; + int warned; } bcr_icon_mapping_t; static bcr_icon_mapping_t bcr_icon_mapping[] = { - { BCR_DEF_ICON, BCR_DEF_MPS_ICON, BCR_DEF_ICON }, - { "", BCR_DEF_MPS_ICON, "Eigene Adressen" }, - { "AdrMon alpen", "Summit", "Pass-Strassen" }, - { "AdrMon bauern", NULL, "Bauern- und Biohoefe" }, - { "AdrMon cmpngs", "Campground", "Campingplaetzte" }, - { "AdrMon p_aeu", "Scenic Area", "Sehenswertes" }, - { "AdrMon p_beu", "Gas Station", "Tanken" }, - { "AdrMon p_deu", "Parking Area", "Parken" }, - { "AdrMon p_feu", "Restaurant", "Gastro" }, - { "AdrMon p_geu", "Museum", "Freizeit" }, - { "AdrMon p_heu", "Gas Station", "Tankstellen" }, - { "AdrMon p_keu", NULL, "Faehrverbindungen" }, - { "AdrMon p_leu", NULL, "Grenzuebergaenge" }, - { "AdrMon p_teu", NULL, "Wein- und Sektgueter" }, - { "AdrMon RUINEN", "Ghost Town", "Burgen und Schloesser" }, - { "AdrMon NFHAUS", "Residence", "Naturfreundehaeuser" }, - { "AdrMon racing", "Bike Trail", "Rennstrecken" }, - { "AdrMon TNKRST", "Bar", "Tankraststaetten" }, - { "AdrMon tpclub", "Contact, Biker", "Motorrad-Clubs" }, - { "AdrMon tpequ", NULL, "Motorrad-Equipment" }, - { "AdrMon tphot", "Hotel", "Motorrad-Hotels" }, - { "AdrMon tpmh", NULL, "Motorradhaendler" }, - { "AdrMon tpss", "Restricted Area", "Sperrungen" }, - { "AdrMon tpsw", "Scenic Area", "Sehenswertes" }, - { "AdrMon tptref", NULL, "Treffpunkte" }, - { "AdrMon VORTE", "Information", "Ortsinformationen" }, - { "AdrMon WEBCAM", NULL, "WebCam-Standorte" }, - { "AdrMon youthh", NULL, "Jugendherbergen" }, - { "Town", "City (Small)", "Orte" }, - { NULL, NULL, NULL, 0 } + { BCR_DEF_ICON, BCR_DEF_MPS_ICON, BCR_DEF_ICON }, + { "", BCR_DEF_MPS_ICON, "Eigene Adressen" }, + { "AdrMon alpen", "Summit", "Pass-Strassen" }, + { "AdrMon bauern", NULL, "Bauern- und Biohoefe" }, + { "AdrMon cmpngs", "Campground", "Campingplaetzte" }, + { "AdrMon p_aeu", "Scenic Area", "Sehenswertes" }, + { "AdrMon p_beu", "Gas Station", "Tanken" }, + { "AdrMon p_deu", "Parking Area", "Parken" }, + { "AdrMon p_feu", "Restaurant", "Gastro" }, + { "AdrMon p_geu", "Museum", "Freizeit" }, + { "AdrMon p_heu", "Gas Station", "Tankstellen" }, + { "AdrMon p_keu", NULL, "Faehrverbindungen" }, + { "AdrMon p_leu", NULL, "Grenzuebergaenge" }, + { "AdrMon p_teu", NULL, "Wein- und Sektgueter" }, + { "AdrMon RUINEN", "Ghost Town", "Burgen und Schloesser" }, + { "AdrMon NFHAUS", "Residence", "Naturfreundehaeuser" }, + { "AdrMon racing", "Bike Trail", "Rennstrecken" }, + { "AdrMon TNKRST", "Bar", "Tankraststaetten" }, + { "AdrMon tpclub", "Contact, Biker", "Motorrad-Clubs" }, + { "AdrMon tpequ", NULL, "Motorrad-Equipment" }, + { "AdrMon tphot", "Hotel", "Motorrad-Hotels" }, + { "AdrMon tpmh", NULL, "Motorradhaendler" }, + { "AdrMon tpss", "Restricted Area", "Sperrungen" }, + { "AdrMon tpsw", "Scenic Area", "Sehenswertes" }, + { "AdrMon tptref", NULL, "Treffpunkte" }, + { "AdrMon VORTE", "Information", "Ortsinformationen" }, + { "AdrMon WEBCAM", NULL, "WebCam-Standorte" }, + { "AdrMon youthh", NULL, "Jugendherbergen" }, + { "Town", "City (Small)", "Orte" }, + { NULL, NULL, NULL, 0 } }; static void bcr_handle_icon_str(const char *str, waypoint *wpt) { - bcr_icon_mapping_t *m; - - wpt->icon_descr = BCR_DEF_MPS_ICON; - - for (m = bcr_icon_mapping; (m->bcr_name); m++) { - if (case_ignore_strcmp(str, m->bcr_name) == 0) { - int nr; - - if (m->symbol_DE == NULL) { - if (! m->warned) { - m->warned = 1; - warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); - } - return; - } - wpt->description = xstrdup(m->symbol_DE); - if (m->mps_name != NULL) { - nr = gt_find_icon_number_from_desc(m->mps_name, MAPSOURCE); - wpt->icon_descr = gt_find_desc_from_icon_number(nr, MAPSOURCE, NULL); - } - return; - } - } + bcr_icon_mapping_t *m; + + wpt->icon_descr = BCR_DEF_MPS_ICON; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (case_ignore_strcmp(str, m->bcr_name) == 0) { + int nr; + + if (m->symbol_DE == NULL) { + if (! m->warned) { + m->warned = 1; + warning(MYNAME ": Unknown icon \"%s\" found. Please report.\n", str); + } + return; + } + wpt->description = xstrdup(m->symbol_DE); + if (m->mps_name != NULL) { + nr = gt_find_icon_number_from_desc(m->mps_name, MAPSOURCE); + wpt->icon_descr = gt_find_desc_from_icon_number(nr, MAPSOURCE, NULL); + } + return; + } + } } static const char * get_bcr_icon_from_icon_descr(const char *icon_descr) { - const char *result = BCR_DEF_ICON; - - if (icon_descr) { - bcr_icon_mapping_t *m; - - for (m = bcr_icon_mapping; (m->bcr_name); m++) { - if (! m->mps_name) continue; - if (case_ignore_strcmp(icon_descr, m->mps_name) == 0) { - result = m->bcr_name; - break; - } - } - } - return result; + const char *result = BCR_DEF_ICON; + + if (icon_descr) { + bcr_icon_mapping_t *m; + + for (m = bcr_icon_mapping; (m->bcr_name); m++) { + if (! m->mps_name) { + continue; + } + if (case_ignore_strcmp(icon_descr, m->mps_name) == 0) { + result = m->bcr_name; + break; + } + } + } + return result; } static void bcr_init_radius(void) { - if (radius_opt != NULL) /* preinitialize the earth radius */ - { - radius = atof(radius_opt); - if (radius <= 0) - fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); - } - else - radius = (double)R_EARTH; - - if (global_opts.verbose_status > 0) - printf(MYNAME ": We calculate with radius %f meters.\n", radius); + if (radius_opt != NULL) { /* preinitialize the earth radius */ + radius = atof(radius_opt); + if (radius <= 0) { + fatal(MYNAME ": Sorry, the radius should be greater than zero!\n"); + } + } else { + radius = (double)R_EARTH; + } + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": We calculate with radius %f meters.\n", radius); + } } static void bcr_rd_init(const char *fname) { - filename = xstrdup(fname); - ini = inifile_init(fname, MYNAME); - if (ini->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - bcr_init_radius(); + filename = xstrdup(fname); + ini = inifile_init(fname, MYNAME); + if (ini->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + bcr_init_radius(); } static void bcr_rd_deinit(void) { - inifile_done(ini); - xfree(filename); + inifile_done(ini); + xfree(filename); } /* ------------------------------------------------------------*/ @@ -201,38 +214,43 @@ bcr_rd_deinit(void) static void bcr_create_waypts_from_route(route_head *route) { - waypoint *wpt; - queue *elem, *tmp; - - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - wpt = waypt_dupe((waypoint *) elem); - waypt_add(wpt); - } + waypoint *wpt; + queue *elem, *tmp; + + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + wpt = waypt_dupe((waypoint *) elem); + waypt_add(wpt); + } } static void bcr_wgs84_to_mercator(const double lat, const double lon, int *north, int *east) { - double N, E; - - N = log(tan(lat * M_PI / 360 + M_PI / 4)) * radius; - E = lon * radius * M_PI / (double)180; - - if (lat > 0) N += 0.500000000001; /* we go from double to integer */ - else N -= 0.500000000001; /* it's time to round a little bit */ - if (lon > 0) E += 0.500000000001; - else E -= 0.500000000001; - - *north = N; - *east = E; + double N, E; + + N = log(tan(lat * M_PI / 360 + M_PI / 4)) * radius; + E = lon * radius * M_PI / (double)180; + + if (lat > 0) { + N += 0.500000000001; /* we go from double to integer */ + } else { + N -= 0.500000000001; /* it's time to round a little bit */ + } + if (lon > 0) { + E += 0.500000000001; + } else { + E -= 0.500000000001; + } + + *north = N; + *east = E; } void -bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) +bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) { - *lat = 2 * (atan(exp(north / radius)) - M_PI / 4) / M_PI * (double)180; - *lon = (double)east * (double)180 / (radius * M_PI); + *lat = 2 * (atan(exp(north / radius)) - M_PI / 4) / M_PI * (double)180; + *lon = (double)east * (double)180 / (radius * M_PI); } /* ------------------------------------------------------------- */ @@ -240,71 +258,82 @@ bcr_mercator_to_wgs84(const int north, const int east, double *lat, double *lon) static void bcr_data_read(void) { - int index; - char *str; - route_head *route; - - route = route_head_alloc(); - - if ((str = inifile_readstr(ini, "client", "routename"))) - route->rte_name = xstrdup(str); - - route_add_head(route); - - for (index = 1; index > 0; index ++) { - - char station[32]; - char *str; - int mlat, mlon; /* mercator data */ - waypoint *wpt; - - snprintf(station, sizeof(station), "STATION%d", index); - if (NULL == (str = inifile_readstr(ini, "coordinates", station))) break; - - if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) - fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); - - wpt = waypt_new(); - - wpt->shortname = xstrdup(station); - bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); - - if (NULL != (str = inifile_readstr(ini, "client", station))) - { - char *cx; - - cx = strchr(str, ','); - if (cx == NULL) - fatal(MYNAME ": structure error at %s (Client)!\n", station); - *cx++ = '\0'; - bcr_handle_icon_str(str, wpt); - } - - if (NULL != (str = inifile_readstr(ini, "description", station))) { - char *c; - - c = strchr(str, ','); - if (c != NULL) *c = '\0'; - if (*str) wpt->notes = xstrdup(str); - if ((str = c)) { - str++; - c = strchr(str, ','); - if (c != NULL) *c = '\0'; - if (*str) { - xfree(wpt->shortname); - wpt->shortname = xstrdup(str); - } - } - } - - route_add_wpt(route, wpt); - } - - /* remove empty route */ - if (route->rte_waypt_ct == 0) - route_del_head(route); - else - bcr_create_waypts_from_route(route); + int index; + char *str; + route_head *route; + + route = route_head_alloc(); + + if ((str = inifile_readstr(ini, "client", "routename"))) { + route->rte_name = xstrdup(str); + } + + route_add_head(route); + + for (index = 1; index > 0; index ++) { + + char station[32]; + char *str; + int mlat, mlon; /* mercator data */ + waypoint *wpt; + + snprintf(station, sizeof(station), "STATION%d", index); + if (NULL == (str = inifile_readstr(ini, "coordinates", station))) { + break; + } + + if (2 != sscanf(str, "%d,%d", &mlon, &mlat)) { + fatal(MYNAME ": structure error at %s (Coordinates)!\n", station); + } + + wpt = waypt_new(); + + wpt->shortname = xstrdup(station); + bcr_mercator_to_wgs84(mlat, mlon, &wpt->latitude, &wpt->longitude); + + if (NULL != (str = inifile_readstr(ini, "client", station))) { + char *cx; + + cx = strchr(str, ','); + if (cx == NULL) { + fatal(MYNAME ": structure error at %s (Client)!\n", station); + } + *cx++ = '\0'; + bcr_handle_icon_str(str, wpt); + } + + if (NULL != (str = inifile_readstr(ini, "description", station))) { + char *c; + + c = strchr(str, ','); + if (c != NULL) { + *c = '\0'; + } + if (*str) { + wpt->notes = xstrdup(str); + } + if ((str = c)) { + str++; + c = strchr(str, ','); + if (c != NULL) { + *c = '\0'; + } + if (*str) { + xfree(wpt->shortname); + wpt->shortname = xstrdup(str); + } + } + } + + route_add_wpt(route, wpt); + } + + /* remove empty route */ + if (route->rte_waypt_ct == 0) { + route_del_head(route); + } else { + bcr_create_waypts_from_route(route); + } } /* %%% bcr write support %%% ----------------------------------- */ @@ -312,19 +341,19 @@ bcr_data_read(void) static void bcr_wr_init(const char *fname) { - filename = xstrdup(fname); - fout = gbfopen(fname, "wb", MYNAME); - bcr_init_radius(); + filename = xstrdup(fname); + fout = gbfopen(fname, "wb", MYNAME); + bcr_init_radius(); } static void bcr_wr_deinit(void) { - gbfclose(fout); - xfree(filename); + gbfclose(fout); + xfree(filename); } -static void +static void bcr_route_trailer(const route_head *rte) { } @@ -336,151 +365,170 @@ bcr_write_wpt(const waypoint *wpt) void bcr_write_line(gbfile *fout, const char *key, int *index, const char *value) { - if (value == NULL) /* this is mostly used in the world of windows */ - { /* so we respectfully add a CR/LF on each line */ - gbfprintf(fout, "%s\r\n", key); - } - else - { - char *tmp; - - tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); - if (index != NULL) - gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); - else - gbfprintf(fout, "%s=%s\r\n", key, tmp); - xfree(tmp); - } + if (value == NULL) { /* this is mostly used in the world of windows */ + /* so we respectfully add a CR/LF on each line */ + gbfprintf(fout, "%s\r\n", key); + } else { + char *tmp; + + tmp = (value != NULL) ? xstrdup(value) : xstrdup(""); + if (index != NULL) { + gbfprintf(fout, "%s%d=%s\r\n", key, *index, tmp); + } else { + gbfprintf(fout, "%s=%s\r\n", key, tmp); + } + xfree(tmp); + } } -static void +static void bcr_route_header(const route_head *route) { - queue *elem, *tmp; - waypoint *wpt; - char *sout; - int i, north, east, nmin, nmax, emin, emax; - - curr_rte_num++; - if (curr_rte_num != target_rte_num) return; - - bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ - bcr_write_line(fout, "REQUEST", NULL, "TRUE"); - - sout = route->rte_name; - if (rtename_opt != 0) sout = rtename_opt; - if (sout != NULL) - bcr_write_line(fout, "ROUTENAME", NULL, sout); - else - bcr_write_line(fout, "ROUTENAME", NULL, "Route"); - - bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "0"); - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - const char *icon; - waypoint *wpt = (waypoint *) elem; - - i++; - - icon = get_bcr_icon_from_icon_descr(wpt->icon_descr); - - xasprintf(&sout, "%s,%.f", icon, BCR_UNKNOWN); - bcr_write_line(fout, "STATION", &i, sout); - xfree(sout); - } - - bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ - - nmin = emin = (1<<30); - emax = nmax = -nmin; - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - i++; - wpt = (waypoint *) elem; - - bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); - - if (north > nmax) nmax = north; - if (east > emax) emax = east; - if (north < nmin) nmin = north; - if (east < emin) emin = east; - - xasprintf(&sout, "%d,%d", east, north); - bcr_write_line(fout, "STATION", &i, sout); - xfree(sout); - } - - bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ - - i = 0; - QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) - { - char *s1, *s2, *sout; - - i++; - wpt = (waypoint *) elem; - s1 = wpt->notes; - if (s1 == NULL) s1 = wpt->description; - - if (prefer_shortnames_opt || (s1 == NULL) || (*s1 == '\0')) { - s2 = s1; - s1 = wpt->shortname; - } - else s2 = wpt->shortname; - - if (s1 == NULL) s1 = xstrdup(""); - else s1 = csv_stringclean(s1, ",\t\r\n"); - if (s2 == NULL) s2 = xstrdup(""); - else s2 = csv_stringclean(s2, ",\t\r\n"); - - if (*s2) - xasprintf(&sout, "%s,%s,@,0", s1, s2); - else - xasprintf(&sout, "%s,%s,@,0", s1, s1); - bcr_write_line(fout, "STATION", &i, sout); - - xfree(s1); - xfree(s2); - xfree(sout); - } - - bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ - - xasprintf(&sout, "%d,%d,%d,%d", emin, nmax, emax, nmin); - bcr_write_line(fout, "ROUTERECT", NULL, sout); - xfree(sout); - + queue *elem, *tmp; + waypoint *wpt; + char *sout; + int i, north, east, nmin, nmax, emin, emax; + + curr_rte_num++; + if (curr_rte_num != target_rte_num) { + return; + } + + bcr_write_line(fout, "[CLIENT]", NULL, NULL); /* client section */ + bcr_write_line(fout, "REQUEST", NULL, "TRUE"); + + sout = route->rte_name; + if (rtename_opt != 0) { + sout = rtename_opt; + } + if (sout != NULL) { + bcr_write_line(fout, "ROUTENAME", NULL, sout); + } else { + bcr_write_line(fout, "ROUTENAME", NULL, "Route"); + } + + bcr_write_line(fout, "DESCRIPTIONLINES", NULL, "0"); + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + const char *icon; + waypoint *wpt = (waypoint *) elem; + + i++; + + icon = get_bcr_icon_from_icon_descr(wpt->icon_descr); + + xasprintf(&sout, "%s,%.f", icon, BCR_UNKNOWN); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[COORDINATES]", NULL, NULL); /* coords section */ + + nmin = emin = (1<<30); + emax = nmax = -nmin; + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + i++; + wpt = (waypoint *) elem; + + bcr_wgs84_to_mercator(wpt->latitude, wpt->longitude, &north, &east); + + if (north > nmax) { + nmax = north; + } + if (east > emax) { + emax = east; + } + if (north < nmin) { + nmin = north; + } + if (east < emin) { + emin = east; + } + + xasprintf(&sout, "%d,%d", east, north); + bcr_write_line(fout, "STATION", &i, sout); + xfree(sout); + } + + bcr_write_line(fout, "[DESCRIPTION]", NULL, NULL); /* descr. section */ + + i = 0; + QUEUE_FOR_EACH(&route->waypoint_list, elem, tmp) { + char *s1, *s2, *sout; + + i++; + wpt = (waypoint *) elem; + s1 = wpt->notes; + if (s1 == NULL) { + s1 = wpt->description; + } + + if (prefer_shortnames_opt || (s1 == NULL) || (*s1 == '\0')) { + s2 = s1; + s1 = wpt->shortname; + } else { + s2 = wpt->shortname; + } + + if (s1 == NULL) { + s1 = xstrdup(""); + } else { + s1 = csv_stringclean(s1, ",\t\r\n"); + } + if (s2 == NULL) { + s2 = xstrdup(""); + } else { + s2 = csv_stringclean(s2, ",\t\r\n"); + } + + if (*s2) { + xasprintf(&sout, "%s,%s,@,0", s1, s2); + } else { + xasprintf(&sout, "%s,%s,@,0", s1, s1); + } + bcr_write_line(fout, "STATION", &i, sout); + + xfree(s1); + xfree(s2); + xfree(sout); + } + + bcr_write_line(fout, "[ROUTE]", NULL, NULL); /* route section */ + + xasprintf(&sout, "%d,%d,%d,%d", emin, nmax, emax, nmin); + bcr_write_line(fout, "ROUTERECT", NULL, sout); + xfree(sout); + } static void bcr_data_write(void) { - target_rte_num = 1; - - if (rtenum_opt != NULL) { - target_rte_num = atoi(rtenum_opt); - if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) - fatal(MYNAME ": invalid route number %d (1..%d))!\n", - target_rte_num, route_count()); - } - curr_rte_num = 0; - route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); + target_rte_num = 1; + + if (rtenum_opt != NULL) { + target_rte_num = atoi(rtenum_opt); + if (((unsigned)target_rte_num > route_count()) || (target_rte_num < 1)) + fatal(MYNAME ": invalid route number %d (1..%d))!\n", + target_rte_num, route_count()); + } + curr_rte_num = 0; + route_disp_all(bcr_route_header, bcr_route_trailer, bcr_write_wpt); } ff_vecs_t bcr_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, - bcr_rd_init, - bcr_wr_init, - bcr_rd_deinit, - bcr_wr_deinit, - bcr_data_read, - bcr_data_write, - NULL, - bcr_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, + bcr_rd_init, + bcr_wr_init, + bcr_rd_deinit, + bcr_wr_deinit, + bcr_data_read, + bcr_data_write, + NULL, + bcr_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/brauniger_iq.c b/gpsbabel/brauniger_iq.c index eef12030d..dbed7c59a 100644 --- a/gpsbabel/brauniger_iq.c +++ b/gpsbabel/brauniger_iq.c @@ -1,21 +1,21 @@ /* * Serial download of barograph data from a Brauniger IQ Variometer. - * + * * Copyright (C) 2004 Chris Jones - * - * This program is free software; you can redistribute it and/or modify it + * + * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111 USA + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA */ #include "defs.h" @@ -28,241 +28,245 @@ static void *serial_handle; #define PRESTRKNAME "PRESALTTRK" static enum { - st_sync, - st_fl_num, - st_data_len, - st_ser_num, - st_pilot_name, - st_start_date, - st_start_year, - st_max_alt_1, - st_max_alt_2, - st_max_climb, - st_flight_dur, - st_log_ival, - st_start_time, - st_end_time, - st_sample_alt, - st_sample_spd, - num_states + st_sync, + st_fl_num, + st_data_len, + st_ser_num, + st_pilot_name, + st_start_date, + st_start_year, + st_max_alt_1, + st_max_alt_2, + st_max_climb, + st_flight_dur, + st_log_ival, + st_start_time, + st_end_time, + st_sample_alt, + st_sample_spd, + num_states } state; static const int reqd_bytes[num_states] = { 6, 1, 2, 2, 25, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1 }; -static void rd_init(const char *fname) { - if (serial_handle = gbser_init(fname), NULL == serial_handle) { - fatal(MYNAME ": Can't open port '%s'\n", fname); - } - if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { - fatal(MYNAME ": Can't configure port '%s'\n", fname); - } +static void rd_init(const char *fname) +{ + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_port(serial_handle, 9600, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } } -static void rd_deinit(void) { - gbser_deinit(serial_handle); - serial_handle = NULL; +static void rd_deinit(void) +{ + gbser_deinit(serial_handle); + serial_handle = NULL; } /** * Process a data record. * @return zero when all expected data has been received */ -static int process_data(const unsigned char *data) { - static int remaining = 100; - static struct tm tm; - static time_t start, creation; - static route_head *track; - static unsigned char interval; - time_t finish; - waypoint *wpt = NULL; - int i; - - if (global_opts.debug_level >= 3) { - for (i = 0; i < reqd_bytes[state]; i++) { - printf("%.2x ", data[i]); - } - puts(""); +static int process_data(const unsigned char *data) +{ + static int remaining = 100; + static struct tm tm; + static time_t start, creation; + static route_head *track; + static unsigned char interval; + time_t finish; + waypoint *wpt = NULL; + int i; + + if (global_opts.debug_level >= 3) { + for (i = 0; i < reqd_bytes[state]; i++) { + printf("%.2x ", data[i]); } + puts(""); + } + + remaining -= reqd_bytes[state]; + switch (state) { + case st_sync: + if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { + fatal(MYNAME ": Could not synchronise\n"); + } + break; - remaining -= reqd_bytes[state]; - switch (state) { - case st_sync: - if (memcmp(data, "\x30\x31\x32\x33\x34\x35", 6) != 0) { - fatal(MYNAME ": Could not synchronise\n"); - } - break; - - case st_fl_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Flight Number: %d\n", data[0]); - } - break; - - case st_data_len: - remaining = (data[0] << 8) + data[1] - 2; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Data Length: %d\n", remaining); - } - break; - - case st_ser_num: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); - } - break; - - case st_pilot_name: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Pilot Name: %.25s\n", data); - } - break; - - case st_start_date: - i = (data[0] << 8) + data[1]; - tm.tm_mday = i / 100; - tm.tm_mon = (i % 100) - 1; - break; - - case st_start_year: - tm.tm_year = ((data[0] << 8) + data[1]) - 1900; - break; - - case st_max_alt_1: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); - } - break; - - case st_max_alt_2: - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); - } - break; - - case st_max_climb: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); - } - break; - - case st_flight_dur: - if (global_opts.debug_level >= 1) { - i = (data[0] << 8) + data[1]; - printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); - } - break; - - case st_log_ival: - interval = data[0]; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Logging Interval: %ds\n", interval); - } - break; - - case st_start_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - tm.tm_sec = 0; - creation = start = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": Start Time: %s", ctime(&start)); - } - break; - - case st_end_time: - i = (data[0] << 8) + data[1]; - tm.tm_hour = i / 100; - tm.tm_min = (i % 100) - 1; - finish = mktime(&tm); - if (global_opts.debug_level >= 1) { - printf(MYNAME ": End Time: %s", ctime(&finish)); - } - if (remaining) { - track = route_head_alloc(); - track->rte_name = xstrdup(PRESTRKNAME); - track->rte_desc = xstrdup("Brauniger-IQ Barograph"); - track_add_head(track); - } else { - warning(MYNAME ": No barograph recorded for this flight\n"); - } - break; - - case st_sample_alt: - wpt = waypt_new(); - wpt->latitude = wpt->longitude = 0.0; - wpt->creation_time = creation; - creation += interval; - wpt->altitude = (data[0] << 8) + data[1]; - track_add_wpt(track, wpt); - if (global_opts.debug_level >= 2) { - printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); - } - break; - - case st_sample_spd: - if (global_opts.debug_level >= 2) { - printf("Airspeed=%dkmh\n", data[0]); - } - state = st_sample_alt; - return remaining; - - default: - fatal(MYNAME ": Bad internal state\n"); + case st_fl_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Flight Number: %d\n", data[0]); } - state++; - return remaining; -} + break; + + case st_data_len: + remaining = (data[0] << 8) + data[1] - 2; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Data Length: %d\n", remaining); + } + break; + + case st_ser_num: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Serial Number: %d\n", (data[0] << 8) + data[1]); + } + break; + + case st_pilot_name: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Pilot Name: %.25s\n", data); + } + break; + + case st_start_date: + i = (data[0] << 8) + data[1]; + tm.tm_mday = i / 100; + tm.tm_mon = (i % 100) - 1; + break; + + case st_start_year: + tm.tm_year = ((data[0] << 8) + data[1]) - 1900; + break; + + case st_max_alt_1: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 1: %dm\n", (data[0] << 8) + data[1]); + } + break; + + case st_max_alt_2: + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Max Altitude 2: %dm\n", (data[0] << 8) + data[1]); + } + break; + + case st_max_climb: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Max climb: %d.%dm/s\n", i / 10, i % 10); + } + break; -static void data_read(void) { - unsigned char ibuf[25]; - int rd_cnt; + case st_flight_dur: + if (global_opts.debug_level >= 1) { + i = (data[0] << 8) + data[1]; + printf(MYNAME ": Flight Time: %d:%d\n", i / 100, i % 100); + } + break; + + case st_log_ival: + interval = data[0]; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Logging Interval: %ds\n", interval); + } + break; + + case st_start_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + tm.tm_sec = 0; + creation = start = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": Start Time: %s", ctime(&start)); + } + break; + + case st_end_time: + i = (data[0] << 8) + data[1]; + tm.tm_hour = i / 100; + tm.tm_min = (i % 100) - 1; + finish = mktime(&tm); + if (global_opts.debug_level >= 1) { + printf(MYNAME ": End Time: %s", ctime(&finish)); + } + if (remaining) { + track = route_head_alloc(); + track->rte_name = xstrdup(PRESTRKNAME); + track->rte_desc = xstrdup("Brauniger-IQ Barograph"); + track_add_head(track); + } else { + warning(MYNAME ": No barograph recorded for this flight\n"); + } + break; + + case st_sample_alt: + wpt = waypt_new(); + wpt->latitude = wpt->longitude = 0.0; + wpt->creation_time = creation; + creation += interval; + wpt->altitude = (data[0] << 8) + data[1]; + track_add_wpt(track, wpt); + if (global_opts.debug_level >= 2) { + printf(MYNAME ": remaining=%d, Altitude=%fm, ", remaining, wpt->altitude); + } + break; - if (global_opts.debug_level >= 0) { - puts(MYNAME ": Select recorded flight in memo mode."); - puts(MYNAME ": Press Memo button for two seconds..."); + case st_sample_spd: + if (global_opts.debug_level >= 2) { + printf("Airspeed=%dkmh\n", data[0]); } + state = st_sample_alt; + return remaining; - // Wait until something arrives - if (global_opts.debug_level >= 0) { - puts(MYNAME ": Downloading flight..."); + default: + fatal(MYNAME ": Bad internal state\n"); + } + state++; + return remaining; +} + +static void data_read(void) +{ + unsigned char ibuf[25]; + int rd_cnt; + + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Select recorded flight in memo mode."); + puts(MYNAME ": Press Memo button for two seconds..."); + } + + // Wait until something arrives + if (global_opts.debug_level >= 0) { + puts(MYNAME ": Downloading flight..."); + } + + // Read data until there is none left to read + state = st_sync; + for (;;) { + /* wait up to 5 seconds for more data */ + rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); + if (rd_cnt < 0) { + fatal(MYNAME ": Serial error\n"); + } else if (rd_cnt < reqd_bytes[state]) { + fatal(MYNAME ": Incomplete download\n"); } - // Read data until there is none left to read - state = st_sync; - for (;;) { - /* wait up to 5 seconds for more data */ - rd_cnt = gbser_read_wait(serial_handle, ibuf, reqd_bytes[state], 5000); - if (rd_cnt < 0) { - fatal(MYNAME ": Serial error\n"); - } else if (rd_cnt < reqd_bytes[state]) { - fatal(MYNAME ": Incomplete download\n"); - } - - if (!process_data(ibuf)) { - if (global_opts.debug_level >= 0) { - puts(MYNAME " ...Finished"); - } - return; - } - } + if (!process_data(ibuf)) { + if (global_opts.debug_level >= 0) { + puts(MYNAME " ...Finished"); + } + return; + } + } } static arglist_t brauniger_iq_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t brauniger_iq_vecs = { - ff_type_serial, - { ff_cap_none, ff_cap_read, ff_cap_none}, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - brauniger_iq_args, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_serial, + { ff_cap_none, ff_cap_read, ff_cap_none}, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + brauniger_iq_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/bushnell.c b/gpsbabel/bushnell.c index a26d9e595..f73aadd6f 100644 --- a/gpsbabel/bushnell.c +++ b/gpsbabel/bushnell.c @@ -25,14 +25,14 @@ static gbfile *file_in; static char *ofname; -static short_handle mkshort_handle = NULL; +static short_handle mkshort_handle = NULL; static arglist_t bushnell_args[] = { ARG_TERMINATOR }; -// Apparently, the icons are undocumented, so we made up names, +// Apparently, the icons are undocumented, so we made up names, // preferring them to be consistent with other brands where possiblde. typedef struct { @@ -73,10 +73,10 @@ icon_mapping_t bushnell_icons[] = { { 0x19, "Blue Diamond Checkmark" }, // undocumented. { 0x1a, "Camera" }, - { 0x1b, "Restaraunt" }, // "Fork/Knife (meal place?)" - { 0x1c, "Restroom" }, // (man & Woman icon)" - { 0x1d, "RV Park" }, // "Bus or RV (RV campground?)" - { 0x1e, "Potable Water" }, // (faucet/glass or bucket)" + { 0x1b, "Restaraunt" }, // "Fork/Knife (meal place?)" + { 0x1c, "Restroom" }, // (man & Woman icon)" + { 0x1d, "RV Park" }, // "Bus or RV (RV campground?)" + { 0x1e, "Potable Water" }, // (faucet/glass or bucket)" { 0x1f, "Fishing" }, { 0x20, "Anchor in square" }, { 0x21, "Boat ramp/launch" }, @@ -87,17 +87,17 @@ icon_mapping_t bushnell_icons[] = { { 0x26, "Mouantin/Mountain Peak" }, { 0x27, "Turkey Tracks/animal tracks" }, - { 0x28, "Bank" }, // "Cash (ATM MAybe)" - { 0x29, "Bar" }, // "Martini undocumented" + { 0x28, "Bank" }, // "Cash (ATM MAybe)" + { 0x29, "Bar" }, // "Martini undocumented" { 0x2a, "Lighthouse" }, { 0x2b, "Tent" }, { 0x2c, "Cresent Wrench or can opener" }, - { 0x2d, "School" }, //? White Building with tunnel looking door and flag on top." - { 0x2f, "Information" }, // "i (info/internet maybe?)" - { 0x30, "Picnic" }, //"Picnic table & Tree, maybe forest picnic or day use area?" + { 0x2d, "School" }, //? White Building with tunnel looking door and flag on top." + { 0x2f, "Information" }, // "i (info/internet maybe?)" + { 0x30, "Picnic" }, //"Picnic table & Tree, maybe forest picnic or day use area?" { 0x31, "Phone" }, { 0x32, "Letter/Envelope" }, { 0x33, "Forest/Park Ranger" }, @@ -113,61 +113,70 @@ icon_mapping_t bushnell_icons[] = { { 0x3a, "Swimmer/swimming" }, { 0x3b, "Officer? Looks like man leaned over holding blue cube..." }, - { 0x3c, "Parking" }, //"Car Parked" + { 0x3c, "Parking" }, //"Car Parked" { 0x3d, "Airport" }, - { 0x3e, "Bus Terminal" }, // (guess) Loks like Bus under canopy." + { 0x3e, "Bus Terminal" }, // (guess) Loks like Bus under canopy." { 0x3f, "Red Cross" }, { 0x40, "Red Buidling with flag, Fire Station maybe." }, { 0x41, "Bus" }, - { 0x42, "Officer" }, // "see 3b: duplicate" + { 0x42, "Officer" }, // "see 3b: duplicate" { 0x43, "Railroad" }, { 0x44, "Auto Ferry" }, {-1, NULL} }; static unsigned int -bushnell_get_icon_from_name(const char *name) { +bushnell_get_icon_from_name(const char *name) +{ icon_mapping_t *t; for (t = bushnell_icons; t->icon > 0; t++) { - if (0 == case_ignore_strcmp(name, t->icon)) - return t->symbol; + if (0 == case_ignore_strcmp(name, t->icon)) { + return t->symbol; + } } return 0; } static const char * -bushnell_get_name_from_symbol(signed int s) { +bushnell_get_name_from_symbol(signed int s) +{ icon_mapping_t *t; for (t = bushnell_icons; t->icon > 0; t++) { - if (s == t->symbol) - return t->icon; + if (s == t->symbol) { + return t->icon; + } } return "Waypoint"; } static void -rd_init(const char *fname) { +rd_init(const char *fname) +{ file_in = gbfopen_le(fname, "rb", MYNAME); } static void -rd_deinit(void) { +rd_deinit(void) +{ gbfclose(file_in); } static void -wr_init(const char *fname) { +wr_init(const char *fname) +{ char *dot, *slash; static char valid_chars [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" - ".-/\\~@#$%^&*()_+=<>" - "abcdefghijklmnopqrstuvwxyz"; + ".-/\\~@#$%^&*()_+=<>" + "abcdefghijklmnopqrstuvwxyz"; ofname = xstrdup(fname); // If user provided an extension in the pathname, whack it. dot = strrchr(ofname, '.'); slash = strrchr(ofname, GB_PATHSEP); - if (dot > slash) *dot = 0; + if (dot > slash) { + *dot = 0; + } mkshort_handle = mkshort_new_handle(); setshort_length(mkshort_handle, 19); @@ -175,7 +184,8 @@ wr_init(const char *fname) { } static void -wr_deinit(void) { +wr_deinit(void) +{ mkshort_del_handle(&mkshort_handle); xfree(ofname); } @@ -184,7 +194,8 @@ wr_deinit(void) { * Each file contains a single waypoint. */ static void -bushnell_read(void) { +bushnell_read(void) +{ gbint32 lat_tmp,lon_tmp; unsigned int proximity; unsigned int icon; @@ -208,7 +219,8 @@ bushnell_read(void) { } static void -bushnell_write_one(const waypoint *wpt) { +bushnell_write_one(const waypoint *wpt) +{ char tbuf[20]; // 19 text bytes + null terminator. char padding[2] = {0, 0}; gbfile *file_out; @@ -220,7 +232,7 @@ bushnell_write_one(const waypoint *wpt) { file_out = gbfopen_le(fname, "wb", MYNAME); gbfputint32(wpt->latitude * 10000000, file_out); gbfputint32(wpt->longitude * 10000000, file_out); - gbfputc(bushnell_get_icon_from_name(wpt->icon_descr ? wpt->icon_descr : + gbfputc(bushnell_get_icon_from_name(wpt->icon_descr ? wpt->icon_descr : "Waypoint"), file_out); gbfputc(0x01, file_out); // Proximity alarm. 1 == "off", 3 == armed. @@ -237,7 +249,8 @@ bushnell_write_one(const waypoint *wpt) { } static void -bushnell_write(void) { +bushnell_write(void) +{ waypt_disp_all(bushnell_write_one); } diff --git a/gpsbabel/bushnell_trl.c b/gpsbabel/bushnell_trl.c index 744a26a7c..0c6a6cbba 100644 --- a/gpsbabel/bushnell_trl.c +++ b/gpsbabel/bushnell_trl.c @@ -34,7 +34,8 @@ arglist_t bushnell_args[] = { }; static void -rd_init(const char *fname) { +rd_init(const char *fname) +{ char h[0x14]; // Believed to be zero terminated. file_in = gbfopen_le(fname, "rb", MYNAME); gbfread(h, 1, sizeof(h), file_in); @@ -46,29 +47,34 @@ rd_init(const char *fname) { } static void -rd_deinit(void) { +rd_deinit(void) +{ gbfclose(file_out); } static void -wr_init(const char *fname) { +wr_init(const char *fname) +{ int i,l = strlen(fname); - char obuf[20] = { 0 } ; + char obuf[20] = { 0 } ; char *p = obuf; file_out = gbfopen_le(fname, "w", MYNAME); trkpt_count = 0; for (i = 0; (i < l) && (i < 20); i++) { char c = toupper(fname[i]); - if (isalnum(c)) + if (isalnum(c)) { *p++ = c; - if (c == '.') + } + if (c == '.') { break; + } } gbfwrite(&obuf, 1, 20, file_out); } static void -wr_deinit(void) { +wr_deinit(void) +{ int i = trkpt_count; while (i < 4502) { gbfputint32(0, file_out); @@ -86,7 +92,8 @@ wr_deinit(void) { * Each file contains a single waypoint. */ static void -bushnell_read(void) { +bushnell_read(void) +{ int lat_tmp,lon_tmp; while (1) { @@ -95,8 +102,9 @@ bushnell_read(void) { lat_tmp = gbfgetint32(file_in); lon_tmp = gbfgetint32(file_in); - if (!lat_tmp && !lon_tmp) + if (!lat_tmp && !lon_tmp) { break; + } wpt_tmp = waypt_new(); wpt_tmp->latitude = lat_tmp / 10000000.0; @@ -107,19 +115,22 @@ bushnell_read(void) { } static void -bushnell_write_one(const waypoint *wpt) { +bushnell_write_one(const waypoint *wpt) +{ gbint32 lat = wpt->latitude * 10000000.0; gbint32 lon = wpt->longitude * 10000000.0; trkpt_count++; - if (trkpt_count > 4502) + if (trkpt_count > 4502) { fatal(MYNAME " too many trackpoints. Max is 4502."); + } gbfputint32(lat, file_out); gbfputint32(lon, file_out); } static void -bushnell_write(void) { +bushnell_write(void) +{ track_disp_all(NULL, NULL, bushnell_write_one); } diff --git a/gpsbabel/cet.c b/gpsbabel/cet.c index e88c6b316..8264e6e77 100644 --- a/gpsbabel/cet.c +++ b/gpsbabel/cet.c @@ -28,41 +28,42 @@ #include /* ! ALL vec PARAMETERS HAVE TO BE A VALID POINTER TO A cet_cs_vec_t RECORD ! */ - + /* =========================================================================== */ /* %%% single character or value transmission %%% */ /* --------------------------------------------------------------------------- */ /* %%% cet_char_to_ucs4 %%% * - * single character to UCS-4 code %%% + * single character to UCS-4 code %%% * return values: 0 if convertable character, otherwise 1 */ - + int cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value) { - int trash, c; - int *dest; - - c = ((unsigned char)src & 0xFF); - dest = (value != NULL) ? value : &trash; - - *dest = c; - c -= vec->ucs4_offset; - - if (c < 0) return CET_SUCCESS; - else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) return CET_ERROR; - else - { - *dest = vec->ucs4_map[c]; - return CET_SUCCESS; - } + int trash, c; + int *dest; + + c = ((unsigned char)src & 0xFF); + dest = (value != NULL) ? value : &trash; + + *dest = c; + c -= vec->ucs4_offset; + + if (c < 0) { + return CET_SUCCESS; + } else if ((c >= vec->ucs4_count) || (vec->ucs4_map[c] == -1)) { + return CET_ERROR; + } else { + *dest = vec->ucs4_map[c]; + return CET_SUCCESS; + } } /* %%% cet_ucs4_to_utf8 %%% * - * convert single UCS-4 value into UTF-8 sequence + * convert single UCS-4 value into UTF-8 sequence * * return values: >= 0: length of produced UTF-8 sequence * < 0: -bytes more needed in target space @@ -71,72 +72,71 @@ cet_char_to_ucs4(const char src, const cet_cs_vec_t *vec, int *value) int cet_ucs4_to_utf8(char *dest, size_t dest_size, int value) { - int result; - unsigned char trash[16]; - unsigned char *c; - - c = (dest != NULL) ? (unsigned char *) dest : trash; - - if ((value & 0xffffff80) == 0) /* <= 7 bits */ - { - if (dest_size < 1) return (dest_size - 1); - *c++ = value; - result = 1; - } - else if ((value & 0xfffff800) == 0) /* <= 11 bits */ - { - if (dest_size < 2) return (dest_size - 2); - *c++ = (0xc0 | (value >> 6)); - *c++ = (0x80 | (value & 0x3f)); - result = 2; - - } - else if ((value & 0xffff0000) == 0) /* <= 16 bits */ - { - if (dest_size < 3) return (dest_size - 3); - *c++ = (0xe0 | (value >> 12)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 3; - } - else if ((value & 0xffe00000) == 0) /* <= 21 bits */ - { - if (dest_size < 4) return (dest_size - 4); - *c++ = (0xf0 | (value >> 18)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 4; - } - else if ((value & 0xfc000000) == 0) /* <= 26 bits */ - { - if (dest_size < 5) return (dest_size - 5); - *c++ = (0xf8 | (value >> 24)); - *c++ = (0x80 | ((value >> 18) & 0x3f)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 5; - } - else if ((value & 0x80000000) == 0) /* <= 31 bits */ - { - if (dest_size < 6) return (dest_size - 6); - *c++ = (0xfc | (value >> 30)); - *c++ = (0x80 | ((value >> 24) & 0x3f)); - *c++ = (0x80 | ((value >> 18) & 0x3f)); - *c++ = (0x80 | ((value >> 12) & 0x3f)); - *c++ = (0x80 | ((value >> 6) & 0x3f)); - *c++ = (0x80 | (value & 0x3f)); - result = 6; - } - else - { - return 0; /* Value = -1 */ - } - return result; + int result; + unsigned char trash[16]; + unsigned char *c; + + c = (dest != NULL) ? (unsigned char *) dest : trash; + + if ((value & 0xffffff80) == 0) { /* <= 7 bits */ + if (dest_size < 1) { + return (dest_size - 1); + } + *c++ = value; + result = 1; + } else if ((value & 0xfffff800) == 0) { /* <= 11 bits */ + if (dest_size < 2) { + return (dest_size - 2); + } + *c++ = (0xc0 | (value >> 6)); + *c++ = (0x80 | (value & 0x3f)); + result = 2; + + } else if ((value & 0xffff0000) == 0) { /* <= 16 bits */ + if (dest_size < 3) { + return (dest_size - 3); + } + *c++ = (0xe0 | (value >> 12)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 3; + } else if ((value & 0xffe00000) == 0) { /* <= 21 bits */ + if (dest_size < 4) { + return (dest_size - 4); + } + *c++ = (0xf0 | (value >> 18)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 4; + } else if ((value & 0xfc000000) == 0) { /* <= 26 bits */ + if (dest_size < 5) { + return (dest_size - 5); + } + *c++ = (0xf8 | (value >> 24)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 5; + } else if ((value & 0x80000000) == 0) { /* <= 31 bits */ + if (dest_size < 6) { + return (dest_size - 6); + } + *c++ = (0xfc | (value >> 30)); + *c++ = (0x80 | ((value >> 24) & 0x3f)); + *c++ = (0x80 | ((value >> 18) & 0x3f)); + *c++ = (0x80 | ((value >> 12) & 0x3f)); + *c++ = (0x80 | ((value >> 6) & 0x3f)); + *c++ = (0x80 | (value & 0x3f)); + result = 6; + } else { + return 0; /* Value = -1 */ + } + return result; } -/* %%% cet_utf8_to_ucs4 %%% +/* %%% cet_utf8_to_ucs4 %%% * * decode single UTF-8 sequence into UCS-4 value * @@ -145,55 +145,62 @@ cet_ucs4_to_utf8(char *dest, size_t dest_size, int value) int cet_utf8_to_ucs4(const char *str, int *bytes, int *value) { - unsigned char *cp = (unsigned char *)str; - - if (*cp < 0x80) - { - if (bytes != NULL) *bytes = 1; - if (value != NULL) *value = *cp; - return CET_SUCCESS; - } - else - { - unsigned char bits = 0xc0; - unsigned char mask = 0xe0; - int len = 0; - - for (len = 1; len <= 6; len++) /* outer loop, test UTF-8 frame */ - { - if ((*cp & mask) == bits) - { - int i = len; - while (i-- > 0) - { - cp++; - if ((*cp & 0xc0) != 0x80) break; /* invalid */ - else if (i == 0) /* all valid */ - { - char *c = (char *)str; /* found valid sequence, now storing value */ - int res = *c++ & (mask ^ 0xFF); - i = len; - while (i-- > 0) - res = (res << 6) | (*c++ & 0x3f); - - if (bytes != NULL) *bytes = len + 1; - if (value != NULL) *value = res; - return CET_SUCCESS; - } - } - } - bits = (bits >> 1) | 0x80; - mask = (mask >> 1) | 0x80; - } - } - if (bytes != NULL) *bytes = 1; - if (value != NULL) *value = *cp; - return CET_ERROR; /* not valid */ + unsigned char *cp = (unsigned char *)str; + + if (*cp < 0x80) { + if (bytes != NULL) { + *bytes = 1; + } + if (value != NULL) { + *value = *cp; + } + return CET_SUCCESS; + } else { + unsigned char bits = 0xc0; + unsigned char mask = 0xe0; + int len = 0; + + for (len = 1; len <= 6; len++) { /* outer loop, test UTF-8 frame */ + if ((*cp & mask) == bits) { + int i = len; + while (i-- > 0) { + cp++; + if ((*cp & 0xc0) != 0x80) { + break; /* invalid */ + } else if (i == 0) { /* all valid */ + char *c = (char *)str; /* found valid sequence, now storing value */ + int res = *c++ & (mask ^ 0xFF); + i = len; + while (i-- > 0) { + res = (res << 6) | (*c++ & 0x3f); + } + + if (bytes != NULL) { + *bytes = len + 1; + } + if (value != NULL) { + *value = res; + } + return CET_SUCCESS; + } + } + } + bits = (bits >> 1) | 0x80; + mask = (mask >> 1) | 0x80; + } + } + if (bytes != NULL) { + *bytes = 1; + } + if (value != NULL) { + *value = *cp; + } + return CET_ERROR; /* not valid */ } /* %%% cet_ucs4_to_char %%% * - * convert single UCS-4 value to original character from CS + * convert single UCS-4 value to original character from CS * * return values: coverted character or "CET_NOT_CONVERTABLE_DEFAULT" * if not possible @@ -201,46 +208,51 @@ cet_utf8_to_ucs4(const char *str, int *bytes, int *value) short cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) { - cet_ucs4_link_t *link; - - if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) - { - int i = 0; - int j = vec->ucs4_links - 1; /* validate ucs value against vec */ - while (i <= j) - { - int a = (i + j) >> 1; - int x = link[a].value; - - if (x < value) i = a + 1; - else if (x > value) j = a - 1; - else return link[a].origin; - } - } - - if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) /* can be NULL */ - { - int i = 0; - int j = vec->ucs4_extras - 1; - while (i <= j) - { - int a = (i + j) >> 1; - int x = link[a].value; - - if (x < value) i = a + 1; - else if (x > value) j = a - 1; - else return link[a].origin; - } - } - - if (value < vec->ucs4_offset + vec->ucs4_count) - return (char)value & 0xFF; - else { - if (vec->fallback && (vec->fallback != vec)) - return cet_ucs4_to_char(value, vec->fallback); - else - return CET_NOT_CONVERTABLE_DEFAULT; - } + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) { + int i = 0; + int j = vec->ucs4_links - 1; /* validate ucs value against vec */ + while (i <= j) { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) { + i = a + 1; + } else if (x > value) { + j = a - 1; + } else { + return link[a].origin; + } + } + } + + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) { /* can be NULL */ + int i = 0; + int j = vec->ucs4_extras - 1; + while (i <= j) { + int a = (i + j) >> 1; + int x = link[a].value; + + if (x < value) { + i = a + 1; + } else if (x > value) { + j = a - 1; + } else { + return link[a].origin; + } + } + } + + if (value < vec->ucs4_offset + vec->ucs4_count) { + return (char)value & 0xFF; + } else { + if (vec->fallback && (vec->fallback != vec)) { + return cet_ucs4_to_char(value, vec->fallback); + } else { + return CET_NOT_CONVERTABLE_DEFAULT; + } + } } /* %%% cet_utf8_to_char %%% @@ -248,18 +260,22 @@ cet_ucs4_to_char(const int value, const cet_cs_vec_t *vec) * Convert single UTF-8 sequence directly into associated characted * by given character set. */ - + short cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, int *value) { - int b, v; - - cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ - - if (bytes != NULL) *bytes = b; - if (value != NULL) *value = v; - - return cet_ucs4_to_char(v, vec); + int b, v; + + cet_utf8_to_ucs4(str, &b, &v); /* decode UTF-8 sequence */ + + if (bytes != NULL) { + *bytes = b; + } + if (value != NULL) { + *value = v; + } + + return cet_ucs4_to_char(v, vec); } /* =========================================================================== */ @@ -270,71 +286,74 @@ cet_utf8_to_char(const char *str, const cet_cs_vec_t *vec, /* out */ int *bytes, * * Returns the number of valid (visible) characters. */ -unsigned int +unsigned int cet_utf8_strlen(const char *str) { - if (str) { - const char *cin = str; - int len = 0; - - while (*cin) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) len++; - cin += bytes; - } - return len; - } - else - return 0; + if (str) { + const char *cin = str; + int len = 0; + + while (*cin) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + len++; + } + cin += bytes; + } + return len; + } else { + return 0; + } } /* %%% cet_utf8_strdup %%% * - * Checks and duplicates an UTF-8 string + * Checks and duplicates an UTF-8 string */ -char * +char * cet_utf8_strdup(const char *str) { - if (str) - return cet_utf8_strndup(str, strlen(str)); - else - return NULL; + if (str) { + return cet_utf8_strndup(str, strlen(str)); + } else { + return NULL; + } } /* %%% cet_utf8_strndup %%% * - * Checks and duplicates an UTF-8 string + * Checks and duplicates an UTF-8 string */ char * cet_utf8_strndup(const char *str, const int maxlen) { - if (str) { - const char *cin = str; - char *res, *cout; - int len = 0; - - res = cout = xstrdup(cin); - - while (*cin && (len < maxlen)) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { - cout += cet_ucs4_to_utf8(cout, 6, value); - len += 1; - } - cin += bytes; - } - *cout = '\0'; - - if ((cin - str) != (cout - res)) { - cout = xstrdup(res); - xfree(res); - res = cout; - } - - return res; - } - else - return NULL; + if (str) { + const char *cin = str; + char *res, *cout; + int len = 0; + + res = cout = xstrdup(cin); + + while (*cin && (len < maxlen)) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + cout += cet_ucs4_to_utf8(cout, 6, value); + len += 1; + } + cin += bytes; + } + *cout = '\0'; + + if ((cin - str) != (cout - res)) { + cout = xstrdup(res); + xfree(res); + res = cout; + } + + return res; + } else { + return NULL; + } } /* =========================================================================== */ @@ -343,32 +362,35 @@ cet_utf8_strndup(const char *str, const int maxlen) /* %%% cet_str_utf8_to_any %%% * - * Converts a UTF-8 string to given character set + * Converts a UTF-8 string to given character set */ char * cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) { - char *c = (char *)src; - int len; - char *res, *dest, *cend; - - if (c == NULL) return NULL; - if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ - - len = strlen(c); - res = dest = (char *) xmalloc(len + 1); /* target will become smaller or equal length */ - - cend = c + len; - - while (c < cend) - { - int bytes; - *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); - c += bytes; - } - *dest = '\0'; - - return res; + char *c = (char *)src; + int len; + char *res, *dest, *cend; + + if (c == NULL) { + return NULL; + } + if (vec->ucs4_count == 0) { + return xstrdup(src); /* UTF-8 -> UTF-8 */ + } + + len = strlen(c); + res = dest = (char *) xmalloc(len + 1); /* target will become smaller or equal length */ + + cend = c + len; + + while (c < cend) { + int bytes; + *dest++ = cet_utf8_to_char(c, vec, &bytes, NULL); + c += bytes; + } + *dest = '\0'; + + return res; } @@ -379,33 +401,37 @@ cet_str_utf8_to_any(const char *src, const cet_cs_vec_t *vec) char * cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) { - int len, value; - char *result, *cin, *cout; - char temp = CET_NOT_CONVERTABLE_DEFAULT; - - cin = (char *)src; - if (cin == NULL) return NULL; - if (vec->ucs4_count == 0) return xstrdup(src); /* UTF-8 -> UTF-8 */ - - len = 0; - while (*cin != '\0') /* determine length of resulting UTF-8 string */ - { - if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) - cet_char_to_ucs4(temp, vec, &value); - len += cet_ucs4_to_utf8(NULL, 6, value); - } - - result = cout = (char *) xmalloc(len + 1); - cin = (char *)src; - - while (*cin != '\0') - { - if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) - cet_char_to_ucs4(temp, vec, &value); - cout += cet_ucs4_to_utf8(cout, 6, value); - } - *cout = '\0'; - return result; + int len, value; + char *result, *cin, *cout; + char temp = CET_NOT_CONVERTABLE_DEFAULT; + + cin = (char *)src; + if (cin == NULL) { + return NULL; + } + if (vec->ucs4_count == 0) { + return xstrdup(src); /* UTF-8 -> UTF-8 */ + } + + len = 0; + while (*cin != '\0') { /* determine length of resulting UTF-8 string */ + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) { + cet_char_to_ucs4(temp, vec, &value); + } + len += cet_ucs4_to_utf8(NULL, 6, value); + } + + result = cout = (char *) xmalloc(len + 1); + cin = (char *)src; + + while (*cin != '\0') { + if (CET_ERROR == cet_char_to_ucs4(*cin++, vec, &value)) { + cet_char_to_ucs4(temp, vec, &value); + } + cout += cet_ucs4_to_utf8(cout, 6, value); + } + *cout = '\0'; + return result; } /* %%% cet_str_uni_to_utf8 %%% @@ -415,29 +441,33 @@ cet_str_any_to_utf8(const char *src, const cet_cs_vec_t *vec) char * cet_str_uni_to_utf8(const short *src, const int length) { - int i, len; - unsigned short *cin; - char *res, *cout; - - if (src == NULL) return NULL; - - len = 0; - i = length; - cin = (unsigned short *)src; - - while (i-- > 0) - len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); - - res = cout = (char *) xmalloc(len + 1); - cin = (unsigned short *)src; - i = length; - - while (i-- > 0) - cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); - - *cout = '\0'; - - return res; + int i, len; + unsigned short *cin; + char *res, *cout; + + if (src == NULL) { + return NULL; + } + + len = 0; + i = length; + cin = (unsigned short *)src; + + while (i-- > 0) { + len += cet_ucs4_to_utf8(NULL, 6, le_read16(cin++)); + } + + res = cout = (char *) xmalloc(len + 1); + cin = (unsigned short *)src; + i = length; + + while (i-- > 0) { + cout += cet_ucs4_to_utf8(cout, 6, le_read16(cin++)); + } + + *cout = '\0'; + + return res; } /* %%% cet_str_any_to_uni %%% @@ -447,33 +477,39 @@ cet_str_uni_to_utf8(const short *src, const int length) short * cet_str_any_to_uni(const char *src, const cet_cs_vec_t *vec, int *length) { - char *utf8; - int len; - short *res, *sout; - - if (! src) utf8 = xstrdup(""); - else if (vec->ucs4_count == 0) utf8 = cet_utf8_strdup(src); /* UTF-8 -> clean UTF-8 */ - else utf8 = cet_str_any_to_utf8(src, vec); - - len = cet_utf8_strlen(utf8); - res = sout = (short int *) xcalloc(2, len + 1); - - if (len) { - char *cin = utf8; - - while (*cin) { - int bytes, value; - if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { - le_write16(sout, value); - sout++; - } - cin += bytes; - } - } - - *sout = 0; - if (length) *length = len; - xfree(utf8); - - return res; + char *utf8; + int len; + short *res, *sout; + + if (! src) { + utf8 = xstrdup(""); + } else if (vec->ucs4_count == 0) { + utf8 = cet_utf8_strdup(src); /* UTF-8 -> clean UTF-8 */ + } else { + utf8 = cet_str_any_to_utf8(src, vec); + } + + len = cet_utf8_strlen(utf8); + res = sout = (short int *) xcalloc(2, len + 1); + + if (len) { + char *cin = utf8; + + while (*cin) { + int bytes, value; + if (CET_SUCCESS == cet_utf8_to_ucs4(cin, &bytes, &value)) { + le_write16(sout, value); + sout++; + } + cin += bytes; + } + } + + *sout = 0; + if (length) { + *length = len; + } + xfree(utf8); + + return res; } diff --git a/gpsbabel/cet.h b/gpsbabel/cet.h index 84099e589..33ffc7d50 100644 --- a/gpsbabel/cet.h +++ b/gpsbabel/cet.h @@ -28,26 +28,24 @@ #define CET_ERROR 1 #define CET_SUCCESS 0 -typedef struct cet_ucs4_link_s -{ - int value; /* UCS-4 value */ - short origin; /* associeted character */ +typedef struct cet_ucs4_link_s { + int value; /* UCS-4 value */ + short origin; /* associeted character */ } cet_ucs4_link_t; -typedef struct cet_cs_vec_s -{ - const char *name; /* name of character set */ - const char **alias; /* alias table */ - struct cet_cs_vec_s *fallback; /* fallback character set */ - void *unused; - const int *ucs4_map; /* char to UCS-4 value table */ - const int ucs4_offset; /* first non standard character */ - const int ucs4_count; /* values in table */ - const cet_ucs4_link_t *ucs4_link; /* UCS-4 to char backward links */ - const int ucs4_links; /* number of links */ - const cet_ucs4_link_t *ucs4_extra; /* Non standard UCS-4 to ... */ - const int ucs4_extras; /* number of extra links */ - struct cet_cs_vec_s *next; +typedef struct cet_cs_vec_s { + const char *name; /* name of character set */ + const char **alias; /* alias table */ + struct cet_cs_vec_s *fallback; /* fallback character set */ + void *unused; + const int *ucs4_map; /* char to UCS-4 value table */ + const int ucs4_offset; /* first non standard character */ + const int ucs4_count; /* values in table */ + const cet_ucs4_link_t *ucs4_link; /* UCS-4 to char backward links */ + const int ucs4_links; /* number of links */ + const cet_ucs4_link_t *ucs4_extra; /* Non standard UCS-4 to ... */ + const int ucs4_extras; /* number of extra links */ + struct cet_cs_vec_s *next; } cet_cs_vec_t; /* single char/value transmission */ diff --git a/gpsbabel/cet_util.c b/gpsbabel/cet_util.c index 205c23d25..4eee51593 100644 --- a/gpsbabel/cet_util.c +++ b/gpsbabel/cet_util.c @@ -38,10 +38,9 @@ static cet_cs_vec_t *cet_cs_vec_root = NULL; -typedef struct cet_cs_alias_s -{ - char *name; - cet_cs_vec_t *vec; +typedef struct cet_cs_alias_s { + char *name; + cet_cs_vec_t *vec; } cet_cs_alias_t; static cet_cs_alias_t *cet_cs_alias; @@ -63,78 +62,78 @@ static int cet_output = 0; char * cet_str_utf8_to_iso8859_1(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_1); } char * cet_str_iso8859_1_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_1); } char * cet_str_utf8_to_iso8859_8(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_8); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_8); } char * cet_str_iso8859_8_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_8); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_8); } char * cet_str_utf8_to_iso8859_15(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); + return cet_str_utf8_to_any(src, &cet_cs_vec_iso_8859_15); } char * cet_str_iso8859_15_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); + return cet_str_any_to_utf8(src, &cet_cs_vec_iso_8859_15); } char * cet_str_utf8_to_us_ascii(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); + return cet_str_utf8_to_any(src, &cet_cs_vec_ansi_x3_4_1968); } char * cet_str_us_ascii_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); + return cet_str_any_to_utf8(src, &cet_cs_vec_ansi_x3_4_1968); } char * cet_str_utf8_to_cp1252(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1252); } char * cet_str_cp1252_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1252); } char * cet_str_utf8_to_cp1255(const char *src) { - return cet_str_utf8_to_any(src, &cet_cs_vec_cp1255); + return cet_str_utf8_to_any(src, &cet_cs_vec_cp1255); } char * cet_str_cp1255_to_utf8(const char *src) { - return cet_str_any_to_utf8(src, &cet_cs_vec_cp1255); + return cet_str_any_to_utf8(src, &cet_cs_vec_cp1255); } short * cet_str_utf8_to_uni(const char *src, int *length) { - return cet_str_any_to_uni(src, &cet_cs_vec_utf8, length); + return cet_str_any_to_uni(src, &cet_cs_vec_utf8, length); } @@ -148,36 +147,44 @@ cet_str_utf8_to_uni(const char *src, int *length) #if HAVE_LIBEXPAT int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *xml_encoding, XML_Encoding *info) { - cet_cs_vec_t *cs; - int i, c, ucs4_def; - const char *encoding; - - encoding = xml_convert_to_char_string(xml_encoding); - cs = cet_find_cs_by_name(encoding); - if (cs == NULL) return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ - - cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); - - for (i = 0; i < cs->ucs4_offset; i++) info->map[i] = i; /* equal to ascii part */ - for (i = 0; i < cs->ucs4_count; i++) /* mixed table */ - { - c = cs->ucs4_map[i]; - if (c == -1) c = ucs4_def; - info->map[i + cs->ucs4_offset] = c; - } - for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) info->map[i] = ucs4_def; /* non convertable trailer */ - - info->data = NULL; - info->convert = NULL; - info->release = NULL; - - cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ - - if (global_opts.verbose_status > 0) - printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); - - xml_free_converted_string(encoding); - return XML_STATUS_OK; + cet_cs_vec_t *cs; + int i, c, ucs4_def; + const char *encoding; + + encoding = xml_convert_to_char_string(xml_encoding); + cs = cet_find_cs_by_name(encoding); + if (cs == NULL) { + return XML_STATUS_ERROR; /* fatal(MYNAME ": Unknown character set \"%s\"!\n", encoding); */ + } + + cet_char_to_ucs4(CET_NOT_CONVERTABLE_DEFAULT, cs, &ucs4_def); + + for (i = 0; i < cs->ucs4_offset; i++) { + info->map[i] = i; /* equal to ascii part */ + } + for (i = 0; i < cs->ucs4_count; i++) { /* mixed table */ + c = cs->ucs4_map[i]; + if (c == -1) { + c = ucs4_def; + } + info->map[i + cs->ucs4_offset] = c; + } + for (i = cs->ucs4_offset + cs->ucs4_count; i < 256; i++) { + info->map[i] = ucs4_def; /* non convertable trailer */ + } + + info->data = NULL; + info->convert = NULL; + info->release = NULL; + + cet_convert_init(CET_CHARSET_UTF8, 1); /* We do not need to transform any string */ + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": XML parser - encoding handler for character set \"%s\" established.\n", encoding); + } + + xml_free_converted_string(encoding); + return XML_STATUS_OK; } #endif @@ -185,40 +192,40 @@ int XMLCALL cet_lib_expat_UnknownEncodingHandler(void *data, const XML_Char *xml char * cet_str_uni_to_any(const short *src, int length, const cet_cs_vec_t *dest_vec) { - char *res, *c; - const cet_cs_vec_t *cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; - - res = cet_str_uni_to_utf8(src, length); - if (cs != &cet_cs_vec_utf8) - { - c = cet_str_utf8_to_any(res, cs); - xfree(res); - res = c; - } - return res; + char *res, *c; + const cet_cs_vec_t *cs = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + res = cet_str_uni_to_utf8(src, length); + if (cs != &cet_cs_vec_utf8) { + c = cet_str_utf8_to_any(res, cs); + xfree(res); + res = c; + } + return res; } -/* %%% cet_str_any_to_any %%% +/* %%% cet_str_any_to_any %%% * * -->> for use in mkshort */ char * cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_vec_t *dest_vec) { - char *c0, *c1; - const cet_cs_vec_t *v_in = (src_vec != NULL ) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; - const cet_cs_vec_t *v_out = (dest_vec != NULL ) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; - - if (src == NULL) - return NULL; - else - if ((*src == '\0') || (v_in == v_out)) return xstrdup(src); - - c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); - c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); - xfree(c0); - - return c1; + char *c0, *c1; + const cet_cs_vec_t *v_in = (src_vec != NULL) ? src_vec : &cet_cs_vec_ansi_x3_4_1968; + const cet_cs_vec_t *v_out = (dest_vec != NULL) ? dest_vec : &cet_cs_vec_ansi_x3_4_1968; + + if (src == NULL) { + return NULL; + } else if ((*src == '\0') || (v_in == v_out)) { + return xstrdup(src); + } + + c0 = (v_in == &cet_cs_vec_utf8) ? xstrdup(src) : cet_str_any_to_utf8(src, v_in); + c1 = (v_out == &cet_cs_vec_utf8) ? xstrdup(c0) : cet_str_utf8_to_any(c0, v_out); + xfree(c0); + + return c1; } /* %%% cet_valid_char %%% @@ -230,10 +237,10 @@ cet_str_any_to_any(const char *src, const cet_cs_vec_t *src_vec, const cet_cs_ve int cet_valid_char(const char *src, const cet_cs_vec_t *vec) { - int value; + int value; - const cet_cs_vec_t *v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; - return cet_char_to_ucs4(*src, v, &value); + const cet_cs_vec_t *v = (vec != NULL) ? vec : &cet_cs_vec_ansi_x3_4_1968; + return cet_char_to_ucs4(*src, v, &value); } /* %%% include character set headers %%% */ @@ -364,36 +371,30 @@ cet_valid_char(const char *src, const cet_cs_vec_t *vec) void cet_check_cs(cet_cs_vec_t *vec) /* test well sorted link & extra tables */ { - cet_ucs4_link_t *link; - - if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) - { - int i, j; - - for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) - { - if (link[i].value >= link[j].value) - { - printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); - fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); - } - - } - } - if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) - { - int i, j; - - for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) - { - if (link[i].value >= link[j].value) - { - printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); - fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); - } - - } - } + cet_ucs4_link_t *link; + + if ((link = (cet_ucs4_link_t *)vec->ucs4_link)) { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_links; i++, j++) { + if (link[i].value >= link[j].value) { + printf(MYNAME ": checked 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-link-table unsorted !!!\n", vec->name); + } + + } + } + if ((link = (cet_ucs4_link_t *)vec->ucs4_extra)) { + int i, j; + + for (i = 0, j = 1; j < vec->ucs4_extras; i++, j++) { + if (link[i].value >= link[j].value) { + printf(MYNAME ": check 0x%04x with 0x%04x\n", link[i].value, link[j].value); + fatal(MYNAME ": \"%s\"-extra-table unsorted !!!\n", vec->name); + } + + } + } } #endif @@ -401,513 +402,515 @@ cet_check_cs(cet_cs_vec_t *vec) /* test well sorted link & extra tables */ static signed int cet_cs_alias_qsort_cb(const void *a, const void *b) { - const cet_cs_alias_t *va = a; - const cet_cs_alias_t *vb = b; - return case_ignore_strcmp(va->name, vb->name); + const cet_cs_alias_t *va = a; + const cet_cs_alias_t *vb = b; + return case_ignore_strcmp(va->name, vb->name); } static signed int cet_cs_vec_qsort_cb(const void *a, const void *b) { - const cet_cs_vec_t *va = *(cet_cs_vec_t **)a; - const cet_cs_vec_t *vb = *(cet_cs_vec_t **)b; - return case_ignore_strcmp(va->name, vb->name); + const cet_cs_vec_t *va = *(cet_cs_vec_t **)a; + const cet_cs_vec_t *vb = *(cet_cs_vec_t **)b; + return case_ignore_strcmp(va->name, vb->name); } -void +void cet_register_cs(cet_cs_vec_t *vec) { - if (vec->next == NULL) - { - vec->next = cet_cs_vec_root; - cet_cs_vec_root = vec; - cet_cs_vec_ct++; + if (vec->next == NULL) { + vec->next = cet_cs_vec_root; + cet_cs_vec_root = vec; + cet_cs_vec_ct++; #ifdef DEBUG_MEM - cet_check_cs(vec); + cet_check_cs(vec); #endif - } + } } /* Dummy vector for our native character set */ -const char *cet_cs_utf8_alias[] = -{ - "utf8", NULL +const char *cet_cs_utf8_alias[] = { + "utf8", NULL }; -cet_cs_vec_t cet_cs_vec_utf8 = -{ - CET_CHARSET_UTF8, - cet_cs_utf8_alias, - NULL, /* dec */ - NULL, /* enc */ - NULL, /* link */ - 0, - 0, - NULL, /* extra */ - 0, /* extras */ - NULL +cet_cs_vec_t cet_cs_vec_utf8 = { + CET_CHARSET_UTF8, + cet_cs_utf8_alias, + NULL, /* dec */ + NULL, /* enc */ + NULL, /* link */ + 0, + 0, + NULL, /* extra */ + 0, /* extras */ + NULL }; void cet_register(void) { - int i, c; - - if (cet_cs_vec_root != NULL) return; - - cet_cs_vec_ct = 0; - cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ - + int i, c; + + if (cet_cs_vec_root != NULL) { + return; + } + + cet_cs_vec_ct = 0; + cet_register_cs(&cet_cs_vec_utf8); /* internal place holder */ + #ifdef cet_cs_name_ansi_x3_4_1968 -cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); + cet_register_cs(&cet_cs_vec_ansi_x3_4_1968); #endif #ifdef cet_cs_name_atarist -cet_register_cs(&cet_cs_vec_atarist); + cet_register_cs(&cet_cs_vec_atarist); #endif #ifdef cet_cs_name_baltic -cet_register_cs(&cet_cs_vec_baltic); + cet_register_cs(&cet_cs_vec_baltic); #endif #ifdef cet_cs_name_bs_4730 -cet_register_cs(&cet_cs_vec_bs_4730); + cet_register_cs(&cet_cs_vec_bs_4730); #endif #ifdef cet_cs_name_bs_viewdata -cet_register_cs(&cet_cs_vec_bs_viewdata); + cet_register_cs(&cet_cs_vec_bs_viewdata); #endif #ifdef cet_cs_name_cp1250 -cet_register_cs(&cet_cs_vec_cp1250); + cet_register_cs(&cet_cs_vec_cp1250); #endif #ifdef cet_cs_name_cp1251 -cet_register_cs(&cet_cs_vec_cp1251); + cet_register_cs(&cet_cs_vec_cp1251); #endif #ifdef cet_cs_name_cp1252 -cet_register_cs(&cet_cs_vec_cp1252); + cet_register_cs(&cet_cs_vec_cp1252); #endif #ifdef cet_cs_name_cp1253 -cet_register_cs(&cet_cs_vec_cp1253); + cet_register_cs(&cet_cs_vec_cp1253); #endif #ifdef cet_cs_name_cp1254 -cet_register_cs(&cet_cs_vec_cp1254); + cet_register_cs(&cet_cs_vec_cp1254); #endif #ifdef cet_cs_name_cp1255 -cet_register_cs(&cet_cs_vec_cp1255); + cet_register_cs(&cet_cs_vec_cp1255); #endif #ifdef cet_cs_name_cp1256 -cet_register_cs(&cet_cs_vec_cp1256); + cet_register_cs(&cet_cs_vec_cp1256); #endif #ifdef cet_cs_name_cp1257 -cet_register_cs(&cet_cs_vec_cp1257); + cet_register_cs(&cet_cs_vec_cp1257); #endif #ifdef cet_cs_name_csa_z243_4_1985_1 -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_1); #endif #ifdef cet_cs_name_csa_z243_4_1985_2 -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_2); #endif #ifdef cet_cs_name_csa_z243_4_1985_gr -cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); + cet_register_cs(&cet_cs_vec_csa_z243_4_1985_gr); #endif #ifdef cet_cs_name_csn_369103 -cet_register_cs(&cet_cs_vec_csn_369103); + cet_register_cs(&cet_cs_vec_csn_369103); #endif #ifdef cet_cs_name_cwi -cet_register_cs(&cet_cs_vec_cwi); + cet_register_cs(&cet_cs_vec_cwi); #endif #ifdef cet_cs_name_dec_mcs -cet_register_cs(&cet_cs_vec_dec_mcs); + cet_register_cs(&cet_cs_vec_dec_mcs); #endif #ifdef cet_cs_name_din_66003 -cet_register_cs(&cet_cs_vec_din_66003); + cet_register_cs(&cet_cs_vec_din_66003); #endif #ifdef cet_cs_name_ds_2089 -cet_register_cs(&cet_cs_vec_ds_2089); + cet_register_cs(&cet_cs_vec_ds_2089); #endif #ifdef cet_cs_name_ecma_cyrillic -cet_register_cs(&cet_cs_vec_ecma_cyrillic); + cet_register_cs(&cet_cs_vec_ecma_cyrillic); #endif #ifdef cet_cs_name_es -cet_register_cs(&cet_cs_vec_es); + cet_register_cs(&cet_cs_vec_es); #endif #ifdef cet_cs_name_es2 -cet_register_cs(&cet_cs_vec_es2); + cet_register_cs(&cet_cs_vec_es2); #endif #ifdef cet_cs_name_gb_1988_80 -cet_register_cs(&cet_cs_vec_gb_1988_80); + cet_register_cs(&cet_cs_vec_gb_1988_80); #endif #ifdef cet_cs_name_gost_19768_87 -cet_register_cs(&cet_cs_vec_gost_19768_87); + cet_register_cs(&cet_cs_vec_gost_19768_87); #endif #ifdef cet_cs_name_hp_roman8 -cet_register_cs(&cet_cs_vec_hp_roman8); + cet_register_cs(&cet_cs_vec_hp_roman8); #endif #ifdef cet_cs_name_ibm037 -cet_register_cs(&cet_cs_vec_ibm037); + cet_register_cs(&cet_cs_vec_ibm037); #endif #ifdef cet_cs_name_ibm1004 -cet_register_cs(&cet_cs_vec_ibm1004); + cet_register_cs(&cet_cs_vec_ibm1004); #endif #ifdef cet_cs_name_ibm1026 -cet_register_cs(&cet_cs_vec_ibm1026); + cet_register_cs(&cet_cs_vec_ibm1026); #endif #ifdef cet_cs_name_ibm1047 -cet_register_cs(&cet_cs_vec_ibm1047); + cet_register_cs(&cet_cs_vec_ibm1047); #endif #ifdef cet_cs_name_ibm256 -cet_register_cs(&cet_cs_vec_ibm256); + cet_register_cs(&cet_cs_vec_ibm256); #endif #ifdef cet_cs_name_ibm273 -cet_register_cs(&cet_cs_vec_ibm273); + cet_register_cs(&cet_cs_vec_ibm273); #endif #ifdef cet_cs_name_ibm277 -cet_register_cs(&cet_cs_vec_ibm277); + cet_register_cs(&cet_cs_vec_ibm277); #endif #ifdef cet_cs_name_ibm278 -cet_register_cs(&cet_cs_vec_ibm278); + cet_register_cs(&cet_cs_vec_ibm278); #endif #ifdef cet_cs_name_ibm280 -cet_register_cs(&cet_cs_vec_ibm280); + cet_register_cs(&cet_cs_vec_ibm280); #endif #ifdef cet_cs_name_ibm284 -cet_register_cs(&cet_cs_vec_ibm284); + cet_register_cs(&cet_cs_vec_ibm284); #endif #ifdef cet_cs_name_ibm285 -cet_register_cs(&cet_cs_vec_ibm285); + cet_register_cs(&cet_cs_vec_ibm285); #endif #ifdef cet_cs_name_ibm297 -cet_register_cs(&cet_cs_vec_ibm297); + cet_register_cs(&cet_cs_vec_ibm297); #endif #ifdef cet_cs_name_ibm437 -cet_register_cs(&cet_cs_vec_ibm437); + cet_register_cs(&cet_cs_vec_ibm437); #endif #ifdef cet_cs_name_ibm500 -cet_register_cs(&cet_cs_vec_ibm500); + cet_register_cs(&cet_cs_vec_ibm500); #endif #ifdef cet_cs_name_ibm850 -cet_register_cs(&cet_cs_vec_ibm850); + cet_register_cs(&cet_cs_vec_ibm850); #endif #ifdef cet_cs_name_ibm851 -cet_register_cs(&cet_cs_vec_ibm851); + cet_register_cs(&cet_cs_vec_ibm851); #endif #ifdef cet_cs_name_ibm852 -cet_register_cs(&cet_cs_vec_ibm852); + cet_register_cs(&cet_cs_vec_ibm852); #endif #ifdef cet_cs_name_ibm855 -cet_register_cs(&cet_cs_vec_ibm855); + cet_register_cs(&cet_cs_vec_ibm855); #endif #ifdef cet_cs_name_ibm857 -cet_register_cs(&cet_cs_vec_ibm857); + cet_register_cs(&cet_cs_vec_ibm857); #endif #ifdef cet_cs_name_ibm860 -cet_register_cs(&cet_cs_vec_ibm860); + cet_register_cs(&cet_cs_vec_ibm860); #endif #ifdef cet_cs_name_ibm861 -cet_register_cs(&cet_cs_vec_ibm861); + cet_register_cs(&cet_cs_vec_ibm861); #endif #ifdef cet_cs_name_ibm862 -cet_register_cs(&cet_cs_vec_ibm862); + cet_register_cs(&cet_cs_vec_ibm862); #endif #ifdef cet_cs_name_ibm863 -cet_register_cs(&cet_cs_vec_ibm863); + cet_register_cs(&cet_cs_vec_ibm863); #endif #ifdef cet_cs_name_ibm864 -cet_register_cs(&cet_cs_vec_ibm864); + cet_register_cs(&cet_cs_vec_ibm864); #endif #ifdef cet_cs_name_ibm865 -cet_register_cs(&cet_cs_vec_ibm865); + cet_register_cs(&cet_cs_vec_ibm865); #endif #ifdef cet_cs_name_ibm868 -cet_register_cs(&cet_cs_vec_ibm868); + cet_register_cs(&cet_cs_vec_ibm868); #endif #ifdef cet_cs_name_ibm869 -cet_register_cs(&cet_cs_vec_ibm869); + cet_register_cs(&cet_cs_vec_ibm869); #endif #ifdef cet_cs_name_ibm871 -cet_register_cs(&cet_cs_vec_ibm871); + cet_register_cs(&cet_cs_vec_ibm871); #endif #ifdef cet_cs_name_ibm891 -cet_register_cs(&cet_cs_vec_ibm891); + cet_register_cs(&cet_cs_vec_ibm891); #endif #ifdef cet_cs_name_ibm903 -cet_register_cs(&cet_cs_vec_ibm903); + cet_register_cs(&cet_cs_vec_ibm903); #endif #ifdef cet_cs_name_ibm904 -cet_register_cs(&cet_cs_vec_ibm904); + cet_register_cs(&cet_cs_vec_ibm904); #endif #ifdef cet_cs_name_iec_p27_1 -cet_register_cs(&cet_cs_vec_iec_p27_1); + cet_register_cs(&cet_cs_vec_iec_p27_1); #endif #ifdef cet_cs_name_iso_10367_box -cet_register_cs(&cet_cs_vec_iso_10367_box); + cet_register_cs(&cet_cs_vec_iso_10367_box); #endif #ifdef cet_cs_name_iso_5427 -cet_register_cs(&cet_cs_vec_iso_5427); + cet_register_cs(&cet_cs_vec_iso_5427); #endif #ifdef cet_cs_name_iso_646_irv -cet_register_cs(&cet_cs_vec_iso_646_irv); + cet_register_cs(&cet_cs_vec_iso_646_irv); #endif #ifdef cet_cs_name_iso_6937_2_25 -cet_register_cs(&cet_cs_vec_iso_6937_2_25); + cet_register_cs(&cet_cs_vec_iso_6937_2_25); #endif #ifdef cet_cs_name_iso_8859_1 -cet_register_cs(&cet_cs_vec_iso_8859_1); + cet_register_cs(&cet_cs_vec_iso_8859_1); #endif #ifdef cet_cs_name_iso_8859_10 -cet_register_cs(&cet_cs_vec_iso_8859_10); + cet_register_cs(&cet_cs_vec_iso_8859_10); #endif #ifdef cet_cs_name_iso_8859_13 -cet_register_cs(&cet_cs_vec_iso_8859_13); + cet_register_cs(&cet_cs_vec_iso_8859_13); #endif #ifdef cet_cs_name_iso_8859_14 -cet_register_cs(&cet_cs_vec_iso_8859_14); + cet_register_cs(&cet_cs_vec_iso_8859_14); #endif #ifdef cet_cs_name_iso_8859_15 -cet_register_cs(&cet_cs_vec_iso_8859_15); + cet_register_cs(&cet_cs_vec_iso_8859_15); #endif #ifdef cet_cs_name_iso_8859_2 -cet_register_cs(&cet_cs_vec_iso_8859_2); + cet_register_cs(&cet_cs_vec_iso_8859_2); #endif #ifdef cet_cs_name_iso_8859_3 -cet_register_cs(&cet_cs_vec_iso_8859_3); + cet_register_cs(&cet_cs_vec_iso_8859_3); #endif #ifdef cet_cs_name_iso_8859_4 -cet_register_cs(&cet_cs_vec_iso_8859_4); + cet_register_cs(&cet_cs_vec_iso_8859_4); #endif #ifdef cet_cs_name_iso_8859_5 -cet_register_cs(&cet_cs_vec_iso_8859_5); + cet_register_cs(&cet_cs_vec_iso_8859_5); #endif #ifdef cet_cs_name_iso_8859_6 -cet_register_cs(&cet_cs_vec_iso_8859_6); + cet_register_cs(&cet_cs_vec_iso_8859_6); #endif #ifdef cet_cs_name_iso_8859_7 -cet_register_cs(&cet_cs_vec_iso_8859_7); + cet_register_cs(&cet_cs_vec_iso_8859_7); #endif #ifdef cet_cs_name_iso_8859_8 -cet_register_cs(&cet_cs_vec_iso_8859_8); + cet_register_cs(&cet_cs_vec_iso_8859_8); #endif #ifdef cet_cs_name_iso_8859_9 -cet_register_cs(&cet_cs_vec_iso_8859_9); + cet_register_cs(&cet_cs_vec_iso_8859_9); #endif #ifdef cet_cs_name_iso_8859_supp -cet_register_cs(&cet_cs_vec_iso_8859_supp); + cet_register_cs(&cet_cs_vec_iso_8859_supp); #endif #ifdef cet_cs_name_it -cet_register_cs(&cet_cs_vec_it); + cet_register_cs(&cet_cs_vec_it); #endif #ifdef cet_cs_name_jis_c6220_1969_ro -cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); + cet_register_cs(&cet_cs_vec_jis_c6220_1969_ro); #endif #ifdef cet_cs_name_jis_x0201 -cet_register_cs(&cet_cs_vec_jis_x0201); + cet_register_cs(&cet_cs_vec_jis_x0201); #endif #ifdef cet_cs_name_jus_i_b1_002 -cet_register_cs(&cet_cs_vec_jus_i_b1_002); + cet_register_cs(&cet_cs_vec_jus_i_b1_002); #endif #ifdef cet_cs_name_jus_i_b1_003_mac -cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); + cet_register_cs(&cet_cs_vec_jus_i_b1_003_mac); #endif #ifdef cet_cs_name_jus_i_b1_003_serb -cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); + cet_register_cs(&cet_cs_vec_jus_i_b1_003_serb); #endif #ifdef cet_cs_name_keybcs2 -cet_register_cs(&cet_cs_vec_keybcs2); + cet_register_cs(&cet_cs_vec_keybcs2); #endif #ifdef cet_cs_name_koi8_r -cet_register_cs(&cet_cs_vec_koi8_r); + cet_register_cs(&cet_cs_vec_koi8_r); #endif #ifdef cet_cs_name_koi8_ru -cet_register_cs(&cet_cs_vec_koi8_ru); + cet_register_cs(&cet_cs_vec_koi8_ru); #endif #ifdef cet_cs_name_koi8_u -cet_register_cs(&cet_cs_vec_koi8_u); + cet_register_cs(&cet_cs_vec_koi8_u); #endif #ifdef cet_cs_name_koi_7 -cet_register_cs(&cet_cs_vec_koi_7); + cet_register_cs(&cet_cs_vec_koi_7); #endif #ifdef cet_cs_name_koi_8 -cet_register_cs(&cet_cs_vec_koi_8); + cet_register_cs(&cet_cs_vec_koi_8); #endif #ifdef cet_cs_name_koi_8_cs2 -cet_register_cs(&cet_cs_vec_koi_8_cs2); + cet_register_cs(&cet_cs_vec_koi_8_cs2); #endif #ifdef cet_cs_name_ksc5636 -cet_register_cs(&cet_cs_vec_ksc5636); + cet_register_cs(&cet_cs_vec_ksc5636); #endif #ifdef cet_cs_name_latin_greek_1 -cet_register_cs(&cet_cs_vec_latin_greek_1); + cet_register_cs(&cet_cs_vec_latin_greek_1); #endif #ifdef cet_cs_name_mac_is -cet_register_cs(&cet_cs_vec_mac_is); + cet_register_cs(&cet_cs_vec_mac_is); #endif #ifdef cet_cs_name_macintosh -cet_register_cs(&cet_cs_vec_macintosh); + cet_register_cs(&cet_cs_vec_macintosh); #endif #ifdef cet_cs_name_macintosh_ce -cet_register_cs(&cet_cs_vec_macintosh_ce); + cet_register_cs(&cet_cs_vec_macintosh_ce); #endif #ifdef cet_cs_name_msz_7795_3 -cet_register_cs(&cet_cs_vec_msz_7795_3); + cet_register_cs(&cet_cs_vec_msz_7795_3); #endif #ifdef cet_cs_name_nats_dano -cet_register_cs(&cet_cs_vec_nats_dano); + cet_register_cs(&cet_cs_vec_nats_dano); #endif #ifdef cet_cs_name_nats_sefi -cet_register_cs(&cet_cs_vec_nats_sefi); + cet_register_cs(&cet_cs_vec_nats_sefi); #endif #ifdef cet_cs_name_nc_nc00_10 -cet_register_cs(&cet_cs_vec_nc_nc00_10); + cet_register_cs(&cet_cs_vec_nc_nc00_10); #endif #ifdef cet_cs_name_nextstep -cet_register_cs(&cet_cs_vec_nextstep); + cet_register_cs(&cet_cs_vec_nextstep); #endif #ifdef cet_cs_name_nf_z_62_010 -cet_register_cs(&cet_cs_vec_nf_z_62_010); + cet_register_cs(&cet_cs_vec_nf_z_62_010); #endif #ifdef cet_cs_name_nf_z_62_010__1973_ -cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); + cet_register_cs(&cet_cs_vec_nf_z_62_010__1973_); #endif #ifdef cet_cs_name_ns_4551_1 -cet_register_cs(&cet_cs_vec_ns_4551_1); + cet_register_cs(&cet_cs_vec_ns_4551_1); #endif #ifdef cet_cs_name_ns_4551_2 -cet_register_cs(&cet_cs_vec_ns_4551_2); + cet_register_cs(&cet_cs_vec_ns_4551_2); #endif #ifdef cet_cs_name_pt -cet_register_cs(&cet_cs_vec_pt); + cet_register_cs(&cet_cs_vec_pt); #endif #ifdef cet_cs_name_pt2 -cet_register_cs(&cet_cs_vec_pt2); + cet_register_cs(&cet_cs_vec_pt2); #endif #ifdef cet_cs_name_sami -cet_register_cs(&cet_cs_vec_sami); + cet_register_cs(&cet_cs_vec_sami); #endif #ifdef cet_cs_name_sen_850200_b -cet_register_cs(&cet_cs_vec_sen_850200_b); + cet_register_cs(&cet_cs_vec_sen_850200_b); #endif #ifdef cet_cs_name_sen_850200_c -cet_register_cs(&cet_cs_vec_sen_850200_c); + cet_register_cs(&cet_cs_vec_sen_850200_c); #endif #ifdef cet_cs_name_tcvn -cet_register_cs(&cet_cs_vec_tcvn); + cet_register_cs(&cet_cs_vec_tcvn); #endif #ifdef cet_cs_name_viscii -cet_register_cs(&cet_cs_vec_viscii); + cet_register_cs(&cet_cs_vec_viscii); #endif #ifdef cet_cs_name_vps -cet_register_cs(&cet_cs_vec_vps); -#endif - - if ( cet_cs_vec_ct > 0) - { - cet_cs_vec_t *p; - cet_cs_alias_t *list; - c = 0; - - /* enumerate count of all names and aliases */ - - for (p = cet_cs_vec_root; p != NULL; p = p->next) - { - c++; - if (p->alias != NULL) - { - char **a = (char **)p->alias; - while ((*a) != NULL) - { - a++; - c++; - } - } - } - /* create name to vec table */ - - list = xcalloc(c, sizeof(*list)); - i = 0; - for (p = cet_cs_vec_root; p != NULL; p = p->next) - { - if (p->alias != NULL) - { - char **a = (char **)p->alias; - - list[i].name = xstrdup(p->name); - list[i].vec = p; - i++; - while (*a != NULL) - { - list[i].name = xstrdup(*a); - list[i].vec = p; - i++; - a++; - } - } - } - qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); - cet_cs_alias = list; - cet_cs_alias_ct = c; - - /* install fallback for ascii-like (first 128 ch.) character sets */ - for (i = 1250; i <= 1258; i++) { - char name[16]; - cet_cs_vec_t *vec; - - snprintf(name, sizeof(name), "WIN-CP%d", i); - if ((vec = cet_find_cs_by_name(name))) - vec->fallback = &cet_cs_vec_ansi_x3_4_1968; - } - for (i = 1; i <= 15; i++) { - char name[16]; - cet_cs_vec_t *vec; - - snprintf(name, sizeof(name), "ISO-8859-%d", i); - if ((vec = cet_find_cs_by_name(name))) - vec->fallback = &cet_cs_vec_ansi_x3_4_1968; - } - } -#ifdef CET_DEBUG - printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); + cet_register_cs(&cet_cs_vec_vps); +#endif + + if (cet_cs_vec_ct > 0) { + cet_cs_vec_t *p; + cet_cs_alias_t *list; + c = 0; + + /* enumerate count of all names and aliases */ + + for (p = cet_cs_vec_root; p != NULL; p = p->next) { + c++; + if (p->alias != NULL) { + char **a = (char **)p->alias; + while ((*a) != NULL) { + a++; + c++; + } + } + } + /* create name to vec table */ + + list = xcalloc(c, sizeof(*list)); + i = 0; + for (p = cet_cs_vec_root; p != NULL; p = p->next) { + if (p->alias != NULL) { + char **a = (char **)p->alias; + + list[i].name = xstrdup(p->name); + list[i].vec = p; + i++; + while (*a != NULL) { + list[i].name = xstrdup(*a); + list[i].vec = p; + i++; + a++; + } + } + } + qsort(list, c, sizeof(*list), cet_cs_alias_qsort_cb); + cet_cs_alias = list; + cet_cs_alias_ct = c; + + /* install fallback for ascii-like (first 128 ch.) character sets */ + for (i = 1250; i <= 1258; i++) { + char name[16]; + cet_cs_vec_t *vec; + + snprintf(name, sizeof(name), "WIN-CP%d", i); + if ((vec = cet_find_cs_by_name(name))) { + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + } + for (i = 1; i <= 15; i++) { + char name[16]; + cet_cs_vec_t *vec; + + snprintf(name, sizeof(name), "ISO-8859-%d", i); + if ((vec = cet_find_cs_by_name(name))) { + vec->fallback = &cet_cs_vec_ansi_x3_4_1968; + } + } + } +#ifdef CET_DEBUG + printf("We have registered %d character sets with %d aliases\n", cet_cs_vec_ct, cet_cs_alias_ct); #endif } cet_cs_vec_t * cet_find_cs_by_name(const char *name) { - int i, j; - - cet_register(); - - if (cet_cs_alias == NULL) return NULL; - - i = 0; - j = cet_cs_alias_ct - 1; - - while (i <= j) - { - int a, x; - cet_cs_alias_t *n; - - a = (i + j) >> 1; - n = &cet_cs_alias[a]; - x = case_ignore_strcmp(name, n->name); - if (x == 0) return n->vec; - else if (x < 0) j = a - 1; - else i = a + 1; - } - return NULL; + int i, j; + + cet_register(); + + if (cet_cs_alias == NULL) { + return NULL; + } + + i = 0; + j = cet_cs_alias_ct - 1; + + while (i <= j) { + int a, x; + cet_cs_alias_t *n; + + a = (i + j) >> 1; + n = &cet_cs_alias[a]; + x = case_ignore_strcmp(name, n->name); + if (x == 0) { + return n->vec; + } else if (x < 0) { + j = a - 1; + } else { + i = a + 1; + } + } + return NULL; } -void +void cet_deregister(void) { - int i; - int j = cet_cs_alias_ct; - cet_cs_alias_t *p = cet_cs_alias; - - if (p == NULL) return; - - cet_cs_alias_ct = 0; - cet_cs_alias = NULL; - - for (i = 0; i < j; i++) - xfree(p[i].name); - xfree(p); + int i; + int j = cet_cs_alias_ct; + cet_cs_alias_t *p = cet_cs_alias; + + if (p == NULL) { + return; + } + + cet_cs_alias_ct = 0; + cet_cs_alias = NULL; + + for (i = 0; i < j; i++) { + xfree(p[i].name); + } + xfree(p); } /* gpsbabel additions */ @@ -915,47 +918,45 @@ cet_deregister(void) int cet_validate_cs(const char *cs, cet_cs_vec_t **vec, char **cs_name) { - cet_cs_vec_t *v; - - if ((cs == NULL) || (strlen(cs) == 0)) /* set default us-ascii */ - { - *vec = &cet_cs_vec_ansi_x3_4_1968; - *cs_name = xstrdup(CET_CHARSET_ASCII); - return 1; - } - - v = cet_find_cs_by_name(cs); - if (v != NULL) - { - *cs_name = strupper(xstrdup(v->name)); - *vec = v; - return 1; - } - else - { - *cs_name = NULL; - *vec = NULL; - return 0; - } + cet_cs_vec_t *v; + + if ((cs == NULL) || (strlen(cs) == 0)) { /* set default us-ascii */ + *vec = &cet_cs_vec_ansi_x3_4_1968; + *cs_name = xstrdup(CET_CHARSET_ASCII); + return 1; + } + + v = cet_find_cs_by_name(cs); + if (v != NULL) { + *cs_name = strupper(xstrdup(v->name)); + *vec = v; + return 1; + } else { + *cs_name = NULL; + *vec = NULL; + return 0; + } } void cet_convert_deinit(void) { - if (global_opts.charset_name != NULL) xfree(global_opts.charset_name); - global_opts.charset = NULL; - global_opts.charset_name = NULL; + if (global_opts.charset_name != NULL) { + xfree(global_opts.charset_name); + } + global_opts.charset = NULL; + global_opts.charset_name = NULL; } void cet_convert_init(const char *cs_name, const int force) { - if ((force != 0) || (global_opts.charset == NULL)) - { - cet_convert_deinit(); - if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) - fatal("Unsupported character set \"%s\"!\n", cs_name); - } + if ((force != 0) || (global_opts.charset == NULL)) { + cet_convert_deinit(); + if (0 == cet_validate_cs(cs_name, &global_opts.charset, &global_opts.charset_name)) { + fatal("Unsupported character set \"%s\"!\n", cs_name); + } + } } /* -------------------------------------------------------------------- */ @@ -963,41 +964,41 @@ cet_convert_init(const char *cs_name, const int force) static void cet_flag_waypt(const waypoint *wpt) { - ((waypoint *)(wpt))->wpt_flags.cet_converted = 1; + ((waypoint *)(wpt))->wpt_flags.cet_converted = 1; } static void cet_flag_route(const route_head *rte) { - ((route_head *)(rte))->cet_converted = 1; + ((route_head *)(rte))->cet_converted = 1; } static void cet_flag_all(void) { - waypt_disp_all(cet_flag_waypt); - route_disp_all(cet_flag_route, NULL, cet_flag_waypt); - track_disp_all(cet_flag_route, NULL, cet_flag_waypt); + waypt_disp_all(cet_flag_waypt); + route_disp_all(cet_flag_route, NULL, cet_flag_waypt); + track_disp_all(cet_flag_route, NULL, cet_flag_waypt); } /* -------------------------------------------------------------------- */ /* %%% complete data strings transformation %%% */ /* -------------------------------------------------------------------- */ -static char * (*converter) (const char *) = NULL; +static char * (*converter)(const char *) = NULL; /* two converters */ static char * cet_convert_to_utf8(const char *str) { - return cet_str_any_to_utf8(str, global_opts.charset); + return cet_str_any_to_utf8(str, global_opts.charset); } static char * cet_convert_from_utf8(const char *str) { - return cet_str_utf8_to_any(str, global_opts.charset); + return cet_str_utf8_to_any(str, global_opts.charset); } /* cet_convert_string: internal used within cet_convert_strings process */ @@ -1005,14 +1006,17 @@ cet_convert_from_utf8(const char *str) char * cet_convert_string(char *str) { - char *res; - - if (str == NULL) return NULL; /* return origin if empty or NULL */ - else if (*str == '\0') return str; - - res = converter(str); - xfree(str); - return res; + char *res; + + if (str == NULL) { + return NULL; /* return origin if empty or NULL */ + } else if (*str == '\0') { + return str; + } + + res = converter(str); + xfree(str); + return res; } /* cet_convert_waypt: internal used within cet_convert_strings process */ @@ -1020,34 +1024,36 @@ cet_convert_string(char *str) static void cet_convert_waypt(const waypoint *wpt) { - waypoint *w = (waypoint *)wpt; - format_specific_data *fs; - url_link *url_next; - geocache_data *gc_data = (geocache_data *)wpt->gc_data; - - if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) return; - - w->wpt_flags.cet_converted = 1; - - w->shortname = cet_convert_string(wpt->shortname); - w->description = cet_convert_string(wpt->description); - w->notes = cet_convert_string(wpt->notes); - w->url = cet_convert_string(wpt->url); - w->url_link_text = cet_convert_string(wpt->url_link_text); - for (url_next = w->url_next; url_next; url_next = url_next->url_next) { - url_next->url = cet_convert_string(url_next->url); - url_next->url_link_text = cet_convert_string(url_next->url_link_text); - } - gc_data->placer = cet_convert_string(gc_data->placer); - gc_data->hint = cet_convert_string(gc_data->hint); - - fs = wpt->fs; - while (fs != NULL) - { - if (fs->convert != NULL) - fs->convert(fs); - fs = fs->next; - } + waypoint *w = (waypoint *)wpt; + format_specific_data *fs; + url_link *url_next; + geocache_data *gc_data = (geocache_data *)wpt->gc_data; + + if ((cet_output == 0) && (w->wpt_flags.cet_converted != 0)) { + return; + } + + w->wpt_flags.cet_converted = 1; + + w->shortname = cet_convert_string(wpt->shortname); + w->description = cet_convert_string(wpt->description); + w->notes = cet_convert_string(wpt->notes); + w->url = cet_convert_string(wpt->url); + w->url_link_text = cet_convert_string(wpt->url_link_text); + for (url_next = w->url_next; url_next; url_next = url_next->url_next) { + url_next->url = cet_convert_string(url_next->url); + url_next->url_link_text = cet_convert_string(url_next->url_link_text); + } + gc_data->placer = cet_convert_string(gc_data->placer); + gc_data->hint = cet_convert_string(gc_data->hint); + + fs = wpt->fs; + while (fs != NULL) { + if (fs->convert != NULL) { + fs->convert(fs); + } + fs = fs->next; + } } /* cet_convert_route_hdr: internal used within cet_convert_strings process */ @@ -1055,15 +1061,17 @@ cet_convert_waypt(const waypoint *wpt) static void cet_convert_route_hdr(const route_head *route) { - route_head *rte = (route_head *)route; - - if ((cet_output == 0) && (rte->cet_converted != 0)) return; - - rte->cet_converted = 1; - - rte->rte_name = cet_convert_string(route->rte_name); - rte->rte_desc = cet_convert_string(route->rte_desc); - rte->rte_url = cet_convert_string(route->rte_url); + route_head *rte = (route_head *)route; + + if ((cet_output == 0) && (rte->cet_converted != 0)) { + return; + } + + rte->cet_converted = 1; + + rte->rte_name = cet_convert_string(route->rte_name); + rte->rte_desc = cet_convert_string(route->rte_desc); + rte->rte_url = cet_convert_string(route->rte_url); } /* cet_convert_route_tlr: internal used within cet_convert_strings process */ @@ -1082,105 +1090,109 @@ cet_convert_route_tlr(const route_head *route) void cet_convert_strings(const cet_cs_vec_t *source, const cet_cs_vec_t *target, const char *format) { - char *cs_name_from, *cs_name_to; - - converter = NULL; - - if ((source == NULL) || (source == &cet_cs_vec_utf8)) - { - if ((target == NULL) || (target == &cet_cs_vec_utf8)) { - cet_flag_all(); - return; - } - - cet_output = 1; - - converter = cet_convert_from_utf8; - cs_name_from = (char *)cet_cs_vec_utf8.name; - cs_name_to = (char *)target->name; - } - else { - if ((target != NULL) && (target != &cet_cs_vec_utf8)) - fatal(MYNAME ": Internal error!\n"); - - cet_output = 0; - - converter = cet_convert_to_utf8; - cs_name_to = (char *)cet_cs_vec_utf8.name; - cs_name_from = (char *)source->name; - } - - if (global_opts.debug_level > 0) - printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); - - waypt_disp_all(cet_convert_waypt); - route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); - track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); - - cet_output = 0; - - if (global_opts.debug_level > 0) - printf(", done.\n"); + char *cs_name_from, *cs_name_to; + + converter = NULL; + + if ((source == NULL) || (source == &cet_cs_vec_utf8)) { + if ((target == NULL) || (target == &cet_cs_vec_utf8)) { + cet_flag_all(); + return; + } + + cet_output = 1; + + converter = cet_convert_from_utf8; + cs_name_from = (char *)cet_cs_vec_utf8.name; + cs_name_to = (char *)target->name; + } else { + if ((target != NULL) && (target != &cet_cs_vec_utf8)) { + fatal(MYNAME ": Internal error!\n"); + } + + cet_output = 0; + + converter = cet_convert_to_utf8; + cs_name_to = (char *)cet_cs_vec_utf8.name; + cs_name_from = (char *)source->name; + } + + if (global_opts.debug_level > 0) { + printf(MYNAME ": Converting from \"%s\" to \"%s\"", cs_name_from, cs_name_to); + } + + waypt_disp_all(cet_convert_waypt); + route_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + track_disp_all(cet_convert_route_hdr, cet_convert_route_tlr, cet_convert_waypt); + + cet_output = 0; + + if (global_opts.debug_level > 0) { + printf(", done.\n"); + } } /* %%% cet_disp_character_set_names %%% * * - Put all character set names and aliases to "FILE" - */ - + void cet_disp_character_set_names(FILE *fout) { - int i, c, ac; - cet_cs_vec_t *vec; - cet_cs_vec_t **list; - - if (cet_cs_alias_ct == 0) return; - - c = 0; - for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) c++; - - if (cet_cs_vec_ct != c) - fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); - - list = (cet_cs_vec_t **)xcalloc(c, sizeof(*list)); - - i = 0; /* fill the list */ - for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) list[i++] = vec; - qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ - - ac = 0; - - fprintf(fout, "GPSBabel builtin character sets: (-c option)\n"); - for (i = 0; i < c; i++) - { - char **a; - - vec = list[i]; - fprintf(fout, "\n* %s", vec->name); - - a = (char **)vec->alias; - if (a != NULL) - { - int column = 0; - int alias = 0; - - while (*a != NULL) - { - if (case_ignore_strcmp(*a, vec->name) != 0) - { - ac++; - fprintf(fout, "%s%s%s", - (alias++ > 0) ? ", " : "", - (column++ % 6 == 0) ? "\n\t" : "", - *a); - } - a++; - } - } - } - fprintf(fout, "\n\n"); - fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); - xfree(list); + int i, c, ac; + cet_cs_vec_t *vec; + cet_cs_vec_t **list; + + if (cet_cs_alias_ct == 0) { + return; + } + + c = 0; + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) { + c++; + } + + if (cet_cs_vec_ct != c) { + fatal(MYNAME ": internal error \"%s\"!\n", "cet_disp_character_set_names"); + } + + list = (cet_cs_vec_t **)xcalloc(c, sizeof(*list)); + + i = 0; /* fill the list */ + for (vec = cet_cs_vec_root; vec != NULL; vec = vec->next) { + list[i++] = vec; + } + qsort(list, c, sizeof(*list), cet_cs_vec_qsort_cb); /* sort list by name */ + + ac = 0; + + fprintf(fout, "GPSBabel builtin character sets: (-c option)\n"); + for (i = 0; i < c; i++) { + char **a; + + vec = list[i]; + fprintf(fout, "\n* %s", vec->name); + + a = (char **)vec->alias; + if (a != NULL) { + int column = 0; + int alias = 0; + + while (*a != NULL) { + if (case_ignore_strcmp(*a, vec->name) != 0) { + ac++; + fprintf(fout, "%s%s%s", + (alias++ > 0) ? ", " : "", + (column++ % 6 == 0) ? "\n\t" : "", + *a); + } + a++; + } + } + } + fprintf(fout, "\n\n"); + fprintf(fout, "We have %d builtin character sets with %d aliases!\n", c, ac); + xfree(list); } /* %%% cet_fprintf / cet_vfprintf %%% @@ -1189,32 +1201,31 @@ cet_disp_character_set_names(FILE *fout) int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, ...) { - int res; - char *cout; - va_list args; - - va_start(args, fmt); - xvasprintf(&cout, fmt, args); - va_end(args); - - if (global_opts.charset != src_vec) - { - if (src_vec != &cet_cs_vec_utf8) { - char *ctemp = cet_str_any_to_utf8(cout, src_vec); - xfree(cout); - cout = ctemp; - } - if (global_opts.charset != &cet_cs_vec_utf8) { - char *ctemp = cet_str_utf8_to_any(cout, global_opts.charset); - xfree(cout); - cout = ctemp; - } - } - - res = gbfprintf(stream, "%s", cout); - xfree(cout); - - return res; + int res; + char *cout; + va_list args; + + va_start(args, fmt); + xvasprintf(&cout, fmt, args); + va_end(args); + + if (global_opts.charset != src_vec) { + if (src_vec != &cet_cs_vec_utf8) { + char *ctemp = cet_str_any_to_utf8(cout, src_vec); + xfree(cout); + cout = ctemp; + } + if (global_opts.charset != &cet_cs_vec_utf8) { + char *ctemp = cet_str_utf8_to_any(cout, global_opts.charset); + xfree(cout); + cout = ctemp; + } + } + + res = gbfprintf(stream, "%s", cout); + xfree(cout); + + return res; } /* @@ -1224,79 +1235,79 @@ int cet_gbfprintf(gbfile *stream, const cet_cs_vec_t *src_vec, const char *fmt, const char *xml_convert_to_char_string_n(const XML_Char *src, int *n) { -#ifdef XML_UNICODE - char *utf8; - char *utf8b; - int i, j; - - /* - * '*n' is the number of source bytes. - * Walk over that, converting each character and - * discarding it, but tallying 'i' as the number of - * bytes in the destination string. - */ - i = 0; - for (j = 0; j < *n; j++) { - i += cet_ucs4_to_utf8(NULL, 6, src[j]); - } - - /* Update output byte count in caller. */ - *n = i; - - /* Appropriately size (not zero terminated) buffer */ - utf8 = utf8b = xmalloc(i); - - for (j = 0; utf8 < utf8b + i; j++) { - utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); - } - - return utf8b; -#else - return src; -#endif +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + + /* + * '*n' is the number of source bytes. + * Walk over that, converting each character and + * discarding it, but tallying 'i' as the number of + * bytes in the destination string. + */ + i = 0; + for (j = 0; j < *n; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* Update output byte count in caller. */ + *n = i; + + /* Appropriately size (not zero terminated) buffer */ + utf8 = utf8b = xmalloc(i); + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + + return utf8b; +#else + return src; +#endif } /* - * 'str' points to NULL terminated string of XML_Chars which + * 'str' points to NULL terminated string of XML_Chars which * may be UNICODE16 words in native endianness. */ const char *xml_convert_to_char_string(const XML_Char *src) { -#ifdef XML_UNICODE - char *utf8; - char *utf8b; - int i, j; - const XML_Char *in = src; - - /* Walk source array until we find source terminator */ - i = 0; - for (j = 0; src[j]; j++) { - i += cet_ucs4_to_utf8(NULL, 6, src[j]); - } - - /* We return a NUL terminated string. */ - utf8 = utf8b = xmalloc(i + 1); - in = src; - - for (j = 0; utf8 < utf8b + i; j++) { - utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); - } - *utf8 = '\0'; - - return utf8b; - +#ifdef XML_UNICODE + char *utf8; + char *utf8b; + int i, j; + const XML_Char *in = src; + + /* Walk source array until we find source terminator */ + i = 0; + for (j = 0; src[j]; j++) { + i += cet_ucs4_to_utf8(NULL, 6, src[j]); + } + + /* We return a NUL terminated string. */ + utf8 = utf8b = xmalloc(i + 1); + in = src; + + for (j = 0; utf8 < utf8b + i; j++) { + utf8 += cet_ucs4_to_utf8(utf8, 6, src[j]); + } + *utf8 = '\0'; + + return utf8b; + #else - return src; -#endif + return src; +#endif } void xml_free_converted_string(const char *str) { -#ifdef XML_UNICODE - xfree((void *) str); -#endif +#ifdef XML_UNICODE + xfree((void *) str); +#endif } const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) @@ -1308,18 +1319,21 @@ const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) const XML_Char **ptr; const char **char_attrs; - if (xml_attr == NULL) + if (xml_attr == NULL) { return NULL; + } - for (ptr = xml_attr; *ptr != NULL; ++ptr) + for (ptr = xml_attr; *ptr != NULL; ++ptr) { ++size; + } // Allocate space char_attrs = xmalloc((size + 1) * sizeof(char *)); // Duplicate strings - for (i = 0; i < size; ++i) + for (i = 0; i < size; ++i) { char_attrs[i] = xml_convert_to_char_string(xml_attr[i]); + } char_attrs[size] = NULL; return char_attrs; @@ -1330,10 +1344,10 @@ const char **xml_convert_attrs_to_char_string(const XML_Char **xml_attr) void xml_free_converted_attrs(const char **attr) { -#ifdef XML_UNICODE - while (attr != NULL && *attr != NULL) { - xfree((void *)*attr); - ++attr; - } +#ifdef XML_UNICODE + while (attr != NULL && *attr != NULL) { + xfree((void *)*attr); + ++attr; + } #endif } diff --git a/gpsbabel/cet_util.h b/gpsbabel/cet_util.h index 1fc12062f..a82e668a4 100644 --- a/gpsbabel/cet_util.h +++ b/gpsbabel/cet_util.h @@ -67,7 +67,7 @@ extern cet_cs_vec_t cet_cs_vec_utf8; /* Taken from expat_external.h (Expat 1.95.7) */ -#ifndef XML_STATUS_OK +#ifndef XML_STATUS_OK # define XML_STATUS_OK 1 #endif #ifndef XML_STATUS_ERROR diff --git a/gpsbabel/cetus.c b/gpsbabel/cetus.c index 9dc56e6d0..0ea21be8f 100644 --- a/gpsbabel/cetus.c +++ b/gpsbabel/cetus.c @@ -22,12 +22,12 @@ /* History: - + 2005/08/03: Added track_read by O.K. (Thanx to Adam Schneider for additional information) */ - + #include "defs.h" #if PDBFMTS_ENABLED #include "pdbfile.h" @@ -43,95 +43,93 @@ #define DESCSZ 4096 typedef enum { - WptEdit = 0, /* the position has been edited or it was */ - /* imported from another source */ - WptGPS2D = 1, /* retrieved from a GPS with a 2D fix */ - WptGPS3D = 2, /* retrieved from a GPS with a 3D fix */ - WptDGPS2D = 3, /* retrieved from a GPS with a 2D fix and DGPS signal */ - WptDGPS3D = 4, /* retrieved from a GPS with a 3D fix and DGPS signal */ - WptAverage = 5, /* averaging over 3D positions */ - WptCache = 50, /* this position is a geocache reference */ - WptGarmin = 70 /* this position was imported from a Garmin GPS */ - /* the icon field contains the garmin symbol number */ + WptEdit = 0, /* the position has been edited or it was */ + /* imported from another source */ + WptGPS2D = 1, /* retrieved from a GPS with a 2D fix */ + WptGPS3D = 2, /* retrieved from a GPS with a 3D fix */ + WptDGPS2D = 3, /* retrieved from a GPS with a 2D fix and DGPS signal */ + WptDGPS3D = 4, /* retrieved from a GPS with a 3D fix and DGPS signal */ + WptAverage = 5, /* averaging over 3D positions */ + WptCache = 50, /* this position is a geocache reference */ + WptGarmin = 70 /* this position was imported from a Garmin GPS */ + /* the icon field contains the garmin symbol number */ } wpt_type; struct cetus_wpt_s { - char type; - - char readonly; - - pdb_32 latitude; /* Big endian, degrees*1e7, s=negative */ - pdb_32 longitude; /* same as lat; w=negative */ - pdb_32 elevation; /* Big endian, meters*100. blank=-1e8 */ - - pdb_16 year; /* sample time, UTC */ - unsigned char mon; - unsigned char day; - unsigned char hour; - unsigned char min; - unsigned char sec; - - /* accuracy and precision information for use where applicable */ - unsigned char sat; /* ff if averaged or unknown */ - pdb_16 pdop; /* pdop * 100 */ - pdb_16 hdop; - pdb_16 vdop; - pdb_16 dgpstime; - pdb_32 dgpsstn; - pdb_32 avgtime; - pdb_32 avgite; - - pdb_16 dopmask; - pdb_16 elevmask; - - pdb_16 radius; - pdb_32 distance; - - pdb_16 vyear; /* date visited */ - unsigned char vmon; - unsigned char vday; - unsigned char vhour; - unsigned char vmin; - unsigned char vsec; - - char flagged; - - pdb_32 icon; - pdb_16 category; + char type; + + char readonly; + + pdb_32 latitude; /* Big endian, degrees*1e7, s=negative */ + pdb_32 longitude; /* same as lat; w=negative */ + pdb_32 elevation; /* Big endian, meters*100. blank=-1e8 */ + + pdb_16 year; /* sample time, UTC */ + unsigned char mon; + unsigned char day; + unsigned char hour; + unsigned char min; + unsigned char sec; + + /* accuracy and precision information for use where applicable */ + unsigned char sat; /* ff if averaged or unknown */ + pdb_16 pdop; /* pdop * 100 */ + pdb_16 hdop; + pdb_16 vdop; + pdb_16 dgpstime; + pdb_32 dgpsstn; + pdb_32 avgtime; + pdb_32 avgite; + + pdb_16 dopmask; + pdb_16 elevmask; + + pdb_16 radius; + pdb_32 distance; + + pdb_16 vyear; /* date visited */ + unsigned char vmon; + unsigned char vday; + unsigned char vhour; + unsigned char vmin; + unsigned char vsec; + + char flagged; + + pdb_32 icon; + pdb_16 category; }; -typedef struct cetus_track_head_s -{ - char id[2]; - char version; - unsigned char interval; - unsigned short gps; - char year; - char month; - char day; - char hour; - char min; - char sec; - char dsec; - char tz; - char desc; +typedef struct cetus_track_head_s { + char id[2]; + char version; + unsigned char interval; + unsigned short gps; + char year; + char month; + char day; + char hour; + char min; + char sec; + char dsec; + char tz; + char desc; } cetus_track_head_t; #define TRACK_HEAD_SIZE sizeof(struct cetus_track_head_s) -typedef struct cetus_track_point_s -{ - signed char hour; - signed char min; - signed char sec; - signed char dsec; - signed char sat; - signed char hdop; - pdb_32 latitude; - pdb_32 longitude; - short speed; - short course; - pdb_32 elevation; +typedef struct cetus_track_point_s { + signed char hour; + signed char min; + signed char sec; + signed char dsec; + signed char sat; + signed char hdop; + pdb_32 latitude; + pdb_32 longitude; + short speed; + short course; + pdb_32 elevation; } cetus_track_point_t; #define TRACK_POINT_SIZE sizeof(struct cetus_track_point_s) @@ -146,213 +144,248 @@ static char *appendicon = NULL; static arglist_t cetus_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"appendicon", &appendicon, "Append icon_descr to description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "appendicon", &appendicon, "Append icon_descr to description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static waypoint * read_track_point(cetus_track_point_t *data, const time_t basetime) { - int i, ilat, ilon; - waypoint *wpt; - - ilat = be_read32(&data->latitude); - ilon = be_read32(&data->longitude); - - if (data->hour == -1 || data->min == -1 || data->sec == -1 || - ilat == 2000000000 || ilon == 2000000000) return NULL; /* At least one of basic data is not available */ - - wpt = waypt_new(); - - wpt->latitude = (double)ilat / 10000000.0; - wpt->longitude = (double)ilon / 10000000.0; - - i = be_read32(&data->elevation); - wpt->altitude = (i == -100000000) ? unknown_alt : (double) i / 100.0; - - if (data->sat != -1) wpt->sat = data->sat; - if (data->hdop != -1) wpt->hdop = (float) data->hdop / 10; - - i = be_read16(&data->speed); - if (i != 10000) WAYPT_SET(wpt, speed, KNOTS_TO_MPS((float) i / 10)); /* meters/second */ - i = be_read16(&data->course); - if (i != 4000) WAYPT_SET(wpt, course, (float) i / 10); - - switch(data->hour >> 5) /* extract fix */ - { - case 1: wpt->fix = fix_none; break; - case 2: wpt->fix = fix_2d; break; - case 3: wpt->fix = fix_3d; break; - case 4: wpt->fix = fix_dgps; break; - default: break; /* no GPS */ - } - - wpt->creation_time = basetime + - ((data->hour & 0x1F) * 3600) + (data->min * 60) + data->sec; - if (data->dsec) - wpt->microseconds = (int)data->dsec * 10000; - - return wpt; + int i, ilat, ilon; + waypoint *wpt; + + ilat = be_read32(&data->latitude); + ilon = be_read32(&data->longitude); + + if (data->hour == -1 || data->min == -1 || data->sec == -1 || + ilat == 2000000000 || ilon == 2000000000) { + return NULL; /* At least one of basic data is not available */ + } + + wpt = waypt_new(); + + wpt->latitude = (double)ilat / 10000000.0; + wpt->longitude = (double)ilon / 10000000.0; + + i = be_read32(&data->elevation); + wpt->altitude = (i == -100000000) ? unknown_alt : (double) i / 100.0; + + if (data->sat != -1) { + wpt->sat = data->sat; + } + if (data->hdop != -1) { + wpt->hdop = (float) data->hdop / 10; + } + + i = be_read16(&data->speed); + if (i != 10000) { + WAYPT_SET(wpt, speed, KNOTS_TO_MPS((float) i / 10)); /* meters/second */ + } + i = be_read16(&data->course); + if (i != 4000) { + WAYPT_SET(wpt, course, (float) i / 10); + } + + switch (data->hour >> 5) { /* extract fix */ + case 1: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + case 3: + wpt->fix = fix_3d; + break; + case 4: + wpt->fix = fix_dgps; + break; + default: + break; /* no GPS */ + } + + wpt->creation_time = basetime + + ((data->hour & 0x1F) * 3600) + (data->min * 60) + data->sec; + if (data->dsec) { + wpt->microseconds = (int)data->dsec * 10000; + } + + return wpt; } - + static void read_tracks(const pdbfile *pdb) { - pdbrec_t *pdb_rec; - int reclen, records, total, points, dropped; - char descr[(2 * TRACK_POINT_SIZE) + 1]; - char temp_descr[TRACK_POINT_SIZE + 1]; - cetus_track_head_t *head; - waypoint *wpt; - route_head *track; - time_t basetime; - - track = route_head_alloc(); - track_add_head(track); - - total = 0; - points = 0; - dropped = 0; - basetime = 0; - - for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - int i, magic; - char *c = (char *)pdb_rec->data; - - magic = be_read32(c); - if (magic != MYTRACK) - fatal(MYNAME ": Invaid track data or unsupported version!\n"); - - reclen = be_read32(c+4); - records = reclen / TRACK_POINT_SIZE; - - c += 8; - - for (i = 0; i < records; i++, c += TRACK_POINT_SIZE) - { - switch(total++) - { - struct tm tm; - - case 0: /* track header */ - head = (cetus_track_head_t *)c; - if (head->id[0] != 'C' || head->id[1] != 'G') - fatal(MYNAME ": Invalid track header!\n"); - - memset(&tm, 0, sizeof(tm)); - tm.tm_mday = head->day; - tm.tm_mon = head->month - 1; - tm.tm_year = head->year + 100; - basetime = mkgmtime(&tm); - break; - - case 1: /* first part of description */ - strncpy(descr, c, TRACK_POINT_SIZE); - break; - - case 2: /* continued description */ - strncpy(temp_descr, c, TRACK_POINT_SIZE); - strcat(descr, temp_descr); /* here is no need to check target size */ - if (strlen(descr) > 0) - track->rte_desc = xstrdup(descr); - break; - - default: - wpt = read_track_point((cetus_track_point_t *)c, basetime); - if (wpt != NULL) - { - track_add_wpt(track, wpt); - points++; - } - else - dropped++; - } - - } - } - - if (global_opts.verbose_status > 0) - { - printf(MYNAME ": Loaded %d track point(s) from source.\n", points); - if (dropped > 0) - printf(MYNAME ": ! %d dropped because of missing data (no time, no coordinates) !\n", dropped); - } + pdbrec_t *pdb_rec; + int reclen, records, total, points, dropped; + char descr[(2 * TRACK_POINT_SIZE) + 1]; + char temp_descr[TRACK_POINT_SIZE + 1]; + cetus_track_head_t *head; + waypoint *wpt; + route_head *track; + time_t basetime; + + track = route_head_alloc(); + track_add_head(track); + + total = 0; + points = 0; + dropped = 0; + basetime = 0; + + for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + int i, magic; + char *c = (char *)pdb_rec->data; + + magic = be_read32(c); + if (magic != MYTRACK) { + fatal(MYNAME ": Invaid track data or unsupported version!\n"); + } + + reclen = be_read32(c+4); + records = reclen / TRACK_POINT_SIZE; + + c += 8; + + for (i = 0; i < records; i++, c += TRACK_POINT_SIZE) { + switch (total++) { + struct tm tm; + + case 0: /* track header */ + head = (cetus_track_head_t *)c; + if (head->id[0] != 'C' || head->id[1] != 'G') { + fatal(MYNAME ": Invalid track header!\n"); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_mday = head->day; + tm.tm_mon = head->month - 1; + tm.tm_year = head->year + 100; + basetime = mkgmtime(&tm); + break; + + case 1: /* first part of description */ + strncpy(descr, c, TRACK_POINT_SIZE); + break; + + case 2: /* continued description */ + strncpy(temp_descr, c, TRACK_POINT_SIZE); + strcat(descr, temp_descr); /* here is no need to check target size */ + if (strlen(descr) > 0) { + track->rte_desc = xstrdup(descr); + } + break; + + default: + wpt = read_track_point((cetus_track_point_t *)c, basetime); + if (wpt != NULL) { + track_add_wpt(track, wpt); + points++; + } else { + dropped++; + } + } + + } + } + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": Loaded %d track point(s) from source.\n", points); + if (dropped > 0) { + printf(MYNAME ": ! %d dropped because of missing data (no time, no coordinates) !\n", dropped); + } + } } static void read_waypts(const pdbfile *pdb) { - struct cetus_wpt_s *rec; - pdbrec_t *pdb_rec; - char *vdata; - - for(pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - int i; - - wpt_tmp = waypt_new(); - - rec = (struct cetus_wpt_s *) pdb_rec->data; - if ( be_read32(&rec->elevation) == -100000000 ) { - wpt_tmp->altitude = unknown_alt; - } - else { - wpt_tmp->altitude = be_read32(&rec->elevation) / 100.0; - } - - wpt_tmp->latitude = be_read32(&rec->latitude) / 10000000.0; - wpt_tmp->longitude = be_read32(&rec->longitude) / 10000000.0; - - if (rec->sat != 0xff) - wpt_tmp->sat = rec->sat; - - i = be_read16(&rec->pdop); - if (i != 0xffff) wpt_tmp->pdop = i / 100.0; - i = be_read16(&rec->hdop); - if (i != 0xffff) wpt_tmp->hdop = i / 100.0; - i = be_read16(&rec->vdop); - if (i != 0xffff) wpt_tmp->vdop = i / 100.0; - - switch (rec->type) { - case WptGPS2D: wpt_tmp->fix = fix_2d; break; - case WptGPS3D: wpt_tmp->fix = fix_3d; break; - case WptDGPS2D: wpt_tmp->fix = fix_dgps; break; - case WptDGPS3D: wpt_tmp->fix = fix_dgps; break; - } - - if (be_read16(&rec->year) != 0xff) { - struct tm tm; - - memset (&tm, 0, sizeof(tm)); - tm.tm_min = rec->min; - tm.tm_hour = rec->hour; - tm.tm_mday = rec->day; - tm.tm_mon = rec->mon - 1; - tm.tm_year = be_read16(&rec->year) - 1900; - - wpt_tmp->creation_time = mkgmtime(&tm); - - } - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - wpt_tmp->shortname = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->description = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->notes = xstrdup(vdata); - - waypt_add(wpt_tmp); - - } + struct cetus_wpt_s *rec; + pdbrec_t *pdb_rec; + char *vdata; + + for (pdb_rec = pdb->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + int i; + + wpt_tmp = waypt_new(); + + rec = (struct cetus_wpt_s *) pdb_rec->data; + if (be_read32(&rec->elevation) == -100000000) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = be_read32(&rec->elevation) / 100.0; + } + + wpt_tmp->latitude = be_read32(&rec->latitude) / 10000000.0; + wpt_tmp->longitude = be_read32(&rec->longitude) / 10000000.0; + + if (rec->sat != 0xff) { + wpt_tmp->sat = rec->sat; + } + + i = be_read16(&rec->pdop); + if (i != 0xffff) { + wpt_tmp->pdop = i / 100.0; + } + i = be_read16(&rec->hdop); + if (i != 0xffff) { + wpt_tmp->hdop = i / 100.0; + } + i = be_read16(&rec->vdop); + if (i != 0xffff) { + wpt_tmp->vdop = i / 100.0; + } + + switch (rec->type) { + case WptGPS2D: + wpt_tmp->fix = fix_2d; + break; + case WptGPS3D: + wpt_tmp->fix = fix_3d; + break; + case WptDGPS2D: + wpt_tmp->fix = fix_dgps; + break; + case WptDGPS3D: + wpt_tmp->fix = fix_dgps; + break; + } + + if (be_read16(&rec->year) != 0xff) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + tm.tm_min = rec->min; + tm.tm_hour = rec->hour; + tm.tm_mday = rec->day; + tm.tm_mon = rec->mon - 1; + tm.tm_year = be_read16(&rec->year) - 1900; + + wpt_tmp->creation_time = mkgmtime(&tm); + + } + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } } /* --------------------------------------------------------------------------- */ @@ -360,275 +393,274 @@ read_waypts(const pdbfile *pdb) static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - if (file_in->creator != MYCREATOR) fatal(MYNAME ": Not a Cetus file.\n"); - - switch(file_in->type) - { - case MYTYPE_TRK: - read_tracks(file_in); - break; - - case MYTYPE_WPT: - read_waypts(file_in); - break; - } + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a Cetus file.\n"); + } + + switch (file_in->type) { + case MYTYPE_TRK: + read_tracks(file_in); + break; + + case MYTYPE_WPT: + read_waypts(file_in); + break; + } } static void cetus_writewpt(const waypoint *wpt) { - struct cetus_wpt_s *rec; - struct tm *tm; - char *vdata; - char *desc_long; - char *desc_short; - char *desc_geo; - char *desc; - - rec = (struct cetus_wpt_s*) xcalloc(sizeof(*rec)+18 + NOTESZ + DESCSZ,1); - - if (wpt->creation_time && (NULL != (tm = gmtime(&wpt->creation_time)))){ - rec->min = tm->tm_min; - rec->hour = tm->tm_hour; - rec->sec = tm->tm_sec; - rec->day = tm->tm_mday; - rec->mon = tm->tm_mon + 1; - be_write16( &rec->year, tm->tm_year + 1900); - } else { - rec->min = 0xff; - rec->hour = 0xff; - rec->sec = 0xff; - rec->day = 0xff; - rec->mon = 0xff; - be_write16(&rec->year, 0xff); - } - be_write32(&rec->longitude, (unsigned int) (int) (wpt->longitude * 10000000.0)); - be_write32(&rec->latitude, (unsigned int) (wpt->latitude * 10000000.0)); - if ( wpt->altitude == unknown_alt ) { - be_write32(&rec->elevation, -100000000); - } - else { - be_write32(&rec->elevation, (unsigned int) (wpt->altitude * 100.0)); - } - - be_write16( &rec->pdop, wpt->pdop ? wpt->pdop * 100 : 0xffff ); - be_write16( &rec->hdop, wpt->hdop ? wpt->hdop * 100 : 0xffff ); - be_write16( &rec->vdop, wpt->vdop ? wpt->vdop * 100 : 0xffff ); - be_write16( &rec->dgpstime, 0xffff ); - be_write32( &rec->distance, 0xffffffff ); - - rec->vmin = 0xff; - rec->vhour = 0xff; - rec->vsec = 0xff; - rec->vday = 0xff; - rec->vmon = 0xff; - be_write16(&rec->vyear, 0xff); - - rec->sat = wpt->sat ? wpt->sat : 0xff; - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->shortname ) { - char *sn = xstrdup(wpt->shortname); - strncpy( vdata, sn, 16 ); - vdata[15] = '\0'; - xfree(sn); - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if (wpt->gc_data->diff) { - xasprintf(&desc_geo, "%s%s by %s\n%.4s/%.4s %3.1f/%3.1f\n", - wpt->gc_data->is_available==status_true ? - "" : " (Disabled)", - wpt->gc_data->is_archived==status_true ? - " (Archived)" : "", - wpt->gc_data->placer, - gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container), - wpt->gc_data->diff/10.0, - wpt->gc_data->terr/10.0); - } else { - desc_geo = xstrdup(""); - } - - if (wpt->gc_data->desc_short.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_short); - desc_short = xstrdup(wpt->gc_data->diff == 0 ? "\n\n" : ""); - desc_short = xstrappend(desc_short, xstrdup(stripped_html)); - xfree(stripped_html); - } else { - desc_short = xstrdup(""); - } - - if (wpt->gc_data->desc_long.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_long); - desc_long = xstrdup("\n\n"); - desc_long = xstrappend(desc_long, xstrdup(stripped_html)); - xfree(stripped_html); - } else { - desc_long = xstrdup(""); - } - - desc = wpt->description ? xstrdup(wpt->description) : - xstrdup(""); - - snprintf(vdata, DESCSZ, "%s%s%s%s", - desc, - desc_geo, - desc_short, - desc_long); - - xfree(desc); - xfree(desc_geo); - xfree(desc_short); - xfree(desc_long); - - if (appendicon && wpt->icon_descr) { - int left = DESCSZ - strlen( vdata ); - int ilen = strlen( wpt->icon_descr ); - if (ilen && left > (ilen+3)) { - strcat( vdata, " (" ); - strcat( vdata, wpt->icon_descr ); - strcat( vdata, ")" ); - } - } - vdata += strlen( vdata ) + 1; - - if (wpt->gc_data->hint) { - char *hint = xstrdup(wpt->gc_data->hint); - rec->type = WptCache; - strncpy( vdata, hint, NOTESZ + 1 ) ; - xfree(hint); - vdata[NOTESZ] = '\0'; - } else { - rec->type = WptEdit; - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct cetus_wpt_s *rec; + struct tm *tm; + char *vdata; + char *desc_long; + char *desc_short; + char *desc_geo; + char *desc; + + rec = (struct cetus_wpt_s*) xcalloc(sizeof(*rec)+18 + NOTESZ + DESCSZ,1); + + if (wpt->creation_time && (NULL != (tm = gmtime(&wpt->creation_time)))) { + rec->min = tm->tm_min; + rec->hour = tm->tm_hour; + rec->sec = tm->tm_sec; + rec->day = tm->tm_mday; + rec->mon = tm->tm_mon + 1; + be_write16(&rec->year, tm->tm_year + 1900); + } else { + rec->min = 0xff; + rec->hour = 0xff; + rec->sec = 0xff; + rec->day = 0xff; + rec->mon = 0xff; + be_write16(&rec->year, 0xff); + } + be_write32(&rec->longitude, (unsigned int)(int)(wpt->longitude * 10000000.0)); + be_write32(&rec->latitude, (unsigned int)(wpt->latitude * 10000000.0)); + if (wpt->altitude == unknown_alt) { + be_write32(&rec->elevation, -100000000); + } else { + be_write32(&rec->elevation, (unsigned int)(wpt->altitude * 100.0)); + } + + be_write16(&rec->pdop, wpt->pdop ? wpt->pdop * 100 : 0xffff); + be_write16(&rec->hdop, wpt->hdop ? wpt->hdop * 100 : 0xffff); + be_write16(&rec->vdop, wpt->vdop ? wpt->vdop * 100 : 0xffff); + be_write16(&rec->dgpstime, 0xffff); + be_write32(&rec->distance, 0xffffffff); + + rec->vmin = 0xff; + rec->vhour = 0xff; + rec->vsec = 0xff; + rec->vday = 0xff; + rec->vmon = 0xff; + be_write16(&rec->vyear, 0xff); + + rec->sat = wpt->sat ? wpt->sat : 0xff; + + vdata = (char *)rec + sizeof(*rec); + if (wpt->shortname) { + char *sn = xstrdup(wpt->shortname); + strncpy(vdata, sn, 16); + vdata[15] = '\0'; + xfree(sn); + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->gc_data->diff) { + xasprintf(&desc_geo, "%s%s by %s\n%.4s/%.4s %3.1f/%3.1f\n", + wpt->gc_data->is_available==status_true ? + "" : " (Disabled)", + wpt->gc_data->is_archived==status_true ? + " (Archived)" : "", + wpt->gc_data->placer, + gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container), + wpt->gc_data->diff/10.0, + wpt->gc_data->terr/10.0); + } else { + desc_geo = xstrdup(""); + } + + if (wpt->gc_data->desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_short); + desc_short = xstrdup(wpt->gc_data->diff == 0 ? "\n\n" : ""); + desc_short = xstrappend(desc_short, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_short = xstrdup(""); + } + + if (wpt->gc_data->desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_long); + desc_long = xstrdup("\n\n"); + desc_long = xstrappend(desc_long, xstrdup(stripped_html)); + xfree(stripped_html); + } else { + desc_long = xstrdup(""); + } + + desc = wpt->description ? xstrdup(wpt->description) : + xstrdup(""); + + snprintf(vdata, DESCSZ, "%s%s%s%s", + desc, + desc_geo, + desc_short, + desc_long); + + xfree(desc); + xfree(desc_geo); + xfree(desc_short); + xfree(desc_long); + + if (appendicon && wpt->icon_descr) { + int left = DESCSZ - strlen(vdata); + int ilen = strlen(wpt->icon_descr); + if (ilen && left > (ilen+3)) { + strcat(vdata, " ("); + strcat(vdata, wpt->icon_descr); + strcat(vdata, ")"); + } + } + vdata += strlen(vdata) + 1; + + if (wpt->gc_data->hint) { + char *hint = xstrdup(wpt->gc_data->hint); + rec->type = WptCache; + strncpy(vdata, hint, NOTESZ + 1) ; + xfree(hint); + vdata[NOTESZ] = '\0'; + } else { + rec->type = WptEdit; + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char *wpt_name; + waypoint *wpt; }; static -int +int compare(const void *a, const void *b) { - const struct hdr *wa = (const struct hdr*) a; - const struct hdr *wb = (const struct hdr*) b; + const struct hdr *wa = (const struct hdr*) a; + const struct hdr *wb = (const struct hdr*) b; - return strcmp(wa->wpt->shortname, wb->wpt->shortname); + return strcmp(wa->wpt->shortname, wb->wpt->shortname); } static void data_write(void) { - int i, ct = waypt_count(); - struct hdr *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - waypoint *waypointp; - mkshort_wr_handle = mkshort_new_handle(); - setshort_length(mkshort_wr_handle, 15); - setshort_whitespace_ok(mkshort_wr_handle, 0); - - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE_WPT; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - /* - * All this is to sort by waypoint names before going to Cetus. - * Turns out plain old strcmp will do the trick... - */ - - htable = xmalloc(ct * sizeof(*htable)); - bh = htable; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - bh->wpt = waypointp; - if (global_opts.synthesize_shortnames && waypointp->description) { - if (waypointp->shortname) - xfree(waypointp->shortname); - waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp); - } - bh->wpt_name = waypointp->shortname; - bh ++; - } - qsort(htable, ct, sizeof(*bh), compare); - - for (i=0;iname, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_WPT; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to Cetus. + * Turns out plain old strcmp will do the trick... + */ + + htable = xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + if (global_opts.synthesize_shortnames && waypointp->description) { + if (waypointp->shortname) { + xfree(waypointp->shortname); + } + waypointp->shortname = mkshort_from_wpt(mkshort_wr_handle, waypointp); + } + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0; i - static XML_Parser psr; +static XML_Parser psr; #endif #include @@ -44,20 +44,20 @@ static char *cdatastr; // Current XML character data being built up (until a }") - char *created; // CE's creation time (of the form "
TZ") - waypoint *wp; // GPSBabel waypoint - int used; // Is this mark used in a route or not? + queue Q; + char *id; // CE's mark ID (of the form "{}") + char *created; // CE's creation time (of the form "
TZ") + waypoint *wp; // GPSBabel waypoint + int used; // Is this mark used in a route or not? }; typedef struct CE_MARK ce_mark; /* CE-specific route structure */ struct CE_ROUTE { - queue Q; - char *id; // CE's route ID (of the form "{}") - route_head *r; // GPSBabel route header - queue ce_mark_head; // list of CE marks in this route + queue Q; + char *id; // CE's route ID (of the form "{}") + route_head *r; // GPSBabel route header + queue ce_mark_head; // list of CE marks in this route }; typedef struct CE_ROUTE ce_route; @@ -75,64 +75,66 @@ static int inMark = 0; // Are we processing a mark? static void ce_add_route(ce_route *route) { - ENQUEUE_TAIL(&ce_route_head, &route->Q); + ENQUEUE_TAIL(&ce_route_head, &route->Q); } /* Add a mark to the list of stand-alone marks */ static void ce_add_mark(ce_mark *mark) { - ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); } /* Add a mark to the specified route */ static void ce_add_mark_to_route(ce_route *route, ce_mark *mark) { - ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); + ENQUEUE_TAIL(&route->ce_mark_head, &mark->Q); } /* Free a mark */ static void ce_free_mark(ce_mark *mark) { - dequeue(&mark->Q); - if (mark->id) - xfree(mark->id); - if (mark->created) - xfree(mark->created); - xfree(mark); + dequeue(&mark->Q); + if (mark->id) { + xfree(mark->id); + } + if (mark->created) { + xfree(mark->created); + } + xfree(mark); } /* Free a route */ static void ce_free_route(ce_route *route) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_free_mark(mark); - } - xfree(route->id); - xfree(route); - // Don't free the waypoint since this is done elsewhere + queue *elem, *tmp; + QUEUE_FOR_EACH(&route->ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_free_mark(mark); + } + xfree(route->id); + xfree(route); + // Don't free the waypoint since this is done elsewhere } /* Allocate a mark */ static ce_mark * ce_alloc_mark(const waypoint *wpt, const char *id) { - ce_mark *res = xcalloc(sizeof(ce_mark), 1); - res->id = (char *) id; - res->wp = (waypoint *) wpt; - return res; + ce_mark *res = xcalloc(sizeof(ce_mark), 1); + res->id = (char *) id; + res->wp = (waypoint *) wpt; + return res; } #if !HAVE_LIBEXPAT void ce_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded CoastalExplorer support because expat was not installed.\n"); } void @@ -145,208 +147,213 @@ ce_read(void) static void ce_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - const char *el = xml_convert_to_char_string(xml_el); - const char **ap; - const char **attr; - - attr = xml_convert_attrs_to_char_string(xml_attr); - strcpy(element, el); - if (0 == strcmp(el, "Route")) { - inRoute = 1; - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "id")) { - // Create a CE route object and add it to the list of routes - currentRoute = (ce_route *) xcalloc(sizeof (ce_route), 1); - currentRoute->id=xstrdup(ap[1]); - currentRoute->r = route_head_alloc(); - QUEUE_INIT(¤tRoute->ce_mark_head); - ce_add_route(currentRoute); - } - } - } else if (0 == strcmp(el, "Mark")) { - inMark = 1; - currentMark = ce_alloc_mark(NULL, NULL); - ce_add_mark(currentMark); - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "id")) { - // Create a CE mark object and add it to the list of stand-alone marks - currentMark->id = xstrdup(ap[1]); - } - else if (0 == strcmp(ap[0], "created")) { - currentMark->created = xstrdup(ap[1]); - } - } - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); + const char *el = xml_convert_to_char_string(xml_el); + const char **ap; + const char **attr; + + attr = xml_convert_attrs_to_char_string(xml_attr); + strcpy(element, el); + if (0 == strcmp(el, "Route")) { + inRoute = 1; + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE route object and add it to the list of routes + currentRoute = (ce_route *) xcalloc(sizeof(ce_route), 1); + currentRoute->id=xstrdup(ap[1]); + currentRoute->r = route_head_alloc(); + QUEUE_INIT(¤tRoute->ce_mark_head); + ce_add_route(currentRoute); + } + } + } else if (0 == strcmp(el, "Mark")) { + inMark = 1; + currentMark = ce_alloc_mark(NULL, NULL); + ce_add_mark(currentMark); + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "id")) { + // Create a CE mark object and add it to the list of stand-alone marks + currentMark->id = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "created")) { + currentMark->created = xstrdup(ap[1]); + } + } + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } /* Finish processing an XML item */ static void ce_end(void *data, const XML_Char *xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - if (0 == strcmp(el, "Route")) { - inRoute = 0; /* ??? */ - } - else if (0 == strcmp(el, "Mark")) - inMark = 0; - xml_free_converted_string(el); + const char *el = xml_convert_to_char_string(xml_el); + if (0 == strcmp(el, "Route")) { + inRoute = 0; /* ??? */ + } else if (0 == strcmp(el, "Mark")) { + inMark = 0; + } + xml_free_converted_string(el); } /* Process some XML character data for the current item */ static void ce_cdata(void *dta, const XML_Char *xml_s, int len) { - const char *origs = xml_convert_to_char_string_n(xml_s, &len); - const char *s = origs; - if (*s != '\n') { - char *edatastr; - // We buffer up characters in 'cdatastr' until a single is received - if ((strlen(cdatastr) + len) > MY_CBUF) { - printf("Buffer overflow - line too long!"); - exit(-1); - } - edatastr = cdatastr+strlen(cdatastr); - memcpy(edatastr, s, len); - edatastr[len] = '\0'; - } else { - // Now process what we have in 'cdatastr' - s = cdatastr; - while (*s != '\0' && (*s == '\b' || *s == '\t')) - s++; - if (strlen(s) <= 0) - return; - if (0 == strcmp(element, "Marks")) { - if (inRoute) { - // We are processing the marks in a route so create a CE mark object - // and add it to the current route - ce_mark *mark = (ce_mark *) ce_alloc_mark(NULL, xstrdup(s)); - ce_add_mark_to_route(currentRoute, mark); - } - } else if (0 == strcmp(element, "Position")) { - if (inMark) { - // We are processing a standalone mark so read the lat/long position - // and create a waypoint to add to the current mark - char *position = xstrdup(s); - char *lat = position; - char *latNorS = position; - char *lng; - char *longEorW; - while (*latNorS != ' ') - latNorS++; - *latNorS++ = '\0'; - lng = latNorS; - lng++; lng++; - longEorW = lng; - while (*longEorW != ' ') - longEorW++; - *longEorW++ = '\0'; - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->latitude = atof(lat); - if (*latNorS == 'S') - currentMark->wp->latitude = -currentMark->wp->latitude; - currentMark->wp->longitude = atof(lng); - if (*longEorW == 'W') - currentMark->wp->longitude = -currentMark->wp->longitude; - xfree(position); - } - } else if (0 == strcmp(element, "Name")) { - // Names we care about may be either for routes or marks - if (inMark) - { - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->shortname = xstrdup(s); - - // Also set the creation time - if (currentMark->created) - { - struct tm t; - char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; - memset(&t, 0, sizeof(struct tm)); - strncpy(yearString, currentMark->created, 4); - yearString[4] = '\0'; - t.tm_year = atoi(yearString) - 1900; - strncpy(monthString, currentMark->created+4, 2); - monthString[2] = '\0'; - t.tm_mon = atoi(monthString) - 1; - strncpy(dayString, currentMark->created+6, 2); - dayString[2] = '\0'; - t.tm_mday = atoi(dayString); - strncpy(hourString, currentMark->created+9, 2); - hourString[2] = '\0'; - t.tm_hour = atoi(hourString); - strncpy(minString, currentMark->created+11, 2); - minString[2] = '\0'; - t.tm_min = atoi(minString); - strncpy(secString, currentMark->created+13, 2); - secString[2] = '\0'; - t.tm_sec = atoi(secString); - currentMark->wp->creation_time = mkgmtime(&t); - } - } - else if (inRoute) { - currentRoute->r->rte_name = xstrdup(s); - } - } else if (0 == strcmp(element, "Description")) { - // Descriptions we care about may be either for routes or marks - char *desc = xstrdup(s); - if (inMark) - { - if (!currentMark->wp) - currentMark->wp = waypt_new(); - currentMark->wp->description = desc; - } - else if (inRoute) - currentRoute->r->rte_desc = desc; - } - - // Start building a new string since we are done with this one - cdatastr[0] = '\0'; - } - - xml_free_converted_string(origs); + const char *origs = xml_convert_to_char_string_n(xml_s, &len); + const char *s = origs; + if (*s != '\n') { + char *edatastr; + // We buffer up characters in 'cdatastr' until a single is received + if ((strlen(cdatastr) + len) > MY_CBUF) { + printf("Buffer overflow - line too long!"); + exit(-1); + } + edatastr = cdatastr+strlen(cdatastr); + memcpy(edatastr, s, len); + edatastr[len] = '\0'; + } else { + // Now process what we have in 'cdatastr' + s = cdatastr; + while (*s != '\0' && (*s == '\b' || *s == '\t')) { + s++; + } + if (strlen(s) <= 0) { + return; + } + if (0 == strcmp(element, "Marks")) { + if (inRoute) { + // We are processing the marks in a route so create a CE mark object + // and add it to the current route + ce_mark *mark = (ce_mark *) ce_alloc_mark(NULL, xstrdup(s)); + ce_add_mark_to_route(currentRoute, mark); + } + } else if (0 == strcmp(element, "Position")) { + if (inMark) { + // We are processing a standalone mark so read the lat/long position + // and create a waypoint to add to the current mark + char *position = xstrdup(s); + char *lat = position; + char *latNorS = position; + char *lng; + char *longEorW; + while (*latNorS != ' ') { + latNorS++; + } + *latNorS++ = '\0'; + lng = latNorS; + lng++; + lng++; + longEorW = lng; + while (*longEorW != ' ') { + longEorW++; + } + *longEorW++ = '\0'; + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->latitude = atof(lat); + if (*latNorS == 'S') { + currentMark->wp->latitude = -currentMark->wp->latitude; + } + currentMark->wp->longitude = atof(lng); + if (*longEorW == 'W') { + currentMark->wp->longitude = -currentMark->wp->longitude; + } + xfree(position); + } + } else if (0 == strcmp(element, "Name")) { + // Names we care about may be either for routes or marks + if (inMark) { + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->shortname = xstrdup(s); + + // Also set the creation time + if (currentMark->created) { + struct tm t; + char yearString[5], monthString[3], dayString[3], hourString[3], minString[3], secString[3]; + memset(&t, 0, sizeof(struct tm)); + strncpy(yearString, currentMark->created, 4); + yearString[4] = '\0'; + t.tm_year = atoi(yearString) - 1900; + strncpy(monthString, currentMark->created+4, 2); + monthString[2] = '\0'; + t.tm_mon = atoi(monthString) - 1; + strncpy(dayString, currentMark->created+6, 2); + dayString[2] = '\0'; + t.tm_mday = atoi(dayString); + strncpy(hourString, currentMark->created+9, 2); + hourString[2] = '\0'; + t.tm_hour = atoi(hourString); + strncpy(minString, currentMark->created+11, 2); + minString[2] = '\0'; + t.tm_min = atoi(minString); + strncpy(secString, currentMark->created+13, 2); + secString[2] = '\0'; + t.tm_sec = atoi(secString); + currentMark->wp->creation_time = mkgmtime(&t); + } + } else if (inRoute) { + currentRoute->r->rte_name = xstrdup(s); + } + } else if (0 == strcmp(element, "Description")) { + // Descriptions we care about may be either for routes or marks + char *desc = xstrdup(s); + if (inMark) { + if (!currentMark->wp) { + currentMark->wp = waypt_new(); + } + currentMark->wp->description = desc; + } else if (inRoute) { + currentRoute->r->rte_desc = desc; + } + } + + // Start building a new string since we are done with this one + cdatastr[0] = '\0'; + } + + xml_free_converted_string(origs); } /* Set up reading the CE input file */ void ce_rd_init(const char *fname) { - fd = gbfopen(fname, "r", MYNAME); - QUEUE_INIT(&ce_route_head); - QUEUE_INIT(&ce_mark_head); + fd = gbfopen(fname, "r", MYNAME); + QUEUE_INIT(&ce_route_head); + QUEUE_INIT(&ce_mark_head); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, ce_start, ce_end); - cdatastr = xcalloc(MY_CBUF,1); - element = xcalloc(MY_CBUF,1); - XML_SetCharacterDataHandler(psr, ce_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, ce_start, ce_end); + cdatastr = xcalloc(MY_CBUF,1); + element = xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, ce_cdata); } /* Parse the input file */ void ce_read(void) { - int len; - char buf[MY_CBUF + 1]; + int len; + char buf[MY_CBUF + 1]; - while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { - buf[len] = '\0'; - if (!XML_Parse(psr, buf, len, gbfeof(fd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + buf[len] = '\0'; + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } - XML_ParserFree(psr); + XML_ParserFree(psr); } #endif @@ -355,362 +362,369 @@ ce_read(void) void ce_fix_route_mark_waypoints(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - queue *elem2, *tmp2; - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - queue *elem3, *tmp3; - QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { - ce_mark *mark2 = (ce_mark *) elem3; - if (0 == strcmp(mark->id, mark2->id)) { - mark->wp = waypt_dupe(mark2->wp); - mark2->used = 1; - break; - } - } - } - } + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + queue *elem3, *tmp3; + QUEUE_FOR_EACH(&ce_mark_head, elem3, tmp3) { + ce_mark *mark2 = (ce_mark *) elem3; + if (0 == strcmp(mark->id, mark2->id)) { + mark->wp = waypt_dupe(mark2->wp); + mark2->used = 1; + break; + } + } + } + } } /* Check route name and if NULL assign a name */ void ce_check_route_names(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - if (route->r->rte_name == NULL) { - *cdatastr = '\0'; - strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); - strcat(cdatastr, "->"); - strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); - route->r->rte_name = xstrdup(cdatastr); - } - } + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + if (route->r->rte_name == NULL) { + *cdatastr = '\0'; + strcat(cdatastr, ((ce_mark *) QUEUE_FIRST(&route->ce_mark_head))->wp->shortname); + strcat(cdatastr, "->"); + strcat(cdatastr, ((ce_mark *) QUEUE_LAST(&route->ce_mark_head))->wp->shortname); + route->r->rte_name = xstrdup(cdatastr); + } + } } /* Remove marks used in routes */ void ce_remove_used_marks(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if (mark->used) - { - if (mark->wp) - waypt_free(mark->wp); - ce_free_mark(mark); - } - } + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->used) { + if (mark->wp) { + waypt_free(mark->wp); + } + ce_free_mark(mark); + } + } } /* Print out results */ void ce_print_results(void) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - queue *elem2, *tmp2; - ce_route *route = (ce_route *) elem; - printf("Route name=%s id=%s\n", route->r->rte_name, route->id); - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - if (mark->wp == NULL) - printf(" null\n"); - else - printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); - } - } - - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); - if (mark->wp == NULL) - printf("(null)\n"); - else - printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); - } + queue *elem, *tmp; + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + queue *elem2, *tmp2; + ce_route *route = (ce_route *) elem; + printf("Route name=%s id=%s\n", route->r->rte_name, route->id); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp == NULL) { + printf(" null\n"); + } else { + printf(" %s (%f, %f)\n", mark->wp->shortname, mark->wp->latitude, mark->wp->longitude); + } + } + } + + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + printf("Mark name=%s id=%s ", mark->wp->shortname, mark->id); + if (mark->wp == NULL) { + printf("(null)\n"); + } else { + printf("(%f, %f)\n", mark->wp->latitude, mark->wp->longitude); + } + } } /* Finish reading the input file */ void ce_rd_deinit(void) { - /* If doing routes, we create GPSBabel route structures and waypoint structures for - any standalone waypoints. - If doing waypoints, we create only waypoint structures for both route waypoints and - standalone waypoints. - */ - queue *elem, *tmp; - - ce_fix_route_mark_waypoints(); - ce_check_route_names(); - ce_remove_used_marks(); - - // Log results - if (global_opts.debug_level > 1) - ce_print_results(); - - // Add routes to GPSBabel - QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { - ce_route *route = (ce_route *) elem; - queue *elem2, *tmp2; - route_add_head(route->r); - QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { - ce_mark *mark = (ce_mark *) elem2; - if (mark->wp) - route_add_wpt(route->r, mark->wp); - else - printf("Undefined mark: %s\n", mark->id); - } - ce_free_route(route); - } - - // Add (unused) marks to GPSBabel - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - waypt_add(mark->wp); - ce_free_mark(mark); - } - - gbfclose(fd); - xfree(element); - xfree(cdatastr); + /* If doing routes, we create GPSBabel route structures and waypoint structures for + any standalone waypoints. + If doing waypoints, we create only waypoint structures for both route waypoints and + standalone waypoints. + */ + queue *elem, *tmp; + + ce_fix_route_mark_waypoints(); + ce_check_route_names(); + ce_remove_used_marks(); + + // Log results + if (global_opts.debug_level > 1) { + ce_print_results(); + } + + // Add routes to GPSBabel + QUEUE_FOR_EACH(&ce_route_head, elem, tmp) { + ce_route *route = (ce_route *) elem; + queue *elem2, *tmp2; + route_add_head(route->r); + QUEUE_FOR_EACH(&route->ce_mark_head, elem2, tmp2) { + ce_mark *mark = (ce_mark *) elem2; + if (mark->wp) { + route_add_wpt(route->r, mark->wp); + } else { + printf("Undefined mark: %s\n", mark->id); + } + } + ce_free_route(route); + } + + // Add (unused) marks to GPSBabel + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + waypt_add(mark->wp); + ce_free_mark(mark); + } + + gbfclose(fd); + xfree(element); + xfree(cdatastr); } /* Setup for writing */ void ce_wr_init(const char *fname) { - QUEUE_INIT(&ce_mark_head); + QUEUE_INIT(&ce_mark_head); - // Alloocate all buffers used for writing - time_buffer = xcalloc(MY_TBUF,1); - uuid_buffer = xcalloc(MY_UBUF,1); - xml_buffer = xcalloc(MY_XBUF, 1); + // Alloocate all buffers used for writing + time_buffer = xcalloc(MY_TBUF,1); + uuid_buffer = xcalloc(MY_UBUF,1); + xml_buffer = xcalloc(MY_XBUF, 1); - ofd = gbfopen(fname, "w", MYNAME); - srand(gpsbabel_now); + ofd = gbfopen(fname, "w", MYNAME); + srand(gpsbabel_now); } void ce_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); - // Free the buffers used for writing - xfree(time_buffer); - xfree(uuid_buffer); - xfree(xml_buffer); + // Free the buffers used for writing + xfree(time_buffer); + xfree(uuid_buffer); + xfree(xml_buffer); } /* Generate a CE-style creation time based on supplied time */ static char * ce_gen_creation_time(time_t tm) { - xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); - return time_buffer; + xml_fill_in_time(time_buffer, tm, 0, XML_SHORT_TIME); + return time_buffer; } /* Generate a CE-style creation time based on current time */ static char * ce_gen_current_time(void) { - return ce_gen_creation_time(current_time()); + return ce_gen_creation_time(current_time()); } /* Generate a UUID (has same format as Microsoft registry GUIDs */ static char * ce_gen_uuid(void) { - uuid_t uu; + uuid_t uu; - memset(&uu, 0, sizeof(uu)); - gb_uuid_generate(uu); - sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", - uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], - uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); - return uuid_buffer; + memset(&uu, 0, sizeof(uu)); + gb_uuid_generate(uu); + sprintf(uuid_buffer, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7], + uu[8], uu[9], uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); + return uuid_buffer; } /* Generate route header XML */ static void ce_route_hdr(const route_head *rte) { - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); - write_xml_entity_begin0(ofd, "\t\t", "Marks"); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + write_xml_entity_begin2(ofd, "\t", "Route", "created", ce_gen_current_time(), "id", xml_buffer); + write_xml_entity_begin0(ofd, "\t\t", "Marks"); } /* Generate route body XML */ static void ce_route_disp(const waypoint *waypointp) { - char *uuid = ce_gen_uuid(); - char *id = xcalloc(strlen(uuid)+3, 1); - - sprintf(id, "{%s}", uuid); - currentMark = ce_alloc_mark(waypointp, id); - ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + char *uuid = ce_gen_uuid(); + char *id = xcalloc(strlen(uuid)+3, 1); - gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! + sprintf(id, "{%s}", uuid); + currentMark = ce_alloc_mark(waypointp, id); + ENQUEUE_TAIL(&ce_mark_head, ¤tMark->Q); + + gbfprintf(ofd, "\t\t\t%s\n", id); // CE's departure from XML standard! } /* Generate route trailer XML */ static void ce_route_tlr(const route_head *rte) { - write_xml_entity_end(ofd, "\t\t", "Marks"); - write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); - write_xml_entity_end(ofd, "\t", "Route"); + write_xml_entity_end(ofd, "\t\t", "Marks"); + write_optional_xml_entity(ofd, "\t\t", "Name", rte->rte_name); + write_xml_entity_end(ofd, "\t", "Route"); } /* Generate waypoint body XML */ static void ce_waypt_pr(const waypoint *wp) { - double latitude = wp->latitude; - char NorS = 'N'; - char EorW = 'E'; - double longitude = wp->longitude; - - if (latitude < 0) { - latitude = -latitude; - NorS = 'S'; - } - if (longitude < 0) { - longitude = -longitude; - EorW = 'W'; - } - sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); - write_xml_entity(ofd, "\t\t", "Position", xml_buffer); - write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); - if (wp->description && wp->shortname && - strcmp(wp->description, wp->shortname)) - write_optional_xml_entity(ofd, "\t\t", "Description", wp->description); + double latitude = wp->latitude; + char NorS = 'N'; + char EorW = 'E'; + double longitude = wp->longitude; + + if (latitude < 0) { + latitude = -latitude; + NorS = 'S'; + } + if (longitude < 0) { + longitude = -longitude; + EorW = 'W'; + } + sprintf(xml_buffer, "%3.6f %c %3.6f %c", latitude, NorS, longitude, EorW); + write_xml_entity(ofd, "\t\t", "Position", xml_buffer); + write_optional_xml_entity(ofd, "\t\t", "Name", wp->shortname); + if (wp->description && wp->shortname && + strcmp(wp->description, wp->shortname)) { + write_optional_xml_entity(ofd, "\t\t", "Description", wp->description); + } } static char * ce_find_uuid(const waypoint *wpt) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if (mark->wp == wpt) { - return mark->id; - } - } - return NULL; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if (mark->wp == wpt) { + return mark->id; + } + } + return NULL; } static waypoint * ce_find_wpt(const waypoint *wpt) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - if ((mark->wp->shortname == wpt->shortname) && - (mark->wp->latitude == wpt->latitude) && - (mark->wp->longitude == wpt->longitude)) - return mark->wp; - } - return NULL; + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + if ((mark->wp->shortname == wpt->shortname) && + (mark->wp->latitude == wpt->latitude) && + (mark->wp->longitude == wpt->longitude)) { + return mark->wp; + } + } + return NULL; } /* Generate a mark XML; look for created id's */ static void ce_mark_pr(const waypoint *wp) { - char *id; - - if (inRoute) { - id = ce_find_uuid(wp); - if (id == NULL) { - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - id = xml_buffer; - } - } - /* Have we seen and written the (nearly) same waypoint ? */ - else if (ce_find_wpt(wp) != NULL) return; - else { - ce_mark *mark = ce_alloc_mark(wp, NULL); - ENQUEUE_TAIL(&ce_mark_head, &mark->Q); - sprintf(xml_buffer, "{%s}", ce_gen_uuid()); - id = xml_buffer; - } - write_xml_entity_begin2(ofd, "\t", "Mark", - "created", ce_gen_creation_time(wp->creation_time), - "id", id); - ce_waypt_pr(wp); - write_xml_entity_end(ofd, "\t", "Mark"); + char *id; + + if (inRoute) { + id = ce_find_uuid(wp); + if (id == NULL) { + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + } + /* Have we seen and written the (nearly) same waypoint ? */ + else if (ce_find_wpt(wp) != NULL) { + return; + } else { + ce_mark *mark = ce_alloc_mark(wp, NULL); + ENQUEUE_TAIL(&ce_mark_head, &mark->Q); + sprintf(xml_buffer, "{%s}", ce_gen_uuid()); + id = xml_buffer; + } + write_xml_entity_begin2(ofd, "\t", "Mark", + "created", ce_gen_creation_time(wp->creation_time), + "id", id); + ce_waypt_pr(wp); + write_xml_entity_end(ofd, "\t", "Mark"); } /* Generate all route marks */ static void ce_marks_pr(void) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_mark_pr(mark->wp); - } + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_mark_pr(mark->wp); + } } /* Release all generated marks */ static void ce_marks_flush_all(void) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { - ce_mark *mark = (ce_mark *) elem; - ce_free_mark(mark); - } + QUEUE_FOR_EACH(&ce_mark_head, elem, tmp) { + ce_mark *mark = (ce_mark *) elem; + ce_free_mark(mark); + } } /* Write all routes and marks */ void ce_write(void) { - /* If doing routes, we write out the routes and all the standalone waypoints. - If doing waypoints, we write out the route waypoints (without the routes) and - the standalone waypoints. - */ - time_t now = 0; - now = current_time(); - - write_xml_header(ofd); - write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", - ce_gen_current_time()); - write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); - - inRoute = 1; - route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); - ce_marks_pr(); - inRoute = 0; - - waypt_disp_all(ce_mark_pr); - ce_marks_flush_all(); - - write_xml_entity_end(ofd, "", "NavObjectCollection"); + /* If doing routes, we write out the routes and all the standalone waypoints. + If doing waypoints, we write out the route waypoints (without the routes) and + the standalone waypoints. + */ + time_t now = 0; + now = current_time(); + + write_xml_header(ofd); + write_xml_entity_begin1(ofd, "", "NavObjectCollection", "created", + ce_gen_current_time()); + write_xml_entity(ofd, "\t", "Name", "Navigation Objects"); + + inRoute = 1; + route_disp_all(ce_route_hdr, ce_route_tlr, ce_route_disp); + ce_marks_pr(); + inRoute = 0; + + waypt_disp_all(ce_mark_pr); + ce_marks_flush_all(); + + write_xml_entity_end(ofd, "", "NavObjectCollection"); } ff_vecs_t coastexp_vecs = { - ff_type_file, - { ff_cap_read|ff_cap_write, ff_cap_none, ff_cap_read|ff_cap_write }, - ce_rd_init, - ce_wr_init, - ce_rd_deinit, - ce_wr_deinit, - ce_read, - ce_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read|ff_cap_write, ff_cap_none, ff_cap_read|ff_cap_write }, + ce_rd_init, + ce_wr_init, + ce_rd_deinit, + ce_wr_deinit, + ce_read, + ce_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/compegps.c b/gpsbabel/compegps.c index eb5fa0f59..0f8d20b76 100644 --- a/gpsbabel/compegps.c +++ b/gpsbabel/compegps.c @@ -28,12 +28,12 @@ 08/13/2006: switch to gbfile api */ -/* - +/* + the meaning of leading characters in CompeGPS data lines (enhanced PCX): - header lines: - + header lines: + "G": WGS 84 - Datum of the map "N": Anybody - Name of the user "L": -02:00:00 - Difference to UTC @@ -44,16 +44,16 @@ "C": 0 0 255 2 -1.000000 - ??? "V": 0.0 0.0 0 0 0 0 0.0 - ??? "E": 0|1|00-NUL-00 00:00:00|00:00:00|0 - ??? - + data lines: - + "W": if(route) routepoint; else waypoint - "T": trackpoint + "T": trackpoint "t": if(track) additionally track info if(!track) additionally trackpoint info "a": link to ... "w": waypoint additional info - + */ #include "defs.h" @@ -91,55 +91,65 @@ static char *option_snlen; static arglist_t compegps_args[] = { - {"deficon", &option_icon, "Default icon name", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"index", &option_index, "Index of route/track to write (if more than one in source)", - NULL, ARGTYPE_INT, "1", NULL}, - {"radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", - NULL, ARGTYPE_FLOAT, "0", NULL}, - {"snlen", &option_snlen, "Length of generated shortnames (default 16)", - "16", ARGTYPE_INT, "1", NULL}, - ARG_TERMINATOR + { + "deficon", &option_icon, "Default icon name", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "index", &option_index, "Index of route/track to write (if more than one in source)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "radius", &option_radius, "Give points (waypoints/route points) a default radius (proximity)", + NULL, ARGTYPE_FLOAT, "0", NULL + }, + { + "snlen", &option_snlen, "Length of generated shortnames (default 16)", + "16", ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; static void fix_datum(double *lat, double *lon) { - double amt; - - /* - * Avoid FP jitter in the common case. - */ - if (input_datum != DATUM_WGS84) { - GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, - &amt, input_datum); - } + double amt; + + /* + * Avoid FP jitter in the common case. + */ + if (input_datum != DATUM_WGS84) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, lat, lon, + &amt, input_datum); + } } static void compegps_parse_date(const char *c, struct tm* tm) { - char month[4]; - int year; - tm->tm_mday = atoi(c); - strncpy(month, c+3, 3); - month[3] = 0; - tm->tm_mon = month_lookup(month); - year = atoi(c + 7); - if (year < 70) - year += 100; - if (year > 1900) - year -= 1900; - tm->tm_year = year; - // if (tm->tm_year < 70) tm->tm_year += 100; + char month[4]; + int year; + tm->tm_mday = atoi(c); + strncpy(month, c+3, 3); + month[3] = 0; + tm->tm_mon = month_lookup(month); + year = atoi(c + 7); + if (year < 70) { + year += 100; + } + if (year > 1900) { + year -= 1900; + } + tm->tm_year = year; + // if (tm->tm_year < 70) tm->tm_year += 100; } static void compegps_parse_time(const char *c, struct tm* tm) { - tm->tm_hour = atoi(c); - tm->tm_min = atoi(c+3); - tm->tm_sec = atoi(c+6); + tm->tm_hour = atoi(c); + tm->tm_min = atoi(c+3); + tm->tm_sec = atoi(c+6); } /* specialized readers */ @@ -147,220 +157,222 @@ compegps_parse_time(const char *c, struct tm* tm) static waypoint* parse_wpt(char *buff) { - int col = -1; - char *c, *cx; - waypoint *wpt = waypt_new(); - struct tm tm; - int has_time = 0; - memset(&tm, 0, sizeof(tm)); - - c = strstr(buff, "A "); - if (c == buff) col++; - - c = csv_lineparse(buff, " ", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + int col = -1; + char *c, *cx; + waypoint *wpt = waypt_new(); + struct tm tm; + int has_time = 0; + memset(&tm, 0, sizeof(tm)); + + c = strstr(buff, "A "); + if (c == buff) { + col++; + } + + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); + printf(MYNAME "_read_wpt: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - - cx = c + strlen(c) - 1; /* trim trailing underscores */ - while ((cx >= c) && (*cx == '_')) *cx-- = '\0'; - if (*c != '\0') - wpt->shortname = xstrdup(c); - break; - case 2: - human_to_dec(c, &wpt->latitude, NULL, 1); - break; - case 3: - human_to_dec(c, NULL, &wpt->longitude, 2); - break; - // Older compegps used a dumb constant. - // Report are that 2010-era writes a sensible - // value here. - /* always "27-MAR-62 00:00:00" */ - case 4: - if (strcmp(c, "27-MAR-62")) { - has_time = 1; - compegps_parse_date(c, &tm); - } - break; - case 5: - if (has_time) { - compegps_parse_time(c, &tm); - wpt->creation_time = mkgmtime(&tm); - } - case 6: - wpt->altitude = atof(c); - break; - case 7: - wpt->description = xstrdup(c); - break; - default: - if (col > 7) - { - wpt->description = xstrappend(wpt->description, " "); - wpt->description = xstrappend(wpt->description, c); - } - } - } - c = csv_lineparse(NULL, " ", "", col++); - } - fix_datum(&wpt->latitude, &wpt->longitude); - return wpt; + switch (col) { + case 0: + + cx = c + strlen(c) - 1; /* trim trailing underscores */ + while ((cx >= c) && (*cx == '_')) { + *cx-- = '\0'; + } + if (*c != '\0') { + wpt->shortname = xstrdup(c); + } + break; + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + // Older compegps used a dumb constant. + // Report are that 2010-era writes a sensible + // value here. + /* always "27-MAR-62 00:00:00" */ + case 4: + if (strcmp(c, "27-MAR-62")) { + has_time = 1; + compegps_parse_date(c, &tm); + } + break; + case 5: + if (has_time) { + compegps_parse_time(c, &tm); + wpt->creation_time = mkgmtime(&tm); + } + case 6: + wpt->altitude = atof(c); + break; + case 7: + wpt->description = xstrdup(c); + break; + default: + if (col > 7) { + wpt->description = xstrappend(wpt->description, " "); + wpt->description = xstrappend(wpt->description, c); + } + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; } static void parse_wpt_info(const char *buff, waypoint *wpt) /* "w" */ { - char *c; - int col = -1; - double fx; - - c = csv_lineparse(buff, ",", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char *c; + int col = -1; + double fx; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_wpt_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - wpt->icon_descr = xstrdup(c); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 1: break; /* Text postion */ - case 2: break; /* Lens zoom level */ - case 3: break; /* Text colour */ - case 4: break; /* Background colour */ - case 5: break; /* Transparent text  (0=transparent, 1=no transparent) */ - case 6: break; /* ??? */ - case 7: break; /* ??? */ - case 8: /* radius */ - fx = atof(c); - if (fx > 0) WAYPT_SET(wpt, proximity, fx); - break; - } - } - c = csv_lineparse(NULL, ",", "", col++); - } + switch (col) { + case 0: + wpt->icon_descr = xstrdup(c); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 1: + break; /* Text postion */ + case 2: + break; /* Lens zoom level */ + case 3: + break; /* Text colour */ + case 4: + break; /* Background colour */ + case 5: + break; /* Transparent text  (0=transparent, 1=no transparent) */ + case 6: + break; /* ??? */ + case 7: + break; /* ??? */ + case 8: /* radius */ + fx = atof(c); + if (fx > 0) { + WAYPT_SET(wpt, proximity, fx); + } + break; + } + } + c = csv_lineparse(NULL, ",", "", col++); + } } static waypoint * parse_trkpt(char *buff) { - int col = -1; - char *c; - struct tm tm; - waypoint *wpt = waypt_new(); - - c = strstr(buff, "A "); - if (c == buff) col++; - - memset(&tm, 0, sizeof(tm)); - c = csv_lineparse(buff, " ", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + int col = -1; + char *c; + struct tm tm; + waypoint *wpt = waypt_new(); + + c = strstr(buff, "A "); + if (c == buff) { + col++; + } + + memset(&tm, 0, sizeof(tm)); + c = csv_lineparse(buff, " ", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); + printf(MYNAME "_read_trkpt: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 2: - human_to_dec(c, &wpt->latitude, NULL, 1); - break; - case 3: - human_to_dec(c, NULL, &wpt->longitude, 2); - break; - case 4: - compegps_parse_date(c, &tm); - break; - case 5: - compegps_parse_time(c, &tm); - wpt->creation_time = mkgmtime(&tm); - break; - case 7: - wpt->altitude = atof(c); - break; - } - } - c = csv_lineparse(NULL, " ", "", col++); - } - fix_datum(&wpt->latitude, &wpt->longitude); - return wpt; + switch (col) { + case 2: + human_to_dec(c, &wpt->latitude, NULL, 1); + break; + case 3: + human_to_dec(c, NULL, &wpt->longitude, 2); + break; + case 4: + compegps_parse_date(c, &tm); + break; + case 5: + compegps_parse_time(c, &tm); + wpt->creation_time = mkgmtime(&tm); + break; + case 7: + wpt->altitude = atof(c); + break; + } + } + c = csv_lineparse(NULL, " ", "", col++); + } + fix_datum(&wpt->latitude, &wpt->longitude); + return wpt; } static void parse_track_info(const char *buff, route_head *track) /* "t" */ { - char *c; - int col = -1; - - c = csv_lineparse(buff, "|", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char *c; + int col = -1; + + c = csv_lineparse(buff, "|", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_track_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: - break; /* unknown field */ - case 1: - track->rte_name = xstrdup(c); - break; - case 2: - break; /* unknown field */ - case 3: - break; /* unknown field */ - } - } - c = csv_lineparse(NULL, "|", "", col++); - } + switch (col) { + case 0: + break; /* unknown field */ + case 1: + track->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + case 3: + break; /* unknown field */ + } + } + c = csv_lineparse(NULL, "|", "", col++); + } } static void parse_rte_info(const char *buff, route_head *route) /* "R" */ { - char *c; - int col = -1; - - c = csv_lineparse(buff, ",", "", col++); - while (c != NULL) - { - c = lrtrim(c); - if (*c != '\0') - { + char *c; + int col = -1; + + c = csv_lineparse(buff, ",", "", col++); + while (c != NULL) { + c = lrtrim(c); + if (*c != '\0') { #if 0 - printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); + printf(MYNAME "_read_rte_info: col(%d)=%s\n", col, c); #endif - switch(col) - { - case 0: break; /* unknown field (colour?) */ - case 1: - route->rte_name = xstrdup(c); - break; - case 2: break; /* unknown field */ - - } - } - c = csv_lineparse(NULL, ",", "", col++); - } + switch (col) { + case 0: + break; /* unknown field (colour?) */ + case 1: + route->rte_name = xstrdup(c); + break; + case 2: + break; /* unknown field */ + + } + } + c = csv_lineparse(NULL, ",", "", col++); + } } /* main functions */ @@ -368,97 +380,99 @@ parse_rte_info(const char *buff, route_head *route) /* "R" */ static void compegps_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); - input_datum = DATUM_WGS84; + fin = gbfopen(fname, "rb", MYNAME); + input_datum = DATUM_WGS84; } static void compegps_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void compegps_data_read(void) { - char *buff; - int line = 0; - int input_datum; - waypoint *wpt = NULL; - route_head *route = NULL; - route_head *track = NULL; - - while ((buff = gbfgetstr(fin))) - { - char *cin = buff; - char *ctail; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - cin = lrtrim(buff); - if (strlen(cin) == 0) continue; - - ctail = strchr(cin, ' '); - if (ctail == NULL) continue; - ctail = lrtrim(ctail); - - switch(*cin) - { - case 'G': - input_datum = GPS_Lookup_Datum_Index(ctail); - if (input_datum < 0) { - fatal( MYNAME ": Unsupported datum \"%s\"!", ctail); - } - break; - case 'U': - switch(*ctail) - { - case '1': /* lat/lon, that's we want to see */ - break; - case '0': /* UTM not supported yet */ - fatal(MYNAME "Sorry, UTM is not supported yet!\n"); - default: - fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); - } - break; - case 'R': - route = route_head_alloc(); - route_add_head(route); - parse_rte_info(ctail, route); - break; - case 'M': - break; - case 'W': - wpt = parse_wpt(ctail); - if (wpt != NULL) - { - if (route != NULL) - route_add_wpt(route, wpt); - else - waypt_add(wpt); - } - break; - case 'w': - is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); - parse_wpt_info(ctail, wpt); - break; - case 'T': - wpt = parse_trkpt(ctail); - if (wpt != NULL) - { - if (track == NULL) - { - track = route_head_alloc(); - track_add_head(track); - } - track_add_wpt(track, wpt); - } - break; - case 't': - if (track != NULL) - parse_track_info(ctail, track); - break; - } - } + char *buff; + int line = 0; + int input_datum; + waypoint *wpt = NULL; + route_head *route = NULL; + route_head *track = NULL; + + while ((buff = gbfgetstr(fin))) { + char *cin = buff; + char *ctail; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + cin = lrtrim(buff); + if (strlen(cin) == 0) { + continue; + } + + ctail = strchr(cin, ' '); + if (ctail == NULL) { + continue; + } + ctail = lrtrim(ctail); + + switch (*cin) { + case 'G': + input_datum = GPS_Lookup_Datum_Index(ctail); + if (input_datum < 0) { + fatal(MYNAME ": Unsupported datum \"%s\"!", ctail); + } + break; + case 'U': + switch (*ctail) { + case '1': /* lat/lon, that's we want to see */ + break; + case '0': /* UTM not supported yet */ + fatal(MYNAME "Sorry, UTM is not supported yet!\n"); + default: + fatal(MYNAME "Invalid system of coordinates (%s)!\n", cin); + } + break; + case 'R': + route = route_head_alloc(); + route_add_head(route); + parse_rte_info(ctail, route); + break; + case 'M': + break; + case 'W': + wpt = parse_wpt(ctail); + if (wpt != NULL) { + if (route != NULL) { + route_add_wpt(route, wpt); + } else { + waypt_add(wpt); + } + } + break; + case 'w': + is_fatal((wpt == NULL), MYNAME ": No waypoint data before \"%s\"!", cin); + parse_wpt_info(ctail, wpt); + break; + case 'T': + wpt = parse_trkpt(ctail); + if (wpt != NULL) { + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + } + break; + case 't': + if (track != NULL) { + parse_track_info(ctail, track); + } + break; + } + } } /* ----------------------------------------------------------- */ @@ -466,135 +480,144 @@ compegps_data_read(void) static void write_waypt_cb(const waypoint *wpt) { - char *name; - - if (curr_index != target_index ) return; - - name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); - - gbfprintf(fout, "W %s A ", name); - gbfprintf(fout, "%.10f%c%c ", - fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); - gbfprintf(fout, "%.10f%c%c ", - fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); - gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", - (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); - if (wpt->description != NULL) - gbfprintf(fout, " %s", wpt->description); - gbfprintf(fout, "\n"); - - if ((wpt->icon_descr != NULL) || (wpt->wpt_flags.proximity) || \ - (option_icon != NULL)) - { - char *icon = option_icon; - - if (wpt->icon_descr != NULL) icon = (char *) wpt->icon_descr; - - gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", - (icon != NULL) ? icon : "Waypoint", - WAYPT_GET(wpt, proximity, 0)); - } - xfree(name); + char *name; + + if (curr_index != target_index) { + return; + } + + name = (snlen > 0) ? mkshort_from_wpt(sh, wpt) : csv_stringclean(wpt->shortname, " "); + + gbfprintf(fout, "W %s A ", name); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S'); + gbfprintf(fout, "%.10f%c%c ", + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "27-MAR-62 00:00:00 %.6f", + (wpt->altitude != unknown_alt) ? wpt->altitude : 0.0); + if (wpt->description != NULL) { + gbfprintf(fout, " %s", wpt->description); + } + gbfprintf(fout, "\n"); + + if ((wpt->icon_descr != NULL) || (wpt->wpt_flags.proximity) || \ + (option_icon != NULL)) { + char *icon = option_icon; + + if (wpt->icon_descr != NULL) { + icon = (char *) wpt->icon_descr; + } + + gbfprintf(fout, "w %s,0,0.0,16777215,255,1,7,,%.1f\n", + (icon != NULL) ? icon : "Waypoint", + WAYPT_GET(wpt, proximity, 0)); + } + xfree(name); } -static void +static void write_route_hdr_cb(const route_head *rte) { - char *name; - curr_route = (route_head *) rte; - curr_index++; - if (curr_index != target_index) return; - - name = rte->rte_name; - if (name != NULL) - name = csv_stringclean(name, ","); - else - name = xstrdup(" "); - gbfprintf(fout, "R 16711680,%s,1,-1\n", name); - xfree(name); + char *name; + curr_route = (route_head *) rte; + curr_index++; + if (curr_index != target_index) { + return; + } + + name = rte->rte_name; + if (name != NULL) { + name = csv_stringclean(name, ","); + } else { + name = xstrdup(" "); + } + gbfprintf(fout, "R 16711680,%s,1,-1\n", name); + xfree(name); } -static void +static void write_route(void) { - curr_index = 0; - route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); + curr_index = 0; + route_disp_all(write_route_hdr_cb, NULL, write_waypt_cb); } static void write_track_hdr_cb(const route_head *trk) { - track_info_flag = 0; - curr_track = (route_head *) trk; - - curr_index++; - if (curr_index != target_index) return; - - track_info_flag = 1; + track_info_flag = 0; + curr_track = (route_head *) trk; + + curr_index++; + if (curr_index != target_index) { + return; + } + + track_info_flag = 1; } static void write_trkpt_cb(const waypoint *wpt) { - char buff[128]; - struct tm tm; - - if ((curr_index != target_index) || (wpt == NULL)) return; - - buff[0] = '\0'; - - if (wpt->creation_time != 0) - { - tm = *gmtime(&wpt->creation_time); - strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); - strupper(buff); - } - else strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); - - gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", - fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', - fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); - gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", - buff, - wpt->altitude, - 0.0, - 0.0, - 0.0, - 0); - gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", - -1000.0, - -1.0, - -1.0, - -1.0, - -1.0); - if (track_info_flag != 0) - { - track_info_flag = 0; - if (curr_track->rte_name != NULL) - { - char *name; - - name = csv_stringclean(curr_track->rte_name, "|"); - gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); - xfree(name); - } - } + char buff[128]; + struct tm tm; + + if ((curr_index != target_index) || (wpt == NULL)) { + return; + } + + buff[0] = '\0'; + + if (wpt->creation_time != 0) { + tm = *gmtime(&wpt->creation_time); + strftime(buff, sizeof(buff), "%d-%b-%y %H:%M:%S", &tm); + strupper(buff); + } else { + strncpy(buff, "01-JAN-70 00:00:00", sizeof(buff)); + } + + gbfprintf(fout, "T A %.10f%c%c %.10f%c%c ", + fabs(wpt->latitude), 0xBA, (wpt->latitude >= 0) ? 'N' : 'S', + fabs(wpt->longitude), 0xBA, (wpt->longitude >= 0) ? 'E' : 'W'); + gbfprintf(fout, "%s s %.1f %.1f %.1f %.1f %d ", + buff, + wpt->altitude, + 0.0, + 0.0, + 0.0, + 0); + gbfprintf(fout, "%.1f %.1f %.1f %.1f %.1f\n", + -1000.0, + -1.0, + -1.0, + -1.0, + -1.0); + if (track_info_flag != 0) { + track_info_flag = 0; + if (curr_track->rte_name != NULL) { + char *name; + + name = csv_stringclean(curr_track->rte_name, "|"); + gbfprintf(fout, "t 4294967295|%s|-1|-1\n", name); + xfree(name); + } + } } static void write_track(void) { - curr_index = 0; - + curr_index = 0; + // gbfprintf(fout, "L +02:00:00\n"); - track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); - gbfprintf(fout, "F 1234\n"); + track_disp_all(write_track_hdr_cb, NULL, write_trkpt_cb); + gbfprintf(fout, "F 1234\n"); } static void write_waypoints(void) { - waypt_disp_all(write_waypt_cb); + waypt_disp_all(write_waypt_cb); } /* --------------------------------------------------------------------------- */ @@ -602,91 +625,90 @@ write_waypoints(void) static void compegps_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); - sh = mkshort_new_handle(); + fout = gbfopen(fname, "w", MYNAME); + sh = mkshort_new_handle(); } static void compegps_wr_deinit(void) { - mkshort_del_handle(&sh); - gbfclose(fout); + mkshort_del_handle(&sh); + gbfclose(fout); } static void compegps_data_write(void) { - /* because of different file extensions we can only write one GPS data type at time */ - - gbfprintf(fout, "G WGS 84\n"); - gbfprintf(fout, "U 1\n"); - - /* process options */ - - target_index = 1; - if (option_index != NULL) - target_index = atoi(option_index); - - snlen = 0; - if (global_opts.synthesize_shortnames != 0) - { - if (option_snlen != NULL) - snlen = atoi(option_snlen); - else - snlen = SHORT_NAME_LENGTH; - - is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); - - setshort_whitespace_ok(sh, 0); - setshort_length(sh, snlen); - } - - radius = -1; - if (option_radius != 0) - { - radius = atof(option_radius); - is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); - } - - if (option_icon != NULL) - { - if (*option_icon == '\0') - option_icon = NULL; - else if (case_ignore_strcmp(option_icon, "deficon") == 0) - option_icon = NULL; - } - - switch(global_opts.objective) - { - case wptdata: - curr_index = target_index = 0; - write_waypoints(); - break; - case trkdata: - write_track(); - break; - case rtedata: - write_route(); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + /* because of different file extensions we can only write one GPS data type at time */ + + gbfprintf(fout, "G WGS 84\n"); + gbfprintf(fout, "U 1\n"); + + /* process options */ + + target_index = 1; + if (option_index != NULL) { + target_index = atoi(option_index); + } + + snlen = 0; + if (global_opts.synthesize_shortnames != 0) { + if (option_snlen != NULL) { + snlen = atoi(option_snlen); + } else { + snlen = SHORT_NAME_LENGTH; + } + + is_fatal((snlen < 1), MYNAME "Invalid length for generated shortnames!"); + + setshort_whitespace_ok(sh, 0); + setshort_length(sh, snlen); + } + + radius = -1; + if (option_radius != 0) { + radius = atof(option_radius); + is_fatal((radius <= 0.0), MYNAME "Invalid value for radius!"); + } + + if (option_icon != NULL) { + if (*option_icon == '\0') { + option_icon = NULL; + } else if (case_ignore_strcmp(option_icon, "deficon") == 0) { + option_icon = NULL; + } + } + + switch (global_opts.objective) { + case wptdata: + curr_index = target_index = 0; + write_waypoints(); + break; + case trkdata: + write_track(); + break; + case rtedata: + write_route(); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } /* --------------------------------------------------------------------------- */ ff_vecs_t compegps_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - compegps_rd_init, - compegps_wr_init, - compegps_rd_deinit, - compegps_wr_deinit, - compegps_data_read, - compegps_data_write, - NULL, - compegps_args, - CET_CHARSET_MS_ANSI, 1 + ff_type_file, + FF_CAP_RW_ALL, + compegps_rd_init, + compegps_wr_init, + compegps_rd_deinit, + compegps_wr_deinit, + compegps_data_read, + compegps_data_write, + NULL, + compegps_args, + CET_CHARSET_MS_ANSI, 1 }; #endif /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/copilot.c b/gpsbabel/copilot.c index 9405b9723..d0ac4c3fa 100644 --- a/gpsbabel/copilot.c +++ b/gpsbabel/copilot.c @@ -33,32 +33,32 @@ struct record0 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - gbuint32 elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + gbuint32 elevation; /* feet */ }; struct record1 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - pdb_double elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ }; struct record3 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_double magvar; /* magnetic variation in degrees, neg = east */ - pdb_double elevation; /* feet */ - char flags; /* flags */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_double magvar; /* magnetic variation in degrees, neg = east */ + pdb_double elevation; /* feet */ + char flags; /* flags */ }; struct record4 { - pdb_double latitude; /* PDB double format, */ - pdb_double longitude; /* similarly, neg = east */ - pdb_float magvar; /* magnetic variation in degrees, neg = east */ - pdb_float elevation; /* feet */ + pdb_double latitude; /* PDB double format, */ + pdb_double longitude; /* similarly, neg = east */ + pdb_float magvar; /* magnetic variation in degrees, neg = east */ + pdb_float elevation; /* feet */ }; static pdbfile *file_in, *file_out; @@ -68,27 +68,27 @@ static int ct; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); + pdb_close(file_out); } static waypoint* @@ -101,9 +101,9 @@ read_version0(void *data) wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = FEET_TO_METERS(be_read32(&rec->elevation)); vdata = (char *) data + sizeof(*rec); @@ -129,11 +129,11 @@ read_version1(void *data) wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_double(&rec->elevation)); + FEET_TO_METERS(pdb_read_double(&rec->elevation)); vdata = (char *) data + sizeof(*rec); @@ -158,11 +158,11 @@ read_version3(void *data) wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_double(&rec->elevation)); + FEET_TO_METERS(pdb_read_double(&rec->elevation)); vdata = (char *) data + sizeof(*rec); @@ -187,11 +187,11 @@ read_version4(void *data) wpt_tmp = waypt_new(); wpt_tmp->longitude = - DEG(-pdb_read_double(&rec->longitude)); + DEG(-pdb_read_double(&rec->longitude)); wpt_tmp->latitude = - DEG(pdb_read_double(&rec->latitude)); + DEG(pdb_read_double(&rec->latitude)); wpt_tmp->altitude = - FEET_TO_METERS(pdb_read_float(&rec->elevation)); + FEET_TO_METERS(pdb_read_float(&rec->elevation)); vdata = (char *) data + sizeof(*rec); @@ -209,115 +209,111 @@ read_version4(void *data) static void data_read(void) { - pdbrec_t *pdb_rec; - - if ((file_in->creator != GXPU_CREATOR && file_in->creator != AP_P_CREATOR) || - (file_in->type != wayp_TYPE && file_in->type != swpu_TYPE && - file_in->type != wayu_TYPE)) { - fatal(MYNAME ": Not a CoPilot file.\n"); - } - if (file_in->version > 4) { - fatal(MYNAME ": %d is not a known version.\n", file_in->version); - } - - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - - switch (file_in->version) - { - case 0: - wpt_tmp = read_version0(pdb_rec->data); - break; - case 1: - case 2: - wpt_tmp = read_version1(pdb_rec->data); - break; - case 3: - wpt_tmp = read_version3(pdb_rec->data); - break; - case 4: - wpt_tmp = read_version4(pdb_rec->data); - break; - default: - fatal(MYNAME ": Unknown version %d.\n", file_in->version); - } - waypt_add(wpt_tmp); - } + pdbrec_t *pdb_rec; + + if ((file_in->creator != GXPU_CREATOR && file_in->creator != AP_P_CREATOR) || + (file_in->type != wayp_TYPE && file_in->type != swpu_TYPE && + file_in->type != wayu_TYPE)) { + fatal(MYNAME ": Not a CoPilot file.\n"); + } + if (file_in->version > 4) { + fatal(MYNAME ": %d is not a known version.\n", file_in->version); + } + + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + + switch (file_in->version) { + case 0: + wpt_tmp = read_version0(pdb_rec->data); + break; + case 1: + case 2: + wpt_tmp = read_version1(pdb_rec->data); + break; + case 3: + wpt_tmp = read_version3(pdb_rec->data); + break; + case 4: + wpt_tmp = read_version4(pdb_rec->data); + break; + default: + fatal(MYNAME ": Unknown version %d.\n", file_in->version); + } + waypt_add(wpt_tmp); + } } static void copilot_writewpt(const waypoint *wpt) { - struct record4 *rec; - char *vdata; - - rec = xcalloc(sizeof(*rec)+1141,1); - - pdb_write_double(&rec->latitude, RAD(wpt->latitude)); - pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); - pdb_write_float(&rec->magvar, 0); - pdb_write_float(&rec->elevation, - METERS_TO_FEET(wpt->altitude)); - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->shortname ) { - strncpy( vdata, wpt->shortname, 10 ); - vdata[9] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 100 ); - vdata[99] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if ( wpt->notes ) { - strncpy( vdata, wpt->notes, 1000 ); - vdata[999] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record4 *rec; + char *vdata; + + rec = xcalloc(sizeof(*rec)+1141,1); + + pdb_write_double(&rec->latitude, RAD(wpt->latitude)); + pdb_write_double(&rec->longitude, RAD(-wpt->longitude)); + pdb_write_float(&rec->magvar, 0); + pdb_write_float(&rec->elevation, + METERS_TO_FEET(wpt->altitude)); + + vdata = (char *)rec + sizeof(*rec); + if (wpt->shortname) { + strncpy(vdata, wpt->shortname, 10); + vdata[9] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 100); + vdata[99] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->notes) { + strncpy(vdata, wpt->notes, 1000); + vdata[999] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); } static void data_write(void) { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = wayp_TYPE; - file_out->creator = GXPU_CREATOR; - file_out->version = 4; - - waypt_disp_all(copilot_writewpt); + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = wayp_TYPE; + file_out->creator = GXPU_CREATOR; + file_out->version = 4; + + waypt_disp_all(copilot_writewpt); } ff_vecs_t copilot_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/coto.c b/gpsbabel/coto.c index eff0692e7..a4c3e705a 100644 --- a/gpsbabel/coto.c +++ b/gpsbabel/coto.c @@ -2,7 +2,7 @@ Read and write cotoGPS files. Copyright (C) 2005 Tobias Minich, - + Based on the Cetus I/O Filter, Copyright (C) 2002 Robert Lipe, robertlipe@usa.net @@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA - + */ @@ -42,39 +42,39 @@ #define CATEGORY_NAME_LENGTH 16 typedef enum { - cotofixNone = 0, /* No Fix or Warning */ - cotofixReserved = 1, /* Shouldn't occur*/ - cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ - cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ - cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ + cotofixNone = 0, /* No Fix or Warning */ + cotofixReserved = 1, /* Shouldn't occur*/ + cotofix2D = 2, /* retrieved from a GPS with a 2D fix */ + cotofix3D = 3, /* retrieved from a GPS with a 3D fix */ + cotofixDGPS = 4, /* retrieved from a GPS with a DGPS signal */ } fix_quality; struct record_track { - pdb_double latitude; /* radians, s=negative */ - pdb_double longitude; /* same as lat; e=negative */ - pdb_double distance; /* Distance to thel last point; discarded since it's calculated by gpsbabel on write */ - pdb_double arc; /* Course, unknown dimension */ - pdb_double x,y; /* Internal virtual coordinates used for drawing the track on the Palm */ + pdb_double latitude; /* radians, s=negative */ + pdb_double longitude; /* same as lat; e=negative */ + pdb_double distance; /* Distance to thel last point; discarded since it's calculated by gpsbabel on write */ + pdb_double arc; /* Course, unknown dimension */ + pdb_double x,y; /* Internal virtual coordinates used for drawing the track on the Palm */ - gbuint16 alt; /* Altitude */ + gbuint16 alt; /* Altitude */ - /* accuracy and precision information for use where applicable */ - gbuint16 hdop; /* _dop * 10 */ - gbuint16 vdop; - gbuint16 pdop; - gbuint8 sat_tracked; - gbuint8 fix_quality; + /* accuracy and precision information for use where applicable */ + gbuint16 hdop; /* _dop * 10 */ + gbuint16 vdop; + gbuint16 pdop; + gbuint8 sat_tracked; + gbuint8 fix_quality; - gbuint16 speed; /* *10 */ - gbuint32 time; /* Palm Time */ + gbuint16 speed; /* *10 */ + gbuint32 time; /* Palm Time */ }; struct record_wpt { - char lon[8]; - char lat[8]; - char name[MAX_MARKER_NAME_LENGTH]; - char notes[1]; + char lon[8]; + char lat[8]; + char name[MAX_MARKER_NAME_LENGTH]; + char notes[1]; }; @@ -83,11 +83,11 @@ struct record_wpt { typedef char appinfo_category[16]; typedef struct appinfo { - gbuint8 U0; - gbuint8 renamedCategories; - appinfo_category categories[CATEGORY_NAME_LENGTH]; - gbuint8 ids[16]; - gbuint8 maxid; + gbuint8 U0; + gbuint8 renamedCategories; + appinfo_category categories[CATEGORY_NAME_LENGTH]; + gbuint8 ids[16]; + gbuint8 maxid; } appinfo_t; #define APPINFO_SIZE sizeof(appinfo_t) @@ -103,38 +103,42 @@ static char *internals = NULL; static arglist_t coto_args[] = { - {"zerocat", &zerocat, "Name of the 'unassigned' category", NULL, - ARGTYPE_STRING, ARG_NOMINMAX }, - {"internals", &internals, "Export some internal stuff to notes", NULL, - ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "zerocat", &zerocat, "Name of the 'unassigned' category", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "internals", &internals, "Export some internal stuff to notes", NULL, + ARGTYPE_STRING | ARGTYPE_HIDDEN, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); - in_fname = fname; + file_in = pdb_open(fname, MYNAME); + in_fname = fname; } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); + pdb_close(file_out); } /* helpers */ @@ -142,288 +146,288 @@ wr_deinit(void) static char * coto_get_icon_descr(int category, const appinfo_t *app) { - char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; - if ((category >= 0) && (category < 16)) - { - if ((category > 0) && (app->categories[category][0] == '\0')) - category = 0; - - strncpy(buff, app->categories[category], sizeof(buff) - 1); - if (buff[0] == '\0') - return NULL; - } - return xstrdup(buff); + char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned"; + if ((category >= 0) && (category < 16)) { + if ((category > 0) && (app->categories[category][0] == '\0')) { + category = 0; + } + + strncpy(buff, app->categories[category], sizeof(buff) - 1); + if (buff[0] == '\0') { + return NULL; + } + } + return xstrdup(buff); } static void coto_track_read(void) { - struct record_track *rec; - pdbrec_t *pdb_rec; - route_head *trk_head; - char *track_name; - - if (strncmp(file_in->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) - // Use database name if not default - track_name = xstrndup(file_in->name, PDB_DBNAMELEN); - else { - // Use filename for new track title - const char *fnametmp = strrchr(in_fname, '/'); - if (fnametmp == NULL) - fnametmp = strrchr(in_fname, '\\'); - if (fnametmp) - fnametmp++; - else - fnametmp = in_fname; - if (strrchr(fnametmp, '.') != NULL) - track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); - else - track_name = xstrdup(fnametmp); - } - - trk_head = route_head_alloc(); - track_add_head(trk_head); - - trk_head->rte_name = track_name; - - for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - rec = (struct record_track *) pdb_rec->data; - - wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); - wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); - - // It's not the course, so leave it out for now - // WAYPT_SET(wpt_tmp, course, pdb_read_double(&rec->arc)); - wpt_tmp->altitude = be_read16(&rec->alt); - - if (internals) - { - // Parse the option as xcsv delimiter - const char *inter = xcsv_get_char_from_constant_table(internals); - char temp[256]; - snprintf(temp, sizeof(temp), "%.20f%s%.20f%s%.20f%s%.20f", pdb_read_double(&rec->distance), inter, - pdb_read_double(&rec->arc), inter, pdb_read_double(&rec->x), inter, pdb_read_double(&rec->y)); - wpt_tmp->notes = xstrdup(temp); - } - - wpt_tmp->pdop = be_read16(&rec->pdop)/10.0; - wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; - wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; - wpt_tmp->sat = rec->sat_tracked; - switch (rec->fix_quality) - { - case cotofixNone: - wpt_tmp->fix = fix_none; - break; - case cotofixReserved: - wpt_tmp->fix = fix_unknown; - break; - case cotofix2D: - wpt_tmp->fix = fix_2d; - break; - case cotofix3D: - wpt_tmp->fix = fix_3d; - break; - case cotofixDGPS: - wpt_tmp->fix = fix_dgps; - break; - } - WAYPT_SET(wpt_tmp, speed, be_read16(&rec->speed)/10.0); - rec->time = be_read32(&rec->time); - if (rec->time != 0) - { - rec->time -= 2082844800U; - wpt_tmp->creation_time = rec->time; - } - track_add_wpt(trk_head, wpt_tmp); - } + struct record_track *rec; + pdbrec_t *pdb_rec; + route_head *trk_head; + char *track_name; + + if (strncmp(file_in->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0) + // Use database name if not default + { + track_name = xstrndup(file_in->name, PDB_DBNAMELEN); + } else { + // Use filename for new track title + const char *fnametmp = strrchr(in_fname, '/'); + if (fnametmp == NULL) { + fnametmp = strrchr(in_fname, '\\'); + } + if (fnametmp) { + fnametmp++; + } else { + fnametmp = in_fname; + } + if (strrchr(fnametmp, '.') != NULL) { + track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp); + } else { + track_name = xstrdup(fnametmp); + } + } + + trk_head = route_head_alloc(); + track_add_head(trk_head); + + trk_head->rte_name = track_name; + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + rec = (struct record_track *) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->longitude)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->latitude)); + + // It's not the course, so leave it out for now + // WAYPT_SET(wpt_tmp, course, pdb_read_double(&rec->arc)); + wpt_tmp->altitude = be_read16(&rec->alt); + + if (internals) { + // Parse the option as xcsv delimiter + const char *inter = xcsv_get_char_from_constant_table(internals); + char temp[256]; + snprintf(temp, sizeof(temp), "%.20f%s%.20f%s%.20f%s%.20f", pdb_read_double(&rec->distance), inter, + pdb_read_double(&rec->arc), inter, pdb_read_double(&rec->x), inter, pdb_read_double(&rec->y)); + wpt_tmp->notes = xstrdup(temp); + } + + wpt_tmp->pdop = be_read16(&rec->pdop)/10.0; + wpt_tmp->hdop = be_read16(&rec->hdop)/10.0; + wpt_tmp->vdop = be_read16(&rec->vdop)/10.0; + wpt_tmp->sat = rec->sat_tracked; + switch (rec->fix_quality) { + case cotofixNone: + wpt_tmp->fix = fix_none; + break; + case cotofixReserved: + wpt_tmp->fix = fix_unknown; + break; + case cotofix2D: + wpt_tmp->fix = fix_2d; + break; + case cotofix3D: + wpt_tmp->fix = fix_3d; + break; + case cotofixDGPS: + wpt_tmp->fix = fix_dgps; + break; + } + WAYPT_SET(wpt_tmp, speed, be_read16(&rec->speed)/10.0); + rec->time = be_read32(&rec->time); + if (rec->time != 0) { + rec->time -= 2082844800U; + wpt_tmp->creation_time = rec->time; + } + track_add_wpt(trk_head, wpt_tmp); + } } static void coto_wpt_read(void) { - struct record_wpt *rec; - pdbrec_t *pdb_rec; - appinfo_t *app; - app = (struct appinfo *) file_in->appinfo; - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt_tmp; - char *c; - - wpt_tmp = waypt_new(); - - rec = (struct record_wpt *) pdb_rec->data; - - wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); - wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); - - wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); - - wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); - if (wpt_tmp->icon_descr) - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - - if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ - wpt_tmp->notes = xstrdup(c + 8); - if (c != rec->notes) { - wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); - } - } else { - wpt_tmp->notes = xstrdup(rec->notes); - } - - waypt_add(wpt_tmp); - } + struct record_wpt *rec; + pdbrec_t *pdb_rec; + appinfo_t *app; + app = (struct appinfo *) file_in->appinfo; + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + char *c; + + wpt_tmp = waypt_new(); + + rec = (struct record_wpt *) pdb_rec->data; + + wpt_tmp->longitude = DEG(-pdb_read_double(&rec->lon)); + wpt_tmp->latitude = DEG(pdb_read_double(&rec->lat)); + + wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name)); + + wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app); + if (wpt_tmp->icon_descr) { + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } + + if ((c = strstr(rec->notes, "\nNotes:\n"))) { /* remove our contruct */ + wpt_tmp->notes = xstrdup(c + 8); + if (c != rec->notes) { + wpt_tmp->description = xstrndup(rec->notes, c - rec->notes); + } + } else { + wpt_tmp->notes = xstrdup(rec->notes); + } + + waypt_add(wpt_tmp); + } } static void data_read(void) { - if ((file_in->creator != MYCREATOR) || ((file_in->type != MYTYPETRACK) && (file_in->type != MYTYPEWPT))) { - warning("Creator %x Type %x Version %d\n", (int) file_in->creator, (int) file_in->type, (int) file_in->version); - fatal(MYNAME ": Not a cotoGPS file.\n"); - } - - is_fatal((file_in->version > 0), - MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); - - switch(file_in->type) - { - case MYTYPETRACK: - coto_track_read(); - break; - case MYTYPEWPT: - coto_wpt_read(); - break; - } + if ((file_in->creator != MYCREATOR) || ((file_in->type != MYTYPETRACK) && (file_in->type != MYTYPEWPT))) { + warning("Creator %x Type %x Version %d\n", (int) file_in->creator, (int) file_in->type, (int) file_in->version); + fatal(MYNAME ": Not a cotoGPS file.\n"); + } + + is_fatal((file_in->version > 0), + MYNAME ": This file is from an unsupported newer version of cotoGPS. It may be supported in a newer version of GPSBabel.\n"); + + switch (file_in->type) { + case MYTYPETRACK: + coto_track_read(); + break; + case MYTYPEWPT: + coto_wpt_read(); + break; + } } static void coto_prepare_wpt_write(void) { - struct appinfo *ai; - - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->type = MYTYPEWPT; - file_out->creator = MYCREATOR; - file_out->version = 0; - - strncpy(file_out->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); - - file_out->appinfo_len = APPINFO_SIZE; - file_out->appinfo = calloc(APPINFO_SIZE,1); - - ai = (struct appinfo *) file_out->appinfo; - be_write16(&ai->renamedCategories, 31); // Don't ask me why... - if (zerocat) - strncpy(ai->categories[0], zerocat, 16); - else - strncpy(ai->categories[0], "Not Assigned", 16); // FIXME: Replace by default English Palm 'Not Assigned' category - + struct appinfo *ai; + + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->type = MYTYPEWPT; + file_out->creator = MYCREATOR; + file_out->version = 0; + + strncpy(file_out->name, "cotoGPS MarkerDB", PDB_DBNAMELEN); + + file_out->appinfo_len = APPINFO_SIZE; + file_out->appinfo = calloc(APPINFO_SIZE,1); + + ai = (struct appinfo *) file_out->appinfo; + be_write16(&ai->renamedCategories, 31); // Don't ask me why... + if (zerocat) { + strncpy(ai->categories[0], zerocat, 16); + } else { + strncpy(ai->categories[0], "Not Assigned", 16); // FIXME: Replace by default English Palm 'Not Assigned' category + } + } static void coto_wpt_write(const waypoint *wpt) { - struct record_wpt *rec; - struct appinfo *ai = (struct appinfo *) file_out->appinfo; - char *notes = NULL; - char *shortname = NULL; - int size; - gbuint8 cat = 0; - int i; - - mkshort_wr_handle = mkshort_new_handle(); - setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); - setshort_whitespace_ok(mkshort_wr_handle, 1); - - if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) - shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); - else - shortname = xstrdup(wpt->shortname); - - if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) - { - if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) - { - notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); - sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); - } else { - notes = xstrdup(wpt->description); - } - } - else if (wpt->notes != NULL) - { - notes = xstrdup(wpt->notes); - } - - size = sizeof(*rec); - if (notes != NULL) - size += strlen(notes); - rec = xcalloc(size, 1); - - pdb_write_double(&rec->lon, RAD(-wpt->longitude)); - pdb_write_double(&rec->lat, RAD(wpt->latitude)); - strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); - - if (notes) - { - strcpy(rec->notes, notes); - xfree(notes); - } - - if (wpt->icon_descr) - { - for(i = 1; i < 16; i++) - if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) {cat=i; break;} - if (!cat) { - // We have a new one - if (ai->maxid<15) { - i = ++ai->maxid; - snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); - cat = ai->ids[i] = i; - } else { - // We're full! - warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); - } - } - } - - pdb_write_rec(file_out, 0, cat, ct++, (const gbuint8 *)rec, size); - - xfree(shortname); - xfree(rec); - - mkshort_del_handle(&mkshort_wr_handle); + struct record_wpt *rec; + struct appinfo *ai = (struct appinfo *) file_out->appinfo; + char *notes = NULL; + char *shortname = NULL; + int size; + gbuint8 cat = 0; + int i; + + mkshort_wr_handle = mkshort_new_handle(); + setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH); + setshort_whitespace_ok(mkshort_wr_handle, 1); + + if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL)) { + shortname = mkshort_from_wpt(mkshort_wr_handle, wpt); + } else { + shortname = xstrdup(wpt->shortname); + } + + if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) { + if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) { + notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1); + sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes); + } else { + notes = xstrdup(wpt->description); + } + } else if (wpt->notes != NULL) { + notes = xstrdup(wpt->notes); + } + + size = sizeof(*rec); + if (notes != NULL) { + size += strlen(notes); + } + rec = xcalloc(size, 1); + + pdb_write_double(&rec->lon, RAD(-wpt->longitude)); + pdb_write_double(&rec->lat, RAD(wpt->latitude)); + strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH); + + if (notes) { + strcpy(rec->notes, notes); + xfree(notes); + } + + if (wpt->icon_descr) { + for (i = 1; i < 16; i++) + if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) { + cat=i; + break; + } + if (!cat) { + // We have a new one + if (ai->maxid<15) { + i = ++ai->maxid; + snprintf(ai->categories[i], 16, "%s", wpt->icon_descr); + cat = ai->ids[i] = i; + } else { + // We're full! + warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned"); + } + } + } + + pdb_write_rec(file_out, 0, cat, ct++, (const gbuint8 *)rec, size); + + xfree(shortname); + xfree(rec); + + mkshort_del_handle(&mkshort_wr_handle); } static void data_write(void) { - coto_prepare_wpt_write(); - waypt_disp_all(coto_wpt_write); + coto_prepare_wpt_write(); + waypt_disp_all(coto_wpt_write); } ff_vecs_t coto_vecs = { - ff_type_file, - {ff_cap_read|ff_cap_write, ff_cap_read, ff_cap_none}, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - coto_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + {ff_cap_read|ff_cap_write, ff_cap_read, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + coto_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/cst.c b/gpsbabel/cst.c index e58421b12..ad59bcda9 100644 --- a/gpsbabel/cst.c +++ b/gpsbabel/cst.c @@ -30,7 +30,7 @@ #define MYNAME "cst" #undef CST_DEBUG - + #define CST_UNKNOWN 0 #define CST_HEADER 1 #define CST_ROUTE 2 @@ -46,7 +46,7 @@ static route_head *temp_route; static arglist_t cst_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* helpers */ @@ -54,83 +54,85 @@ arglist_t cst_args[] = { static void cst_add_wpt(const route_head *track, waypoint *wpt) { - if ((wpt == NULL) || (track == NULL)) return; - - if (wpt->shortname != NULL) - { - waypt_add(waypt_dupe(wpt)); - if (wpt->url != NULL) - { - xfree(wpt->url); - wpt->url = NULL; - } - - if (temp_route == NULL) - { - temp_route = route_head_alloc(); - route_add_head(temp_route); - } - route_add_wpt(temp_route, waypt_dupe(wpt)); - } - track_add_wpt((route_head *)track, (waypoint *)wpt); + if ((wpt == NULL) || (track == NULL)) { + return; + } + + if (wpt->shortname != NULL) { + waypt_add(waypt_dupe(wpt)); + if (wpt->url != NULL) { + xfree(wpt->url); + wpt->url = NULL; + } + + if (temp_route == NULL) { + temp_route = route_head_alloc(); + route_add_head(temp_route); + } + route_add_wpt(temp_route, waypt_dupe(wpt)); + } + track_add_wpt((route_head *)track, (waypoint *)wpt); } static char * cst_make_url(char *str) { - int len = strlen(str); - char *res; - - if (len < 3) return NULL; - - if (strstr(str, "://") > str) - return xstrdup(str); - else if (strstr(str, ":\\") == str+1) /* DOS 0.01++ file format */ - { - res = xstrdup("file://*:"); - res[7] = *str++; - res[8] = *str++; - res = xstrappend(res, str); - { - char *c; - int i; - - c = res; /* replace all backslashes with a slash */ - while ((c = strchr(c, '\\'))) *c++ = '/'; - - c = res; /* enumerate number of spaces within filename */ - i = 0; - while ((c = strchr(c, ' '))) - { - c++; - i++; - } - - if (i > 0) /* .. and replace them with "%20" */ - { - char *src, *dest, *last; - - last = src = res; - res = dest = xcalloc(strlen(src) + (2*i) + 1, 1); - while ((c = strchr(src, ' '))) - { - if (c != src) strncpy(dest, src, c - src); - strcat(dest, "%20"); - c++; - src = c; - dest = res + strlen(res); - } - while (*src != '\0') - *dest++ = *src++; - xfree(last); - } - } - return res; - - } - else - return NULL; - + int len = strlen(str); + char *res; + + if (len < 3) { + return NULL; + } + + if (strstr(str, "://") > str) { + return xstrdup(str); + } else if (strstr(str, ":\\") == str+1) { /* DOS 0.01++ file format */ + res = xstrdup("file://*:"); + res[7] = *str++; + res[8] = *str++; + res = xstrappend(res, str); + { + char *c; + int i; + + c = res; /* replace all backslashes with a slash */ + while ((c = strchr(c, '\\'))) { + *c++ = '/'; + } + + c = res; /* enumerate number of spaces within filename */ + i = 0; + while ((c = strchr(c, ' '))) { + c++; + i++; + } + + if (i > 0) { /* .. and replace them with "%20" */ + char *src, *dest, *last; + + last = src = res; + res = dest = xcalloc(strlen(src) + (2*i) + 1, 1); + while ((c = strchr(src, ' '))) { + if (c != src) { + strncpy(dest, src, c - src); + } + strcat(dest, "%20"); + c++; + src = c; + dest = res + strlen(res); + } + while (*src != '\0') { + *dest++ = *src++; + } + xfree(last); + } + } + return res; + + } else { + return NULL; + } + } /* --------------------------------------------------------------------------- */ @@ -138,14 +140,14 @@ cst_make_url(char *str) static void cst_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); - temp_route = NULL; + fin = gbfopen(fname, "rb", MYNAME); + temp_route = NULL; } static void cst_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } /* --------------------------------------------------------------------------- */ @@ -153,185 +155,192 @@ cst_rd_deinit(void) static void cst_data_read(void) { - char *buff; - int line = 0; - int data_lines = -1; - int line_of_count = -1; - int valid = 0; - int section = CST_UNKNOWN; - int cst_version; - int cst_points = -1; - route_head *track = NULL; - waypoint *wpt = NULL; - - while ((buff = gbfgetstr(fin))) - { - char *cin = buff; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - cin = lrtrim(buff); - if (strlen(cin) == 0) continue; - - if (strncmp(cin, "; ", 2) == 0) continue; - if (*cin == '#') - { - section = CST_UNKNOWN; - if (strcmp(cin+1, "ROUTE") == 0) section = CST_ROUTE; - else if (strcmp(cin+1, "VERSION") == 0) section = CST_VERSION; - else if (strcmp(cin+1, "NOTES") == 0) section = CST_NOTES; - else if (strcmp(cin+1, "REFERENCE") == 0) section = CST_REFERENCE; - else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) - { - section = CST_HEADER; - valid = 1; - } - else - warning(MYNAME ": Unknown section \"%s\".\n", cin+1); - - continue; - } - - if (valid == 0) continue; - - switch(section) - { - case CST_ROUTE: - if (*cin == ';') - { - int data = 0; - - if (*(cin+1) != '\xA4') continue; - - if (strncmp(cin + 2, "bitmap", 6) == 0) - { - cin = lrtrim(cin + 8); - if (*cin != '\0') - wpt->url = cst_make_url(cin); - } - - while ((buff = gbfgetstr(fin))) - { - line++; - cin = lrtrim(buff); - - if (strcmp(cin + 2, "note") == 0) - { - buff = gbfgetstr(fin); - if (buff == NULL) buff = ""; - line++; - cin = lrtrim(buff); - if (*cin != '\0') - wpt->notes = xstrdup(cin); - } - else if (strcmp(cin + 2, "end") == 0) - { - data = 1; - break; - } - } - if (data == 0) - fatal(MYNAME ": Unexpected end of file!\n"); - } - else - { - int interp, i; - char name[256]; - char *pow; - - if (data_lines < 0) - { - if ((2 != sscanf(cin, "%d %128s", &i, name)) || - (case_ignore_strcmp(name, "Points") != 0)) - fatal(MYNAME "-line %d: Number of points expected!\n", line); - line_of_count = line; - data_lines = 0; - cst_points = i; - continue; - } - - cst_add_wpt(track, wpt); - wpt = NULL; - - - wpt = waypt_new(); - - if (5 != sscanf(cin, "%lf %lf %lf %d %s", - &wpt->longitude, - &wpt->latitude, - &wpt->altitude, - &interp, name)) - { - fatal(MYNAME ": Could not interprete line %d!\n", line); - } - - data_lines++; - - if (strcmp(name, "1") == 0) - { - track = route_head_alloc(); - track_add_head(track); - } - else if (strncmp(name, "NAME:", 5) == 0) - wpt->shortname = xstrdup(((char *)&name) + 5); - - pow = strrchr(cin, '^'); - if (pow != NULL) - { - struct tm tm; - - pow = lrtrim(++pow); - strptime(pow, "%Y %m %d %H:%M:%S", &tm); - - wpt->creation_time = mkgmtime(&tm); - } - wpt->latitude /= 100000.0; - wpt->longitude /= 100000.0; - } - break; - - - case CST_VERSION: - cst_version = atoi(cin); - if (cst_version != 40) - warning(MYNAME ": Not tested with file version %d.\n", cst_version); - break; - - case CST_REFERENCE: - if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) - fatal(MYNAME ": Unsupported datum (%s)!\n", cin); - break; - - case CST_HEADER: - case CST_NOTES: - break; - } - } - cst_add_wpt(track, wpt); - wpt = NULL; - - if ((cst_points >= 0) && (data_lines != cst_points)) - warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); + char *buff; + int line = 0; + int data_lines = -1; + int line_of_count = -1; + int valid = 0; + int section = CST_UNKNOWN; + int cst_version; + int cst_points = -1; + route_head *track = NULL; + waypoint *wpt = NULL; + + while ((buff = gbfgetstr(fin))) { + char *cin = buff; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + cin = lrtrim(buff); + if (strlen(cin) == 0) { + continue; + } + + if (strncmp(cin, "; ", 2) == 0) { + continue; + } + if (*cin == '#') { + section = CST_UNKNOWN; + if (strcmp(cin+1, "ROUTE") == 0) { + section = CST_ROUTE; + } else if (strcmp(cin+1, "VERSION") == 0) { + section = CST_VERSION; + } else if (strcmp(cin+1, "NOTES") == 0) { + section = CST_NOTES; + } else if (strcmp(cin+1, "REFERENCE") == 0) { + section = CST_REFERENCE; + } else if (strcmp(cin+1, "CARTE SUR TABLE DATA FILE") == 0) { + section = CST_HEADER; + valid = 1; + } else { + warning(MYNAME ": Unknown section \"%s\".\n", cin+1); + } + + continue; + } + + if (valid == 0) { + continue; + } + + switch (section) { + case CST_ROUTE: + if (*cin == ';') { + int data = 0; + + if (*(cin+1) != '\xA4') { + continue; + } + + if (strncmp(cin + 2, "bitmap", 6) == 0) { + cin = lrtrim(cin + 8); + if (*cin != '\0') { + wpt->url = cst_make_url(cin); + } + } + + while ((buff = gbfgetstr(fin))) { + line++; + cin = lrtrim(buff); + + if (strcmp(cin + 2, "note") == 0) { + buff = gbfgetstr(fin); + if (buff == NULL) { + buff = ""; + } + line++; + cin = lrtrim(buff); + if (*cin != '\0') { + wpt->notes = xstrdup(cin); + } + } else if (strcmp(cin + 2, "end") == 0) { + data = 1; + break; + } + } + if (data == 0) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + } else { + int interp, i; + char name[256]; + char *pow; + + if (data_lines < 0) { + if ((2 != sscanf(cin, "%d %128s", &i, name)) || + (case_ignore_strcmp(name, "Points") != 0)) { + fatal(MYNAME "-line %d: Number of points expected!\n", line); + } + line_of_count = line; + data_lines = 0; + cst_points = i; + continue; + } + + cst_add_wpt(track, wpt); + wpt = NULL; + + + wpt = waypt_new(); + + if (5 != sscanf(cin, "%lf %lf %lf %d %s", + &wpt->longitude, + &wpt->latitude, + &wpt->altitude, + &interp, name)) { + fatal(MYNAME ": Could not interprete line %d!\n", line); + } + + data_lines++; + + if (strcmp(name, "1") == 0) { + track = route_head_alloc(); + track_add_head(track); + } else if (strncmp(name, "NAME:", 5) == 0) { + wpt->shortname = xstrdup(((char *)&name) + 5); + } + + pow = strrchr(cin, '^'); + if (pow != NULL) { + struct tm tm; + + pow = lrtrim(++pow); + strptime(pow, "%Y %m %d %H:%M:%S", &tm); + + wpt->creation_time = mkgmtime(&tm); + } + wpt->latitude /= 100000.0; + wpt->longitude /= 100000.0; + } + break; + + + case CST_VERSION: + cst_version = atoi(cin); + if (cst_version != 40) { + warning(MYNAME ": Not tested with file version %d.\n", cst_version); + } + break; + + case CST_REFERENCE: + if ((strncmp(cin, "DATUM ", 6) == 0) && (strstr(cin, "WGS 84") == NULL)) { + fatal(MYNAME ": Unsupported datum (%s)!\n", cin); + } + break; + + case CST_HEADER: + case CST_NOTES: + break; + } + } + cst_add_wpt(track, wpt); + wpt = NULL; + + if ((cst_points >= 0) && (data_lines != cst_points)) { + warning(MYNAME ": Loaded %d point(s), but line %d says %d!\n", data_lines, line_of_count, cst_points); + } } #if 0 static void cst_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void cst_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } -static void +static void cst_route_hdr(const route_head *rte) { } -static void +static void cst_route_tlr(const route_head *rte) { } @@ -348,15 +357,15 @@ cst_data_write(void) #endif ff_vecs_t cst_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_read }, - cst_rd_init, - NULL, /* cst_wr_init, */ - cst_rd_deinit, - NULL, /* cst_wr_deinit, */ - cst_data_read, - NULL, /* cst_data_write, */ - NULL, - cst_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + cst_rd_init, + NULL, /* cst_wr_init, */ + cst_rd_deinit, + NULL, /* cst_wr_deinit, */ + cst_data_read, + NULL, /* cst_data_write, */ + NULL, + cst_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/csv_util.c b/gpsbabel/csv_util.c index 626066b67..b0159afbf 100644 --- a/gpsbabel/csv_util.c +++ b/gpsbabel/csv_util.c @@ -52,93 +52,93 @@ * that has GNU gperf on it. */ typedef enum { - XT_unused = 0, - XT_ALT_FEET, - XT_ALT_METERS, - XT_ANYNAME, - XT_CADENCE, - XT_CITY, - XT_CONSTANT, - XT_COUNTRY, - XT_DESCRIPTION, - XT_EXCEL_TIME, - XT_FACILITY, - XT_FILENAME, - XT_FORMAT, - XT_GEOCACHE_CONTAINER, - XT_GEOCACHE_DIFF, - XT_GEOCACHE_HINT, - XT_GEOCACHE_LAST_FOUND, - XT_GEOCACHE_PLACER, - XT_GEOCACHE_TERR, - XT_GEOCACHE_TYPE, - XT_GEOCACHE_ISAVAILABLE, - XT_GEOCACHE_ISARCHIVED, - XT_GMT_TIME, - XT_GPS_FIX, - XT_GPS_HDOP, - XT_GPS_PDOP, - XT_GPS_SAT, - XT_GPS_VDOP, - XT_HEART_RATE, - XT_HMSG_TIME, - XT_HMSL_TIME, - XT_ICON_DESCR, - XT_IGNORE, - XT_INDEX, - XT_ISO_TIME, - XT_ISO_TIME_MS, - XT_LATLON_HUMAN_READABLE, - XT_LAT_DECIMAL, - XT_LAT_DECIMALDIR, - XT_LAT_DIR, - XT_LAT_DIRDECIMAL, - XT_LAT_HUMAN_READABLE, - XT_LAT_INT32DEG, - XT_LAT_DDMMDIR, - XT_LAT_NMEA, - XT_LOCAL_TIME, - XT_LON_DECIMAL, - XT_LON_DECIMALDIR, - XT_LON_DIR, - XT_LON_DIRDECIMAL, - XT_LON_HUMAN_READABLE, - XT_LON_INT32DEG, - XT_LON_DDMMDIR, - XT_LON_NMEA, - XT_MAP_EN_BNG, - XT_NOTES, - XT_NET_TIME, - XT_PATH_COURSE, - XT_PATH_DISTANCE_KM, - XT_PATH_DISTANCE_MILES, - XT_PATH_SPEED, - XT_PATH_SPEED_KNOTS, - XT_PATH_SPEED_KPH, - XT_PATH_SPEED_MPH, - XT_PHONE_NR, - XT_POSTAL_CODE, - XT_ROUTE_NAME, - XT_SHORTNAME, - XT_STATE, - XT_STREET_ADDR, - XT_TIMET_TIME, - XT_TRACK_NAME, - XT_TRACK_NEW, - XT_URL, - XT_UTM, - XT_UTM_ZONE, - XT_UTM_ZONEC, - XT_UTM_ZONEF, - XT_UTM_EASTING, - XT_UTM_NORTHING, - XT_URL_LINK_TEXT, - XT_YYYYMMDD_TIME + XT_unused = 0, + XT_ALT_FEET, + XT_ALT_METERS, + XT_ANYNAME, + XT_CADENCE, + XT_CITY, + XT_CONSTANT, + XT_COUNTRY, + XT_DESCRIPTION, + XT_EXCEL_TIME, + XT_FACILITY, + XT_FILENAME, + XT_FORMAT, + XT_GEOCACHE_CONTAINER, + XT_GEOCACHE_DIFF, + XT_GEOCACHE_HINT, + XT_GEOCACHE_LAST_FOUND, + XT_GEOCACHE_PLACER, + XT_GEOCACHE_TERR, + XT_GEOCACHE_TYPE, + XT_GEOCACHE_ISAVAILABLE, + XT_GEOCACHE_ISARCHIVED, + XT_GMT_TIME, + XT_GPS_FIX, + XT_GPS_HDOP, + XT_GPS_PDOP, + XT_GPS_SAT, + XT_GPS_VDOP, + XT_HEART_RATE, + XT_HMSG_TIME, + XT_HMSL_TIME, + XT_ICON_DESCR, + XT_IGNORE, + XT_INDEX, + XT_ISO_TIME, + XT_ISO_TIME_MS, + XT_LATLON_HUMAN_READABLE, + XT_LAT_DECIMAL, + XT_LAT_DECIMALDIR, + XT_LAT_DIR, + XT_LAT_DIRDECIMAL, + XT_LAT_HUMAN_READABLE, + XT_LAT_INT32DEG, + XT_LAT_DDMMDIR, + XT_LAT_NMEA, + XT_LOCAL_TIME, + XT_LON_DECIMAL, + XT_LON_DECIMALDIR, + XT_LON_DIR, + XT_LON_DIRDECIMAL, + XT_LON_HUMAN_READABLE, + XT_LON_INT32DEG, + XT_LON_DDMMDIR, + XT_LON_NMEA, + XT_MAP_EN_BNG, + XT_NOTES, + XT_NET_TIME, + XT_PATH_COURSE, + XT_PATH_DISTANCE_KM, + XT_PATH_DISTANCE_MILES, + XT_PATH_SPEED, + XT_PATH_SPEED_KNOTS, + XT_PATH_SPEED_KPH, + XT_PATH_SPEED_MPH, + XT_PHONE_NR, + XT_POSTAL_CODE, + XT_ROUTE_NAME, + XT_SHORTNAME, + XT_STATE, + XT_STREET_ADDR, + XT_TIMET_TIME, + XT_TRACK_NAME, + XT_TRACK_NEW, + XT_URL, + XT_UTM, + XT_UTM_ZONE, + XT_UTM_ZONEC, + XT_UTM_ZONEF, + XT_UTM_EASTING, + XT_UTM_NORTHING, + XT_URL_LINK_TEXT, + XT_YYYYMMDD_TIME } xcsv_token; // Static definition of in_word_set to meet C99 rules as used by Clang. static struct xt_mapping * -in_word_set (register const char *str, register unsigned int len); +in_word_set(register const char *str, register unsigned int len); #include "xcsv_tokens.gperf" @@ -173,37 +173,37 @@ char * CSV_STRINGCLEAN(const char *string, const char *chararray, DEBUG_PARAMS) #else csv_stringclean(const char *string, const char *chararray) -#endif +#endif { - char * p1; - char * p2; - const char * cp; - char * tmp = xxstrdup(string,file,line); + char * p1; + char * p2; + const char * cp; + char * tmp = xxstrdup(string,file,line); - if ((! string) || (! chararray)) { - return (tmp); - } + if ((! string) || (! chararray)) { + return (tmp); + } - /* p2 - end of the original string */ - p2 = tmp + strlen(tmp); - - cp = chararray; - - while (*cp) { - p1 = tmp; - while (*p1) { - if (*cp == *p1) { - /* we don't want this character! */ - memmove(p1, p1 + 1, (p2 - p1)); - p1[p2 - p1] = '\0'; - p2--; - } - else - p1++; - } - cp++; + /* p2 - end of the original string */ + p2 = tmp + strlen(tmp); + + cp = chararray; + + while (*cp) { + p1 = tmp; + while (*p1) { + if (*cp == *p1) { + /* we don't want this character! */ + memmove(p1, p1 + 1, (p2 - p1)); + p1[p2 - p1] = '\0'; + p2--; + } else { + p1++; + } } - return (tmp); + cp++; + } + return (tmp); } /***********************************************************************************/ @@ -218,57 +218,57 @@ CSV_STRINGTRIM(const char *string, const char *enclosure, int strip_max, DEBUG_P csv_stringtrim(const char *string, const char *enclosure, int strip_max) #endif { - static const char *p1 = NULL; - char *p2 = NULL; - char * tmp = xxstrdup(string,file,line); - size_t elen; - int stripped = 0; - - if (!strlen(string)) { - return (tmp); - } + static const char *p1 = NULL; + char *p2 = NULL; + char * tmp = xxstrdup(string,file,line); + size_t elen; + int stripped = 0; - if (!enclosure) { - elen = 0; - } else { - elen = strlen(enclosure); - } - - p2 = tmp + strlen(tmp) - 1; - p1 = tmp; - - /* trim off trailing whitespace */ - while ((p2 > p1) && isspace(*p2)) { - p2--; - } - - /* advance p1 past any leading whitespace */ - while ((p1 < p2) && (isspace(*p1))) { - p1++; - } - - /* if no maximum strippage, assign a reasonable value to max */ - strip_max = strip_max ? strip_max : 9999; - - /* if we have enclosures, skip past them in pairs */ - if (elen) { - while ( - (stripped < strip_max) && - ((size_t) (p2 - p1 + 1) >= (elen * 2)) && - (strncmp(p1, enclosure, elen) == 0) && - (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { - p2 -= elen; - p1 += elen; - stripped++; - } + if (!strlen(string)) { + return (tmp); + } + + if (!enclosure) { + elen = 0; + } else { + elen = strlen(enclosure); + } + + p2 = tmp + strlen(tmp) - 1; + p1 = tmp; + + /* trim off trailing whitespace */ + while ((p2 > p1) && isspace(*p2)) { + p2--; + } + + /* advance p1 past any leading whitespace */ + while ((p1 < p2) && (isspace(*p1))) { + p1++; + } + + /* if no maximum strippage, assign a reasonable value to max */ + strip_max = strip_max ? strip_max : 9999; + + /* if we have enclosures, skip past them in pairs */ + if (elen) { + while ( + (stripped < strip_max) && + ((size_t)(p2 - p1 + 1) >= (elen * 2)) && + (strncmp(p1, enclosure, elen) == 0) && + (strncmp((p2 - elen + 1), enclosure, elen) == 0)) { + p2 -= elen; + p1 += elen; + stripped++; } + } - /* copy what's left over back into tmp. */ - memmove(tmp, p1, (p2 - p1) + 1); + /* copy what's left over back into tmp. */ + memmove(tmp, p1, (p2 - p1) + 1); - tmp[(p2 - p1) + 1] = '\0'; + tmp[(p2 - p1) + 1] = '\0'; - return (tmp); + return (tmp); } /*****************************************************************************/ @@ -280,110 +280,113 @@ csv_stringtrim(const char *string, const char *enclosure, int strip_max) /* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */ /*****************************************************************************/ char * -csv_lineparse(const char *stringstart, const char *delimited_by, - const char *enclosed_in, const int line_no) +csv_lineparse(const char *stringstart, const char *delimited_by, + const char *enclosed_in, const int line_no) { - const char *sp; - static const char *p = NULL; - static char *tmp = NULL; - size_t dlen = 0, elen = 0, efound = 0; - int enclosedepth = 0; - short int dfound; - short int hyper_whitespace_delimiter = 0; - - if (tmp) { - xfree(tmp); - tmp = NULL; - } - - if (strcmp(delimited_by, "\\w") == 0) - hyper_whitespace_delimiter = 1; - - /* - * This is tacky. Our "csv" format is actually "commaspace" format. - * Changing that causes unwanted churn, but it also makes "real" - * comma separated data (such as likely to be produced by Excel, etc.) - * unreadable. So we silently change it here on a read and let the - * whitespace eater consume the space. - */ - if (strcmp(delimited_by, ", ") == 0) { - delimited_by = ","; - } + const char *sp; + static const char *p = NULL; + static char *tmp = NULL; + size_t dlen = 0, elen = 0, efound = 0; + int enclosedepth = 0; + short int dfound; + short int hyper_whitespace_delimiter = 0; + + if (tmp) { + xfree(tmp); + tmp = NULL; + } + + if (strcmp(delimited_by, "\\w") == 0) { + hyper_whitespace_delimiter = 1; + } + + /* + * This is tacky. Our "csv" format is actually "commaspace" format. + * Changing that causes unwanted churn, but it also makes "real" + * comma separated data (such as likely to be produced by Excel, etc.) + * unreadable. So we silently change it here on a read and let the + * whitespace eater consume the space. + */ + if (strcmp(delimited_by, ", ") == 0) { + delimited_by = ","; + } + + if (!p) { + /* first pass thru */ + p = stringstart; if (!p) { - /* first pass thru */ - p = stringstart; - - if (!p) { - /* last pass out */ - return (NULL); - } + /* last pass out */ + return (NULL); } - - /* the beginning of the string we start with (this pass) */ - sp = p; - - /* length of delimiters and enclosures */ - if ((delimited_by) && (!hyper_whitespace_delimiter)) - dlen = strlen(delimited_by); - if (enclosed_in) - elen = strlen(enclosed_in); - dfound = 0; - - while ((*p) && (!dfound)) { - if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) - { - efound = 1; - p+=elen; - if (enclosedepth) - enclosedepth--; - else - enclosedepth++; - continue; - } - - if (!enclosedepth) { - if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) { - dfound = 1; - } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) { - dfound = 1; - while (ISWHITESPACE(*p)) - p++; - } else { - p++; - } - } - else { - p++; - } - } - - /* allocate enough space for this data field */ - tmp = (char *) xcalloc((p - sp) + 1, sizeof(char)); - - strncpy(tmp, sp, (p - sp)); - tmp[p - sp] = '\0'; - - if (elen && efound) { - char *c = csv_stringtrim(tmp, enclosed_in, 0); - xfree(tmp); - tmp = c; + } + + /* the beginning of the string we start with (this pass) */ + sp = p; + + /* length of delimiters and enclosures */ + if ((delimited_by) && (!hyper_whitespace_delimiter)) { + dlen = strlen(delimited_by); + } + if (enclosed_in) { + elen = strlen(enclosed_in); + } + dfound = 0; + + while ((*p) && (!dfound)) { + if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) { + efound = 1; + p+=elen; + if (enclosedepth) { + enclosedepth--; + } else { + enclosedepth++; + } + continue; } - if (dfound) { - /* skip over the delimited_by */ - p += dlen; + if (!enclosedepth) { + if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) { + dfound = 1; + } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) { + dfound = 1; + while (ISWHITESPACE(*p)) { + p++; + } + } else { + p++; + } } else { - /* end of the line */ - p = NULL; + p++; } - - if (enclosedepth != 0) { - warning(MYNAME - ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", - enclosed_in, line_no); - } - return (tmp); + } + + /* allocate enough space for this data field */ + tmp = (char *) xcalloc((p - sp) + 1, sizeof(char)); + + strncpy(tmp, sp, (p - sp)); + tmp[p - sp] = '\0'; + + if (elen && efound) { + char *c = csv_stringtrim(tmp, enclosed_in, 0); + xfree(tmp); + tmp = c; + } + + if (dfound) { + /* skip over the delimited_by */ + p += dlen; + } else { + /* end of the line */ + p = NULL; + } + + if (enclosedepth != 0) { + warning(MYNAME + ": Warning- Unbalanced Field Enclosures (%s) on line %d\n", + enclosed_in, line_no); + } + return (tmp); } #if CSVFMTS_ENABLED @@ -392,17 +395,17 @@ csv_lineparse(const char *stringstart, const char *delimited_by, /* usage: i = dec_to_intdeg(31.1234); */ /*****************************************************************************/ static int -dec_to_intdeg(const double d) +dec_to_intdeg(const double d) { - int ideg = 0; - - if (d >= 0) { - ideg = (2147483647) - (d * 8388608); - } else { - ideg = (2147483647) - (fabs(d) * 8388608) + 1; - } + int ideg = 0; + + if (d >= 0) { + ideg = (2147483647) - (d * 8388608); + } else { + ideg = (2147483647) - (fabs(d) * 8388608) + 1; + } - return(ideg); + return(ideg); } /*****************************************************************************/ @@ -410,17 +413,17 @@ dec_to_intdeg(const double d) /* usage: lat = dec_to_intdeg(ilat); */ /*****************************************************************************/ static double -intdeg_to_dec(const int ideg) +intdeg_to_dec(const int ideg) { - double d; - - if (ideg >= 0) { - d = ((2147483647) - ideg) / (double)8388608; - } else { - d = ((-2147483647-1) + ideg) / (double)8388608; - } + double d; + + if (ideg >= 0) { + d = ((2147483647) - ideg) / (double)8388608; + } else { + d = ((-2147483647-1) + ideg) / (double)8388608; + } - return(d); + return(d); } /*****************************************************************************/ @@ -428,33 +431,33 @@ intdeg_to_dec(const int ideg) /* usage: lat = decdir_to_dec("W90.1234"); */ /* lat = decdir_to_dec("30.1234N"); */ /*****************************************************************************/ -static double -decdir_to_dec(const char * decdir) +static double +decdir_to_dec(const char * decdir) { - char *p; - const char *cp; - double rval; - int sign = 0; - - cp = &decdir[0]; - - if ((*cp == 'W') || (*cp == 'S')) - sign = -1; - else - if ((*cp == 'N') || (*cp == 'E')) - sign = 1; - - rval = sign ? strtod(&decdir[1], &p) : strtod(&decdir[0], &p); - - if (sign == 0) { - if ((*p == 'W') || (*p == 'S')) - sign = -1; - else - if ((*p == 'N') || (*p == 'E')) - sign = 1; + char *p; + const char *cp; + double rval; + int sign = 0; + + cp = &decdir[0]; + + if ((*cp == 'W') || (*cp == 'S')) { + sign = -1; + } else if ((*cp == 'N') || (*cp == 'E')) { + sign = 1; + } + + rval = sign ? strtod(&decdir[1], &p) : strtod(&decdir[0], &p); + + if (sign == 0) { + if ((*p == 'W') || (*p == 'S')) { + sign = -1; + } else if ((*p == 'N') || (*p == 'E')) { + sign = 1; } - - return(rval * sign); + } + + return(rval * sign); } /*****************************************************************************/ @@ -465,13 +468,12 @@ decdir_to_dec(const char * decdir) static double ddmmdir_to_degrees(const char * ddmmdir) { - // if not N or E, prepend a '-' to ddmm2degrees input - // see XT_LAT_NMEA which handles ddmm directly - if (strchr(ddmmdir, 'W') || strchr(ddmmdir, 'S')) - { - return ddmm2degrees(- atof(ddmmdir)); - } - return ddmm2degrees(atof(ddmmdir)); + // if not N or E, prepend a '-' to ddmm2degrees input + // see XT_LAT_NMEA which handles ddmm directly + if (strchr(ddmmdir, 'W') || strchr(ddmmdir, 'S')) { + return ddmm2degrees(- atof(ddmmdir)); + } + return ddmm2degrees(atof(ddmmdir)); } #endif @@ -480,131 +482,172 @@ ddmmdir_to_degrees(const char * ddmmdir) * human_to_dec() - convert a "human-readable" lat and/or lon to decimal * usage: human_to_dec( "N 41° 09.12' W 085° 09.36'", &lat, &lon ); * human_to_dec( "41 9 5.652 N", &lat, &lon ); - * + * * which: 0-no preference 1-prefer lat 2-prefer lon *****************************************************************************/ void -human_to_dec( const char *instr, double *outlat, double *outlon, int which ) +human_to_dec(const char *instr, double *outlat, double *outlon, int which) { - double unk[3] = {999,999,999}; - double lat[3] = {999,999,999}; - double lon[3] = {999,999,999}; - int latsign = 0; - int lonsign = 0; - int unksign = 1; - - const char *cur; - double *numres = unk; - int numind = 0; - char *buff; - - if (strchr(instr, ',') != NULL) { - char *c; - buff = xstrdup(instr); - while ((c = strchr(buff, ','))) *c = '.'; + double unk[3] = {999,999,999}; + double lat[3] = {999,999,999}; + double lon[3] = {999,999,999}; + int latsign = 0; + int lonsign = 0; + int unksign = 1; + + const char *cur; + double *numres = unk; + int numind = 0; + char *buff; + + if (strchr(instr, ',') != NULL) { + char *c; + buff = xstrdup(instr); + while ((c = strchr(buff, ','))) { + *c = '.'; } - else { - buff = (char *)instr; + } else { + buff = (char *)instr; + } + + cur = buff; + + while (cur && *cur) { + switch (*cur) { + case 'n': + case 's': + case 'N': + case 'S': + if (unk[0] != 999) { + numind = 0; + numres = unk; + lat[0] = unk[0]; + lat[1] = unk[1]; + lat[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } else { + numres = lat; + numind = 0; + lat[0] = lat[1] = lat[2] = 999; + } + + if (*cur == 'n' || *cur == 'N') { + latsign = 1; + } else { + latsign = -1; + } + cur++; + break; + case 'w': + case 'e': + case 'W': + case 'E': + if (unk[0] != 999) { + numind = 0; + numres = unk; + lon[0] = unk[0]; + lon[1] = unk[1]; + lon[2] = unk[2]; + unk[0] = unk[1] = unk[2] = 999; + } else { + numres = lon; + numind = 0; + lon[0] = lon[1] = lon[2] = 999; + } + + if (*cur == 'e' || *cur == 'E') { + lonsign = 1; + } else { + lonsign = -1; + } + cur++; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + case '.': + case ',': + numres[numind] = atof(cur); + while (cur && *cur && strchr("1234567890.,",*cur)) { + cur++; + } + break; + case '-': + unksign = -1; + cur++; + break; + default: + if (numres[numind] != 999) { + numind++; + if (numind > 2) { + numres = unk; + numind = 0; + } + } + cur++; + break; + } + } + + if (lat[0] == 999 && lon[0] == 999) { + if (which == 1) { + lat[0] = unk[0]; + lat[1] = unk[1]; + lat[2] = unk[2]; + latsign = unksign; + } else if (which == 2) { + lon[0] = unk[0]; + lon[1] = unk[1]; + lon[2] = unk[2]; + lonsign = unksign; } - - cur = buff; - - while ( cur && *cur ) { - switch (*cur) { - case 'n': case 's': case 'N': case 'S': - if ( unk[0] != 999 ) { - numind = 0; - numres = unk; - lat[0] = unk[0]; - lat[1] = unk[1]; - lat[2] = unk[2]; - unk[0] = unk[1] = unk[2] = 999; - } - else { - numres = lat; - numind = 0; - lat[0] = lat[1] = lat[2] = 999; - } - - if ( *cur == 'n' || *cur == 'N' ) - latsign = 1; - else - latsign = -1; - cur++; - break; - case 'w': case 'e': case 'W': case 'E': - if ( unk[0] != 999 ) { - numind = 0; - numres = unk; - lon[0] = unk[0]; - lon[1] = unk[1]; - lon[2] = unk[2]; - unk[0] = unk[1] = unk[2] = 999; - } - else { - numres = lon; - numind = 0; - lon[0] = lon[1] = lon[2] = 999; - } - - if ( *cur == 'e' || *cur == 'E' ) - lonsign = 1; - else - lonsign = -1; - cur++; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': case '0': - case '.': case ',': - numres[numind] = atof(cur); - while (cur && *cur && strchr("1234567890.,",*cur)) cur++; - break; - case '-': - unksign = -1; - cur++; - break; - default: - if (numres[numind] != 999) { - numind++; - if ( numind > 2 ) { - numres = unk; - numind = 0; - } - } - cur++; - break; - } + } + + if (outlat) { + if (lat[0] != 999) { + *outlat = lat[0]; + } + if (lat[1] != 999) { + *outlat += lat[1]/60.0; + } + if (lat[2] != 999) { + *outlat += lat[2]/3600.0; + } + if (*outlat > 360) { + *outlat = ddmm2degrees(*outlat); /* NMEA style */ } - - if ( lat[0] == 999 && lon[0] == 999 ) { - if ( which == 1 ) { - lat[0] = unk[0]; lat[1] = unk[1]; lat[2] = unk[2]; - latsign = unksign; - } - else if ( which == 2 ) { - lon[0] = unk[0]; lon[1] = unk[1]; lon[2] = unk[2]; - lonsign = unksign; - } + if (latsign) { + *outlat *= latsign; } - - if ( outlat ) { - if ( lat[0] != 999 ) *outlat = lat[0]; - if ( lat[1] != 999 ) *outlat += lat[1]/60.0; - if ( lat[2] != 999 ) *outlat += lat[2]/3600.0; - if ( *outlat > 360) *outlat = ddmm2degrees(*outlat); /* NMEA style */ - if ( latsign ) *outlat *= latsign; + } + if (outlon) { + if (lon[0] != 999) { + *outlon = lon[0]; } - if ( outlon ) { - if ( lon[0] != 999 ) *outlon = lon[0]; - if ( lon[1] != 999 ) *outlon += lon[1]/60.0; - if ( lon[2] != 999 ) *outlon += lon[2]/3600.0; - if ( *outlon > 360) *outlon = ddmm2degrees(*outlon); /* NMEA style */ - if ( lonsign ) *outlon *= lonsign; + if (lon[1] != 999) { + *outlon += lon[1]/60.0; } - if (buff != instr) { - xfree(buff); + if (lon[2] != 999) { + *outlon += lon[2]/3600.0; } + if (*outlon > 360) { + *outlon = ddmm2degrees(*outlon); /* NMEA style */ + } + if (lonsign) { + *outlon *= lonsign; + } + } + if (buff != instr) { + xfree(buff); + } } #if CSVFMTS_ENABLED @@ -613,78 +656,81 @@ human_to_dec( const char *instr, double *outlat, double *outlon, int which ) */ void -dec_to_human( char *buff, const char *format, const char *dirs, double val ) +dec_to_human(char *buff, const char *format, const char *dirs, double val) { - char *subformat = NULL; - const char *formatptr = NULL; - char *percent = NULL; - char *type = NULL; - - int index = 0; - int intvals[3] = {0,0,0}; - double dblvals[3] = {0,0,0}; - int sign = 0; - - sign = (val < 0) ? 0 : 1; - - dblvals[0] = fabs(val); - intvals[0] = (int)dblvals[0]; - dblvals[1] = 60*(dblvals[0]-intvals[0]); - intvals[1] = (int)dblvals[1]; - dblvals[2] = 60*(dblvals[1]-intvals[1]); - intvals[2] = (int)dblvals[2]; - - subformat = (char*) xmalloc( strlen(format)+2); - formatptr = format; - - buff[0] = '\0'; - - while ( formatptr && *formatptr ) { - strcpy( subformat, formatptr ); - percent = strchr( subformat, '%' ); - if ( percent ) { - type = percent+1+strcspn( percent+1, "cdiouxXeEfgG%" ); - *(type+1) = '\0'; - switch( *type ) { - case 'c': - sprintf( buff+strlen(buff), subformat, dirs[sign] ); - break; - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - if (index>2) fatal(MYNAME ": too many format specifiers\n"); - sprintf( buff+strlen(buff), subformat, intvals[index]); - index++; - break; - case 'e': - case 'E': - case 'f': - case 'g': - case 'G': - if (index>2) fatal(MYNAME ": too many format specifiers\n"); - sprintf( buff+strlen(buff), subformat, dblvals[index]); - index++; - break; - case '%': - sprintf( buff+strlen(buff), "%s", subformat ); - break; - default: - fatal(MYNAME ": invalid format specifier\n"); - break; - - } - } - else { - sprintf( buff+strlen(buff), "%s", subformat ); - } - formatptr += strlen(subformat); - } - - xfree(subformat); -} + char *subformat = NULL; + const char *formatptr = NULL; + char *percent = NULL; + char *type = NULL; + + int index = 0; + int intvals[3] = {0,0,0}; + double dblvals[3] = {0,0,0}; + int sign = 0; + + sign = (val < 0) ? 0 : 1; + + dblvals[0] = fabs(val); + intvals[0] = (int)dblvals[0]; + dblvals[1] = 60*(dblvals[0]-intvals[0]); + intvals[1] = (int)dblvals[1]; + dblvals[2] = 60*(dblvals[1]-intvals[1]); + intvals[2] = (int)dblvals[2]; + + subformat = (char*) xmalloc(strlen(format)+2); + formatptr = format; + + buff[0] = '\0'; + + while (formatptr && *formatptr) { + strcpy(subformat, formatptr); + percent = strchr(subformat, '%'); + if (percent) { + type = percent+1+strcspn(percent+1, "cdiouxXeEfgG%"); + *(type+1) = '\0'; + switch (*type) { + case 'c': + sprintf(buff+strlen(buff), subformat, dirs[sign]); + break; + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + if (index>2) { + fatal(MYNAME ": too many format specifiers\n"); + } + sprintf(buff+strlen(buff), subformat, intvals[index]); + index++; + break; + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (index>2) { + fatal(MYNAME ": too many format specifiers\n"); + } + sprintf(buff+strlen(buff), subformat, dblvals[index]); + index++; + break; + case '%': + sprintf(buff+strlen(buff), "%s", subformat); + break; + default: + fatal(MYNAME ": invalid format specifier\n"); + break; + + } + } else { + sprintf(buff+strlen(buff), "%s", subformat); + } + formatptr += strlen(subformat); + } + + xfree(subformat); +} /*****************************************************************************/ /* xcsv_file_init() - prepare xcsv_file for first use. */ @@ -692,24 +738,24 @@ dec_to_human( char *buff, const char *format, const char *dirs, double val ) void xcsv_file_init(void) { - memset(&xcsv_file, '\0', sizeof(xcsv_file_t)); - - QUEUE_INIT(&xcsv_file.prologue); - QUEUE_INIT(&xcsv_file.epilogue); - - QUEUE_INIT(&xcsv_file.ifield); - /* ofield is alloced to allow pointing back at ifields - * where applicable. - */ - xcsv_file.ofield = (queue*) xcalloc(sizeof(queue), 1); - QUEUE_INIT(xcsv_file.ofield); - /* - * Provide a sane default for CSV _files_. - */ - xcsv_file.type = ff_type_file; - - xcsv_file.mkshort_handle = (struct short_handle *) mkshort_new_handle(); - xcsv_file.gps_datum = GPS_DATUM_WGS84; + memset(&xcsv_file, '\0', sizeof(xcsv_file_t)); + + QUEUE_INIT(&xcsv_file.prologue); + QUEUE_INIT(&xcsv_file.epilogue); + + QUEUE_INIT(&xcsv_file.ifield); + /* ofield is alloced to allow pointing back at ifields + * where applicable. + */ + xcsv_file.ofield = (queue*) xcalloc(sizeof(queue), 1); + QUEUE_INIT(xcsv_file.ofield); + /* + * Provide a sane default for CSV _files_. + */ + xcsv_file.type = ff_type_file; + + xcsv_file.mkshort_handle = (struct short_handle *) mkshort_new_handle(); + xcsv_file.gps_datum = GPS_DATUM_WGS84; } /*****************************************************************************/ @@ -719,16 +765,16 @@ xcsv_file_init(void) void xcsv_ifield_add(char *key, char *val, char *pfc) { - field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); - struct xt_mapping *xm = in_word_set(key, strlen(key)); - - fmp->key = key; - fmp->hashed_key = xm ? xm->xt_token : -1; - fmp->val = val; - fmp->printfc = pfc; - - ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); - xcsv_file.ifield_ct++; + field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); + struct xt_mapping *xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + + ENQUEUE_TAIL(&xcsv_file.ifield, &fmp->Q); + xcsv_file.ifield_ct++; } /*****************************************************************************/ @@ -738,17 +784,17 @@ xcsv_ifield_add(char *key, char *val, char *pfc) void xcsv_ofield_add(char *key, char *val, char *pfc, int options) { - field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); - struct xt_mapping *xm = in_word_set(key, strlen(key)); - - fmp->key = key; - fmp->hashed_key = xm ? xm->xt_token : -1; - fmp->val = val; - fmp->printfc = pfc; - fmp->options = options; - - ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); - xcsv_file.ofield_ct++; + field_map_t *fmp = (field_map_t *) xcalloc(sizeof(*fmp), 1); + struct xt_mapping *xm = in_word_set(key, strlen(key)); + + fmp->key = key; + fmp->hashed_key = xm ? xm->xt_token : -1; + fmp->val = val; + fmp->printfc = pfc; + fmp->options = options; + + ENQUEUE_TAIL(xcsv_file.ofield, &fmp->Q); + xcsv_file.ofield_ct++; } /*****************************************************************************/ @@ -758,11 +804,11 @@ xcsv_ofield_add(char *key, char *val, char *pfc, int options) void xcsv_prologue_add(char *prologue) { - ogue_t* ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); + ogue_t* ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); - ogp->val = prologue; - ENQUEUE_TAIL(&xcsv_file.prologue, &ogp->Q); - xcsv_file.prologue_lines++; + ogp->val = prologue; + ENQUEUE_TAIL(&xcsv_file.prologue, &ogp->Q); + xcsv_file.prologue_lines++; } /*****************************************************************************/ @@ -772,32 +818,33 @@ xcsv_prologue_add(char *prologue) void xcsv_epilogue_add(char *epilogue) { - ogue_t * ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); + ogue_t * ogp = (ogue_t*) xcalloc(sizeof(*ogp), 1); - ogp->val = epilogue; - ENQUEUE_TAIL(&xcsv_file.epilogue, &ogp->Q); - xcsv_file.epilogue_lines++; + ogp->val = epilogue; + ENQUEUE_TAIL(&xcsv_file.epilogue, &ogp->Q); + xcsv_file.epilogue_lines++; } static time_t yyyymmdd_to_time(const char *s) { - int t = atol(s); - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - tm.tm_mday = t % 100; - t = t / 100; - tm.tm_mon = t % 100 - 1; - t = t / 100; - tm.tm_year = t - 1900; - - if (mkgmtime(&tm) > 0) - return mktime(&tm); - else - return 0; + int t = atol(s); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_mday = t % 100; + t = t / 100; + tm.tm_mon = t % 100 - 1; + t = t / 100; + tm.tm_year = t - 1900; + + if (mkgmtime(&tm) > 0) { + return mktime(&tm); + } else { + return 0; + } } @@ -807,133 +854,137 @@ yyyymmdd_to_time(const char *s) */ static time_t -sscanftime( const char *s, const char *format, const int gmt ) +sscanftime(const char *s, const char *format, const int gmt) { - struct tm stm; - memset(&stm, 0, sizeof(stm)); - - if ( strptime( s, format, &stm ) ) - { - if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) { - stm.tm_mday = 1; - stm.tm_mon = 0; - stm.tm_year = 70; - } - stm.tm_isdst = -1; - if (gmt) - return mkgmtime(&stm); - else - return mktime(&stm); - } - // Don't fuss for empty strings. - if (*s) { - warning("date parse of string '%s' with format '%s' failed.\n", - s, format); - } - return 0; + struct tm stm; + memset(&stm, 0, sizeof(stm)); + + if (strptime(s, format, &stm)) { + if ((stm.tm_mday == 0) && (stm.tm_mon == 0) && (stm.tm_year == 0)) { + stm.tm_mday = 1; + stm.tm_mon = 0; + stm.tm_year = 70; + } + stm.tm_isdst = -1; + if (gmt) { + return mkgmtime(&stm); + } else { + return mktime(&stm); + } + } + // Don't fuss for empty strings. + if (*s) { + warning("date parse of string '%s' with format '%s' failed.\n", + s, format); + } + return 0; } static time_t -addhms( const char *s, const char *format ) +addhms(const char *s, const char *format) { - time_t tt =0; - int hour =0; - int min =0; - int sec =0; - char * ampm = NULL; - int ac; - - ampm = (char*) xmalloc( strlen(s) ); - ac = sscanf(s, format, &hour, &min, &sec, &m); - /* If no time format in arg string, assume AM */ - if (ac < 4) { - ampm[0] = 0; - } - if (ac) { - tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; - } - xfree(ampm); - - return tt; + time_t tt =0; + int hour =0; + int min =0; + int sec =0; + char * ampm = NULL; + int ac; + + ampm = (char*) xmalloc(strlen(s)); + ac = sscanf(s, format, &hour, &min, &sec, &m); + /* If no time format in arg string, assume AM */ + if (ac < 4) { + ampm[0] = 0; + } + if (ac) { + tt = ((tolower(ampm[0])=='P')?43200:0)+3600*hour+60*min+sec; + } + xfree(ampm); + + return tt; } -static -int -writetime(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +static +int +writetime(char * buff, size_t bufsize, const char * format, time_t t, int gmt) { - static struct tm * stmp; + static struct tm * stmp; - if (gmt) - stmp = gmtime(&t); - else - stmp = localtime(&t); + if (gmt) { + stmp = gmtime(&t); + } else { + stmp = localtime(&t); + } - return strftime(buff, bufsize, format, stmp ); + return strftime(buff, bufsize, format, stmp); } #if 0 /* not used */ -static -int +static +int writeisotime(char * buff, size_t bufsize, const char * format, time_t t) { - static struct tm * stmp; - char * ibuff = NULL; - int i; - - ibuff = xmalloc(bufsize); - stmp = gmtime(&t); - strftime(ibuff, bufsize, format, stmp ); - i = snprintf(buff, bufsize, format, ibuff ); - xfree(ibuff); - return i; + static struct tm * stmp; + char * ibuff = NULL; + int i; + + ibuff = xmalloc(bufsize); + stmp = gmtime(&t); + strftime(ibuff, bufsize, format, stmp); + i = snprintf(buff, bufsize, format, ibuff); + xfree(ibuff); + return i; } #endif -static -int -writehms(char * buff, size_t bufsize, const char * format, time_t t, int gmt ) +static +int +writehms(char * buff, size_t bufsize, const char * format, time_t t, int gmt) { - static struct tm no_time = {0}; - static struct tm * stmp = &no_time; - - if (gmt) - stmp = gmtime(&t); - else - stmp = localtime(&t); - - if (stmp == NULL) stmp = &no_time; - - return snprintf(buff, bufsize, format, - stmp->tm_hour, stmp->tm_min, stmp->tm_sec, - (stmp->tm_hour>=12?"PM":"AM") ); + static struct tm no_time = {0}; + static struct tm * stmp = &no_time; + + if (gmt) { + stmp = gmtime(&t); + } else { + stmp = localtime(&t); + } + + if (stmp == NULL) { + stmp = &no_time; + } + + return snprintf(buff, bufsize, format, + stmp->tm_hour, stmp->tm_min, stmp->tm_sec, + (stmp->tm_hour>=12?"PM":"AM")); } -static -long +static +long time_to_yyyymmdd(time_t t) { - long b; - struct tm *tm = gmtime(&t); + long b; + struct tm *tm = gmtime(&t); - b = (1900 + tm->tm_year) * 10000 + - (1 + tm->tm_mon) * 100 + - tm->tm_mday; + b = (1900 + tm->tm_year) * 10000 + + (1 + tm->tm_mon) * 100 + + tm->tm_mday; - return b; + return b; } static garmin_fs_t * gmsd_init(waypoint *wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; } /*****************************************************************************/ @@ -941,1082 +992,1104 @@ gmsd_init(waypoint *wpt) /* usage: xcsv_parse_val("-123.34", *waypt, *field_map) */ /*****************************************************************************/ static void -xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp, +xcsv_parse_val(const char *s, waypoint *wpt, const field_map_t *fmp, route_head **trk) { - char *enclosure = ""; - geocache_data *gc_data = NULL; + char *enclosure = ""; + geocache_data *gc_data = NULL; + + if (!fmp->printfc) { + fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp->key); + } + + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + enclosure = "\""; + } + switch (fmp->hashed_key) { + case XT_IGNORE: + /* IGNORE -- Categorically ignore this... */ + break; + case XT_CONSTANT: + /* CONSTANT -- Ignore on Input... */ + break; + case XT_ANYNAME: + /* ANYNAME -- Ignore -- this is output magic. */ + break; + case XT_INDEX: + /* IGNORE -- Calculated Sequence # For Ouput*/ + break; + case XT_SHORTNAME: + wpt->shortname = csv_stringtrim(s, enclosure, 0); + break; + case XT_DESCRIPTION: + wpt->description = csv_stringtrim(s, enclosure, 0); + break; + case XT_NOTES: + wpt->notes = csv_stringtrim(s, "", 0); + break; + case XT_URL: + wpt->url = csv_stringtrim(s, "", 0); + break; + case XT_URL_LINK_TEXT: + wpt->url_link_text = csv_stringtrim(s, "", 0); + break; + case XT_ICON_DESCR: + wpt->icon_descr = csv_stringtrim(s, "", 0); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + + /* LATITUDE CONVERSIONS**************************************************/ + case XT_LAT_DECIMAL: + /* latitude as a pure decimal value */ + wpt->latitude = atof(s); + break; + case XT_LAT_DECIMALDIR: + case XT_LAT_DIRDECIMAL: + /* latitude as a decimal with N/S in it. */ + wpt->latitude = decdir_to_dec(s); + break; + case XT_LAT_INT32DEG: + /* latitude as a 32 bit integer offset */ + wpt->latitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LAT_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 1); + break; + case XT_LAT_DDMMDIR: + wpt->latitude = ddmmdir_to_degrees(s); + break; + case XT_LAT_NMEA: + wpt->latitude = ddmm2degrees(atof(s)); + break; + // XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS ***********************************************/ + case XT_LON_DECIMAL: + /* longitude as a pure decimal value */ + wpt->longitude = atof(s); + break; + case XT_LON_DECIMALDIR: + case XT_LON_DIRDECIMAL: + /* longitude as a decimal with N/S in it. */ + wpt->longitude = decdir_to_dec(s); + break; + case XT_LON_INT32DEG: + /* longitude as a 32 bit integer offset */ + wpt->longitude = intdeg_to_dec((int) atof(s)); + break; + case XT_LON_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 2); + break; + case XT_LON_DDMMDIR: + wpt->longitude = ddmmdir_to_degrees(s); + break; + case XT_LON_NMEA: + wpt->longitude = ddmm2degrees(atof(s)); + break; + // case XT_LON_10E is handled outside the switch. + /* LAT AND LON CONVERSIONS ********************************************/ + case XT_LATLON_HUMAN_READABLE: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 0); + break; + /* DIRECTIONS **********************************************************/ + case XT_LAT_DIR: + /* latitude N/S. Ignore on input for now */ + break; + case XT_LON_DIR: + /* longitude E/W. Ingore on input for now */ + break; + /* SPECIAL COORDINATES/GRID */ + case XT_MAP_EN_BNG: + parse_coordinates(s, DATUM_OSGB36, grid_bng, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case XT_UTM_ZONE: + utm_zone = atoi(s); + break; + case XT_UTM_ZONEC: + utm_zonec = atoi(s); + break; + case XT_UTM_ZONEF: + utm_zone = atoi(s); + utm_zonec = s[strlen(s) - 1]; + break; + case XT_UTM_EASTING: + utm_easting = atof(s); + break; + case XT_UTM_NORTHING: + utm_northing = atof(s); + break; + case XT_UTM: { + char *ss; + int i = 0;; + + utm_zone = strtod(s, &ss); + utm_zonec = ss[i]; + ss++; + utm_easting = strtod(ss, &ss); + while (*ss && !isdigit(*ss)) { + ss++; + } + utm_northing = strtod(ss, NULL); + } + break; + /* ALTITUDE CONVERSIONS ************************************************/ + case XT_ALT_FEET: + /* altitude in feet as a decimal value */ + wpt->altitude = FEET_TO_METERS(atof(s)); + if (wpt->altitude < unknown_alt + 1) { + wpt->altitude = unknown_alt; + } + break; + case XT_ALT_METERS: + /* altitude in meters as a decimal value */ + wpt->altitude = atof(s); + if (wpt->altitude < unknown_alt + 1) { + wpt->altitude = unknown_alt; + } + break; + + /* PATH CONVERSIONS ************************************************/ + case XT_PATH_SPEED: + WAYPT_SET(wpt, speed, atof(s)); + break; + case XT_PATH_SPEED_KPH: + WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_MPH: + WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s))); + break; + case XT_PATH_SPEED_KNOTS: + WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s))); + break; + case XT_PATH_COURSE: + WAYPT_SET(wpt, course, atof(s)); + break; + + /* TIME CONVERSIONS ***************************************************/ + case XT_EXCEL_TIME: + /* Time as Excel Time */ + wpt->creation_time = EXCEL_TO_TIMET(atof(s)); + break; + case XT_TIMET_TIME: + /* Time as time_t */ + wpt->creation_time = atol(s); + break; + case XT_YYYYMMDD_TIME: + wpt->creation_time = yyyymmdd_to_time(s); + break; + case XT_GMT_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 1); + break; + case XT_LOCAL_TIME: + wpt->creation_time += sscanftime(s, fmp->printfc, 0); + break; + /* Useful when time and date are in separate fields + GMT / Local offset is handled by the two cases above */ + case XT_HMSG_TIME: + case XT_HMSL_TIME: + wpt->creation_time += addhms(s, fmp->printfc); + break; + case XT_ISO_TIME: + case XT_ISO_TIME_MS: + wpt->creation_time = xml_parse_time(s, &wpt->microseconds); + break; + case XT_NET_TIME: + dotnet_time_to_time_t(atof(s), &wpt->creation_time, &wpt->microseconds); + break; + case XT_GEOCACHE_LAST_FOUND: + waypt_alloc_gc_data(wpt)->last_found = yyyymmdd_to_time(s); + break; + + /* GEOCACHING STUFF ***************************************************/ + case XT_GEOCACHE_DIFF: + /* Geocache Difficulty as an int */ + waypt_alloc_gc_data(wpt)->diff = atof(s) * 10; + break; + case XT_GEOCACHE_TERR: + /* Geocache Terrain as an int */ + waypt_alloc_gc_data(wpt)->terr = atof(s) * 10; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + waypt_alloc_gc_data(wpt)->type = gs_mktype(s); + break; + case XT_GEOCACHE_CONTAINER: + waypt_alloc_gc_data(wpt)->container = gs_mkcont(s); + break; + case XT_GEOCACHE_HINT: + waypt_alloc_gc_data(wpt)->hint = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_PLACER: + waypt_alloc_gc_data(wpt)->placer = csv_stringtrim(s, "", 0); + break; + case XT_GEOCACHE_ISAVAILABLE: + gc_data = waypt_alloc_gc_data(wpt); + if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0) { + gc_data->is_available = status_false; + } else if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0) { + gc_data->is_available = status_true; + } else { + gc_data->is_available = status_unknown; + } + break; + case XT_GEOCACHE_ISARCHIVED: + gc_data = waypt_alloc_gc_data(wpt); + if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0) { + gc_data->is_archived = status_false; + } else if (case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0) { + gc_data->is_archived = status_true; + } else { + gc_data->is_archived = status_unknown; + } + break; + + /* GPS STUFF *******************************************************/ + case XT_GPS_HDOP: + wpt->hdop = atof(s); + break; + case XT_GPS_VDOP: + wpt->vdop = atof(s); + break; + case XT_GPS_PDOP: + wpt->pdop = atof(s); + break; + case XT_GPS_SAT: + wpt->sat = atoi(s); + break; + case XT_GPS_FIX: + wpt->fix = (fix_type)(atoi(s)-(fix_type)1); + if (wpt->fix < fix_2d) { + if (!case_ignore_strcmp(s, "none")) { + wpt->fix = fix_none; + } else if (!case_ignore_strcmp(s, "dgps")) { + wpt->fix = fix_dgps; + } else if (!case_ignore_strcmp(s, "pps")) { + wpt->fix = fix_pps; + } else { + wpt->fix = fix_unknown; + } + } + break; + /* Tracks and routes *********************************************/ + case XT_ROUTE_NAME: + if (csv_route) { + csv_route->rte_name = csv_stringtrim(s, enclosure, 0); + } + break; + case XT_TRACK_NEW: + if (atoi(s) && csv_track && !QUEUE_EMPTY(&csv_track->Q)) { + *trk = route_head_alloc(); + csv_track = *trk; + + track_add_head(*trk); + } + break; + case XT_TRACK_NAME: + if (!csv_track) { + csv_track = route_head_alloc(); + } + csv_track->rte_name = csv_stringtrim(s, enclosure, 0); + break; + + /* OTHER STUFF ***************************************************/ + case XT_PATH_DISTANCE_MILES: + /* Ignored on input */ + break; + case XT_HEART_RATE: + wpt->heartrate = atoi(s); + break; + case XT_CADENCE: + wpt->cadence = atoi(s); + break; + case XT_PATH_DISTANCE_KM: + /* Ignored on input */ + break; + /* GMSD ****************************************************************/ + case XT_COUNTRY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(country, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STATE: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(state, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_CITY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(city, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(addr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_POSTAL_CODE: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_PHONE_NR: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0)); + } + break; + case XT_FACILITY: { + garmin_fs_t *gmsd = gmsd_init(wpt); + GMSD_SET(facility, csv_stringtrim(s, enclosure, 0)); + } + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + wpt->longitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + wpt->latitude = atof(s) / pow((double)10, atof(fmp->key+7)); + } else { + warning(MYNAME ": Unknown style directive: %s\n", fmp->key); + } + break; + + default: + fatal("This can't happen\n"); + break; + } +} + +/*****************************************************************************/ +/* xcsv_data_read() - read input file, parsing lines, fields and handling */ +/* any data conversion (the input meat) */ +/*****************************************************************************/ +void +xcsv_data_read(void) +{ + char *buff; + char *s; + waypoint *wpt_tmp; + int linecount = 0; + queue *elem, *tmp; + field_map_t *fmp; + ogue_t *ogp; + route_head *rte = NULL; + route_head *trk = NULL; + utm_northing = 0; + utm_easting = 0; + utm_zone = 0; + utm_zonec = 'N'; + + csv_route = csv_track = NULL; + if (xcsv_file.datatype == trkdata) { + csv_track = trk; + } else if (xcsv_file.datatype == rtedata) { + csv_route = rte; + } + + while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { + if ((linecount == 0) && xcsv_file.xcsvfp->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } - if (!fmp->printfc) { - fatal(MYNAME ": xcsv style '%s' is missing format specifier", fmp->key); + linecount++; + /* Whack trailing space; leading space may matter if our field sep + * is whitespace and we have leading whitespace. + */ + rtrim(buff); + + /* skip over x many lines on the top for the prologue... */ + if ((xcsv_file.prologue_lines) && ((linecount - 1) < + xcsv_file.prologue_lines)) { + continue; } - if (0 == strcmp(fmp->printfc, "\"%s\"")) { - enclosure = "\""; + /* We should skip over epilogue lines also. Since we don't want to + * pre-read the file to know how many data lines we should be seeing, + * we take this cheap shot at the data and cross our fingers. + */ + + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *) elem; + if (strncmp(buff, ogp->val, strlen(ogp->val)) == 0) { + buff[0] = '\0'; + break; + } } - switch(fmp->hashed_key) { + + if (strlen(buff)) { + wpt_tmp = waypt_new(); + + s = buff; + s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount); + + if (QUEUE_EMPTY(&xcsv_file.ifield)) { + fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", xcsv_file.description? xcsv_file.description : "unknown"); + } + + /* reset the ifield queue */ + elem = QUEUE_FIRST(&xcsv_file.ifield); + + /* now rip the line apart, advancing the queue for each tear + * off the beginning of buff since there's no index into queue. + */ + while (s) { + fmp = (field_map_t *) elem; + xcsv_parse_val(s, wpt_tmp, fmp, &trk); + + elem = QUEUE_NEXT(elem); + + if (elem == &xcsv_file.ifield) { + /* we've wrapped the queue. so stop parsing! */ + while (s) { + s=csv_lineparse(NULL, "\xff","",linecount); + } + break; + } + + s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", + linecount); + } + + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, + &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); + } + + if (utm_easting || utm_northing) { + GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude, + &wpt_tmp->longitude, + utm_easting, utm_northing, + utm_zone, utm_zonec, + DATUM_WGS84); + } + + switch (xcsv_file.datatype) { + case 0: + case wptdata: + waypt_add(wpt_tmp); + break; + case trkdata: + if (trk == NULL) { + trk = route_head_alloc(); + csv_track = trk; + track_add_head(trk); + } + track_add_wpt(trk, wpt_tmp); + break; + case rtedata: + if (rte == NULL) { + rte = route_head_alloc(); + csv_route = rte; + route_add_head(rte); + } + route_add_wpt(rte, wpt_tmp); + break; + default: + ; + } + } + + } +} + +static void +xcsv_resetpathlen(const route_head *head) +{ + pathdist = 0; + oldlat = 999; + oldlon = 999; + csv_route = csv_track = NULL; + switch (xcsv_file.datatype) { + case trkdata: + csv_track = (route_head *) head; + break; + case rtedata: + csv_route = (route_head *) head; + break; + default: + break; + } +} + +/*****************************************************************************/ +/* xcsv_waypt_pr() - write output file, handling output conversions */ +/* (the output meat) */ +/*****************************************************************************/ +static void +xcsv_waypt_pr(const waypoint *wpt) +{ + char buff[1024]; + char *shortname = NULL; + char *description = NULL; + char * anyname = NULL; + char * write_delimiter; + int i; + field_map_t *fmp; + queue *elem, *tmp; + double latitude, longitude; + int32 utmz; + double utme, utmn; + char utmzc; + + buff[0] = '\0'; + + if (oldlon < 900) { + pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), + RAD(wpt->latitude),RAD(wpt->longitude))); + } + longitude = oldlon = wpt->longitude; + latitude = oldlat = wpt->latitude; + + if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) { + write_delimiter = " "; + } else { + write_delimiter = xcsv_file.field_delimiter; + } + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt); + } else { + shortname = csv_stringclean(wpt->description, xcsv_file.badchars); + } + } else { + /* no shortname available -- let shortname default on output */ + } + } else { + shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars); + } + + if (! wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, xcsv_file.badchars); + } else { + /* no description -- let description default on output */ + } + } else { + description = csv_stringclean(wpt->description, xcsv_file.badchars); + } + + if (prefer_shortnames) { + if (description) { + xfree(description); + } + description = shortname; + } else if (description) { + char *odesc = description; + description = xstrdup(odesc); + xfree(odesc); + } + if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, + &latitude, &longitude, &alt, xcsv_file.gps_datum); + } + + i = 0; + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + char *obuff; + double lat = latitude; + double lon = longitude; + /* + * A klunky concept. This should evaluate to true for any + * field if we think we don't have realistic value for it. + * This is used by the 'optional' attribute for suppressing + * fields on output. + */ + int field_is_unknown = 0; + + fmp = (field_map_t *) elem; + + if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) { + gbfprintf(xcsv_file.xcsvfp, write_delimiter); + } + + if (fmp->options & OPTIONS_ABSOLUTE) { + lat = fabs(lat); + lon = fabs(lon); + } + + i++; +#define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) + switch (fmp->hashed_key) { case XT_IGNORE: - /* IGNORE -- Categorically ignore this... */ - break; - case XT_CONSTANT: - /* CONSTANT -- Ignore on Input... */ - break; - case XT_ANYNAME: - /* ANYNAME -- Ignore -- this is output magic. */ - break; + /* IGNORE -- Write the char printf conversion */ + writebuff(buff, fmp->printfc, ""); + break; case XT_INDEX: - /* IGNORE -- Calculated Sequence # For Ouput*/ - break; + writebuff(buff, fmp->printfc, waypt_out_count + atoi(fmp->val)); + break; + case XT_CONSTANT: { + const char *cp = xcsv_get_char_from_constant_table(fmp->val); + if (cp) { + writebuff(buff, fmp->printfc, cp); + } else { + writebuff(buff, fmp->printfc, fmp->val); + } + } + break; case XT_SHORTNAME: - wpt->shortname = csv_stringtrim(s, enclosure, 0); - break; + writebuff(buff, fmp->printfc, + (shortname && *shortname) ? shortname : fmp->val); + break; + case XT_ANYNAME: + if (wpt->shortname) { + anyname = xstrdup(wpt->shortname); + } else if (wpt->description) { + anyname = mkshort(xcsv_file.mkshort_handle, wpt->description); + } else if (wpt->notes) { + anyname = xstrdup(wpt->notes); + } else { + anyname = xstrdup(fmp->val); + } + + if ((anyname) && (global_opts.synthesize_shortnames)) { + anyname = xstrdup(shortname); + } + + writebuff(buff, fmp->printfc, anyname); + + xfree(anyname); + break; case XT_DESCRIPTION: - wpt->description = csv_stringtrim(s, enclosure, 0); - break; + writebuff(buff, fmp->printfc, + (description && *description) ? description : fmp->val); + break; case XT_NOTES: - wpt->notes = csv_stringtrim(s, "", 0); - break; - case XT_URL: - wpt->url = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, + (wpt->notes && *wpt->notes) ? wpt->notes : fmp->val); + break; + case XT_URL: { + int off = 0; + if (xcsv_urlbase) { + strcpy(buff, xcsv_urlbase); + off = strlen(xcsv_urlbase); + } + if (wpt->url) { + snprintf(buff + off, sizeof(buff) - off, fmp->printfc, wpt->url); + } else { + strcpy(buff, (fmp->val && *fmp->val) ? fmp->val : "\"\""); + } + } + break; case XT_URL_LINK_TEXT: - wpt->url_link_text = csv_stringtrim(s, "", 0); - break; + snprintf(buff, sizeof(buff), fmp->printfc, + (wpt->url_link_text && *wpt->url_link_text) ? wpt->url_link_text : fmp->val); + break; case XT_ICON_DESCR: - wpt->icon_descr = csv_stringtrim(s, "", 0); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - break; + writebuff(buff, fmp->printfc, + (wpt->icon_descr && *wpt->icon_descr) ? + wpt->icon_descr : fmp->val); + break; - /* LATITUDE CONVERSIONS**************************************************/ + /* LATITUDE CONVERSION***********************************************/ case XT_LAT_DECIMAL: - /* latitude as a pure decimal value */ - wpt->latitude = atof(s); - break; + /* latitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lat); + break; case XT_LAT_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), + LAT_DIR(lat)); + break; case XT_LAT_DIRDECIMAL: - /* latitude as a decimal with N/S in it. */ - wpt->latitude = decdir_to_dec(s); - break; + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LAT_DIR(lat), + fabs(lat)); + break; case XT_LAT_INT32DEG: - /* latitude as a 32 bit integer offset */ - wpt->latitude = intdeg_to_dec((int) atof(s)); - break; - case XT_LAT_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); - break; + /* latitude as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lat)); + break; case XT_LAT_DDMMDIR: - wpt->latitude = ddmmdir_to_degrees(s); + /*latitude as (degrees * 100) + decimal minutes, with N/S after it */ + dec_to_human(buff, fmp->printfc, "SN", degrees2ddmm(lat)); + break; + case XT_LAT_HUMAN_READABLE: + dec_to_human(buff, fmp->printfc, "SN", lat); break; case XT_LAT_NMEA: - wpt->latitude = ddmm2degrees(atof(s)); - break; - // XT_LAT_10E is handled outside the switch. - /* LONGITUDE CONVERSIONS ***********************************************/ + writebuff(buff, fmp->printfc, degrees2ddmm(lat)); + break; + // case XT_LAT_10E is handled outside the switch. + /* LONGITUDE CONVERSIONS*********************************************/ case XT_LON_DECIMAL: - /* longitude as a pure decimal value */ - wpt->longitude = atof(s); - break; + /* longitude as a pure decimal value */ + writebuff(buff, fmp->printfc, lon); + break; case XT_LON_DECIMALDIR: + /* latitude as a decimal value with N/S after it */ + snprintf(buff, sizeof(buff), fmp->printfc, + fabs(lon), + LON_DIR(lon)); + break; case XT_LON_DIRDECIMAL: - /* longitude as a decimal with N/S in it. */ - wpt->longitude = decdir_to_dec(s); - break; + /* latitude as a decimal value with N/S before it */ + snprintf(buff, sizeof(buff), fmp->printfc, + LON_DIR(lon), + fabs(lon)); + break; case XT_LON_INT32DEG: - /* longitude as a 32 bit integer offset */ - wpt->longitude = intdeg_to_dec((int) atof(s)); - break; - case XT_LON_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); - break; + /* longitudee as an integer offset from 0 degrees */ + writebuff(buff, fmp->printfc, + dec_to_intdeg(lon)); + break; case XT_LON_DDMMDIR: - wpt->longitude = ddmmdir_to_degrees(s); + /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/ + dec_to_human(buff, fmp->printfc, "WE", degrees2ddmm(lon)); + break; + case XT_LON_HUMAN_READABLE: + dec_to_human(buff, fmp->printfc, "WE", lon); break; - case XT_LON_NMEA: - wpt->longitude = ddmm2degrees(atof(s)); - break; - // case XT_LON_10E is handled outside the switch. - /* LAT AND LON CONVERSIONS ********************************************/ case XT_LATLON_HUMAN_READABLE: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 0 ); - break; - /* DIRECTIONS **********************************************************/ + dec_to_human(buff, fmp->printfc, "SN", lat); + if (!isspace(buff[strlen(buff)])) { + strcat(buff, " "); + } + dec_to_human(buff+strlen(buff), fmp->printfc, "WE", + lon); + break; + case XT_LON_NMEA: + writebuff(buff, fmp->printfc, degrees2ddmm(lon)); + break; + // case XT_LON_10E is handled outside the switch. + /* DIRECTIONS *******************************************************/ case XT_LAT_DIR: - /* latitude N/S. Ignore on input for now */ - break; + /* latitude N/S as a char */ + writebuff(buff, fmp->printfc, + LAT_DIR(lat)); + break; case XT_LON_DIR: - /* longitude E/W. Ingore on input for now */ - break; - /* SPECIAL COORDINATES/GRID */ - case XT_MAP_EN_BNG: - parse_coordinates(s, DATUM_OSGB36, grid_bng, - &wpt->latitude, &wpt->longitude, MYNAME); - break; + /* longitude E/W as a char */ + writebuff(buff, fmp->printfc, + LON_DIR(lon)); + break; + + /* SPECIAL COORDINATES */ + case XT_MAP_EN_BNG: { + char map[3]; + double north, east; + if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) + fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n", + wpt->latitude, wpt->longitude); + snprintf(buff, sizeof(buff), fmp->printfc, map, (int)(east + 0.5), (int)(north + 0.5)); + } + break; + case XT_UTM: { + char tbuf[100]; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f", + utmz, utmzc, utme, utmn); + writebuff(buff, fmp->printfc, tbuf); + } + break; case XT_UTM_ZONE: - utm_zone = atoi(s); - break; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmz); + break; case XT_UTM_ZONEC: - utm_zonec = atoi(s); - break; - case XT_UTM_ZONEF: - utm_zone = atoi(s); - utm_zonec = s[strlen(s) - 1]; - break; - case XT_UTM_EASTING: - utm_easting = atof(s); - break; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmzc); + break; + case XT_UTM_ZONEF: { + char tbuf[10]; + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + tbuf[0] = 0; + snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc); + writebuff(buff, fmp->printfc, tbuf); + } + break; case XT_UTM_NORTHING: - utm_northing = atof(s); - break; - case XT_UTM: { - char *ss; - int i = 0;; - - utm_zone = strtod(s, &ss); - utm_zonec = ss[i]; - ss++; - utm_easting = strtod(ss, &ss); - while(*ss && !isdigit(*ss)) ss++; - utm_northing = strtod(ss, NULL); - } - break; - /* ALTITUDE CONVERSIONS ************************************************/ + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utmn); + break; + case XT_UTM_EASTING: + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + writebuff(buff, fmp->printfc, utme); + break; + + /* ALTITUDE CONVERSIONS**********************************************/ case XT_ALT_FEET: - /* altitude in feet as a decimal value */ - wpt->altitude = FEET_TO_METERS(atof(s)); - if (wpt->altitude < unknown_alt + 1) - wpt->altitude = unknown_alt; - break; + /* altitude in feet as a decimal value */ + writebuff(buff, fmp->printfc, + METERS_TO_FEET(wpt->altitude)); + break; case XT_ALT_METERS: - /* altitude in meters as a decimal value */ - wpt->altitude = atof(s); - if (wpt->altitude < unknown_alt + 1) - wpt->altitude = unknown_alt; - break; - - /* PATH CONVERSIONS ************************************************/ + /* altitude in meters as a decimal value */ + writebuff(buff, fmp->printfc, + wpt->altitude); + break; + + /* DISTANCE CONVERSIONS**********************************************/ + case XT_PATH_DISTANCE_MILES: + /* path (route/track) distance in miles */ + writebuff(buff, fmp->printfc, pathdist); + break; + case XT_PATH_DISTANCE_KM: + /* path (route/track) distance in */ + writebuff(buff, fmp->printfc, pathdist * 5280*12*2.54/100/1000); + break; case XT_PATH_SPEED: - WAYPT_SET(wpt, speed, atof(s)); - break; + writebuff(buff, fmp->printfc, wpt->speed); + break; case XT_PATH_SPEED_KPH: - WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_KPH(wpt->speed)); + break; case XT_PATH_SPEED_MPH: - WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_MPH(wpt->speed)); + break; case XT_PATH_SPEED_KNOTS: - WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s))); - break; + writebuff(buff, fmp->printfc, MPS_TO_KNOTS(wpt->speed)); + break; case XT_PATH_COURSE: - WAYPT_SET(wpt, course, atof(s)); - break; + writebuff(buff, fmp->printfc, wpt->course); + break; - /* TIME CONVERSIONS ***************************************************/ + /* HEART RATE CONVERSION***********************************************/ + case XT_HEART_RATE: + writebuff(buff, fmp->printfc, wpt->heartrate); + break; + /* CADENCE CONVERSION***********************************************/ + case XT_CADENCE: + writebuff(buff, fmp->printfc, wpt->cadence); + break; + /* TIME CONVERSIONS**************************************************/ case XT_EXCEL_TIME: - /* Time as Excel Time */ - wpt->creation_time = EXCEL_TO_TIMET(atof(s)); - break; + /* creation time as an excel (double) time */ + writebuff(buff, fmp->printfc, TIMET_TO_EXCEL(wpt->creation_time)); + break; case XT_TIMET_TIME: - /* Time as time_t */ - wpt->creation_time = atol(s); - break; + /* time as a time_t variable */ + writebuff(buff, fmp->printfc, wpt->creation_time); + break; case XT_YYYYMMDD_TIME: - wpt->creation_time = yyyymmdd_to_time(s); - break; + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time)); + break; case XT_GMT_TIME: - wpt->creation_time += sscanftime(s, fmp->printfc, 1); - break; + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1); + break; case XT_LOCAL_TIME: - wpt->creation_time += sscanftime(s, fmp->printfc, 0); - break; - /* Useful when time and date are in separate fields - GMT / Local offset is handled by the two cases above */ + writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0); + break; case XT_HMSG_TIME: + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1); + break; case XT_HMSL_TIME: - wpt->creation_time += addhms(s, fmp->printfc); - break; - case XT_ISO_TIME: - case XT_ISO_TIME_MS: - wpt->creation_time = xml_parse_time(s, &wpt->microseconds); - break; - case XT_NET_TIME: - dotnet_time_to_time_t(atof(s), &wpt->creation_time, &wpt->microseconds); - break; + writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0); + break; + case XT_ISO_TIME: + writetime(buff, sizeof buff, "%Y-%m-%dT%H:%M:%SZ", wpt->creation_time, 1); + break; + case XT_ISO_TIME_MS: + xml_fill_in_time(buff, wpt->creation_time, + wpt->microseconds, XML_LONG_TIME); + break; case XT_GEOCACHE_LAST_FOUND: - waypt_alloc_gc_data(wpt)->last_found = yyyymmdd_to_time(s); - break; + writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data->last_found)); + break; - /* GEOCACHING STUFF ***************************************************/ + /* GEOCACHE STUFF **************************************************/ case XT_GEOCACHE_DIFF: - /* Geocache Difficulty as an int */ - waypt_alloc_gc_data(wpt)->diff = atof(s) * 10; - break; + /* Geocache Difficulty as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data->diff / 10.0); + field_is_unknown = !wpt->gc_data->diff; + break; case XT_GEOCACHE_TERR: - /* Geocache Terrain as an int */ - waypt_alloc_gc_data(wpt)->terr = atof(s) * 10; - break; - case XT_GEOCACHE_TYPE: - /* Geocache Type */ - waypt_alloc_gc_data(wpt)->type = gs_mktype(s); - break; + /* Geocache Terrain as a double */ + writebuff(buff, fmp->printfc, wpt->gc_data->terr / 10.0); + field_is_unknown = !wpt->gc_data->terr; + break; case XT_GEOCACHE_CONTAINER: - waypt_alloc_gc_data(wpt)->container = gs_mkcont(s); - break; + /* Geocache Container */ + writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data->container)); + field_is_unknown = wpt->gc_data->container == gc_unknown; + break; + case XT_GEOCACHE_TYPE: + /* Geocache Type */ + writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data->type)); + field_is_unknown = wpt->gc_data->type == gt_unknown; + break; case XT_GEOCACHE_HINT: - waypt_alloc_gc_data(wpt)->hint = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->hint)); + field_is_unknown = !wpt->gc_data->hint; + break; case XT_GEOCACHE_PLACER: - waypt_alloc_gc_data(wpt)->placer = csv_stringtrim(s, "", 0); - break; + writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->placer)); + field_is_unknown = !wpt->gc_data->placer; + break; case XT_GEOCACHE_ISAVAILABLE: - gc_data = waypt_alloc_gc_data(wpt); - if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) - gc_data->is_available = status_false; - else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) - gc_data->is_available = status_true; - else - gc_data->is_available = status_unknown; - break; + if (wpt->gc_data->is_available == status_false) { + writebuff(buff, fmp->printfc, "False"); + } else if (wpt->gc_data->is_available == status_true) { + writebuff(buff, fmp->printfc, "True"); + } else { + writebuff(buff, fmp->printfc, "Unknown"); + } + break; case XT_GEOCACHE_ISARCHIVED: - gc_data = waypt_alloc_gc_data(wpt); - if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "False") == 0 ) - gc_data->is_archived = status_false; - else if ( case_ignore_strcmp(csv_stringtrim(s, "", 0), "True") == 0 ) - gc_data->is_archived = status_true; - else - gc_data->is_archived = status_unknown; - break; - - /* GPS STUFF *******************************************************/ + if (wpt->gc_data->is_archived == status_false) { + writebuff(buff, fmp->printfc, "False"); + } else if (wpt->gc_data->is_archived == status_true) { + writebuff(buff, fmp->printfc, "True"); + } else { + writebuff(buff, fmp->printfc, "Unknown"); + } + break; + /* Tracks and Routes ***********************************************/ + case XT_TRACK_NAME: + if (csv_track) { + writebuff(buff, fmp->printfc, NONULL(csv_track->rte_name)); + } + break; + case XT_ROUTE_NAME: + if (csv_route) { + writebuff(buff, fmp->printfc, NONULL(csv_route->rte_name)); + } + break; + + /* GPS STUFF *******************************************************/ case XT_GPS_HDOP: - wpt->hdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->hdop); + field_is_unknown = !wpt->hdop; + break; case XT_GPS_VDOP: - wpt->vdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->vdop); + field_is_unknown = !wpt->vdop; + break; case XT_GPS_PDOP: - wpt->pdop = atof(s); - break; + writebuff(buff, fmp->printfc, wpt->pdop); + field_is_unknown = !wpt->pdop; + break; case XT_GPS_SAT: - wpt->sat = atoi(s); - break; - case XT_GPS_FIX: - wpt->fix = (fix_type)(atoi(s)-(fix_type)1); - if ( wpt->fix < fix_2d) { - if (!case_ignore_strcmp(s, "none")) - wpt->fix = fix_none; - else if (!case_ignore_strcmp(s, "dgps")) - wpt->fix = fix_dgps; - else if (!case_ignore_strcmp(s, "pps")) - wpt->fix = fix_pps; - else - wpt->fix = fix_unknown; - } - break; - /* Tracks and routes *********************************************/ - case XT_ROUTE_NAME: - if (csv_route) csv_route->rte_name = csv_stringtrim(s, enclosure, 0); - break; - case XT_TRACK_NEW: - if (atoi(s) && csv_track && !QUEUE_EMPTY(&csv_track->Q)) { - *trk = route_head_alloc(); - csv_track = *trk; - - track_add_head(*trk); - } - break; - case XT_TRACK_NAME: - if (!csv_track) { - csv_track = route_head_alloc(); - } - csv_track->rte_name = csv_stringtrim(s, enclosure, 0); - break; - - /* OTHER STUFF ***************************************************/ - case XT_PATH_DISTANCE_MILES: - /* Ignored on input */ - break; - case XT_HEART_RATE: - wpt->heartrate = atoi(s); - break; - case XT_CADENCE: - wpt->cadence = atoi(s); - break; - case XT_PATH_DISTANCE_KM: - /* Ignored on input */ - break; - /* GMSD ****************************************************************/ + writebuff(buff, fmp->printfc, wpt->sat); + field_is_unknown = !wpt->sat; + break; + case XT_GPS_FIX: { + char *fix = NULL; + switch (wpt->fix) { + case fix_unknown: + field_is_unknown = 1; + fix = "Unknown"; + break; + case fix_none: + fix = "None"; + break; + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + } + writebuff(buff, fmp->printfc, fix); + } + break; + /* GMSD ************************************************************/ case XT_COUNTRY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(country, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(country, "")); + } + break; case XT_STATE: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(state, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(state, "")); + } + break; case XT_CITY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(city, csv_stringtrim(s, enclosure, 0)); - } - break; - case XT_STREET_ADDR: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(addr, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(city, "")); + } + break; case XT_POSTAL_CODE: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(postal_code, csv_stringtrim(s, enclosure, 0)); - } - break; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(postal_code, "")); + } + break; + case XT_STREET_ADDR: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(addr, "")); + } + break; case XT_PHONE_NR: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(phone_nr, csv_stringtrim(s, enclosure, 0)); - } - break; - case XT_FACILITY: { - garmin_fs_t *gmsd = gmsd_init(wpt); - GMSD_SET(facility, csv_stringtrim(s, enclosure, 0)); - } - break; - case -1: - if (strncmp(fmp->key, "LON_10E", 7) == 0) { - wpt->longitude = atof(s) / pow((double)10, atof(fmp->key+7)); - } else - if (strncmp(fmp->key, "LAT_10E", 7) == 0) { - wpt->latitude = atof(s) / pow((double)10, atof(fmp->key+7)); - } else { - warning( MYNAME ": Unknown style directive: %s\n", fmp->key); - } - break; - - default: - fatal("This can't happen\n"); - break; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(phone_nr, "")); } -} - -/*****************************************************************************/ -/* xcsv_data_read() - read input file, parsing lines, fields and handling */ -/* any data conversion (the input meat) */ -/*****************************************************************************/ -void -xcsv_data_read(void) -{ - char *buff; - char *s; - waypoint *wpt_tmp; - int linecount = 0; - queue *elem, *tmp; - field_map_t *fmp; - ogue_t *ogp; - route_head *rte = NULL; - route_head *trk = NULL; - utm_northing = 0; - utm_easting = 0; - utm_zone = 0; - utm_zonec = 'N'; - - csv_route = csv_track = NULL; - if (xcsv_file.datatype == trkdata) { - csv_track = trk; - } else - if (xcsv_file.datatype == rtedata) { - csv_route = rte; + break; + case XT_FACILITY: { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + writebuff(buff, fmp->printfc, GMSD_GET(facility, "")); } - - while ((buff = gbfgetstr(xcsv_file.xcsvfp))) { - if ((linecount == 0) && xcsv_file.xcsvfp->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - linecount++; - /* Whack trailing space; leading space may matter if our field sep - * is whitespace and we have leading whitespace. - */ - rtrim(buff); - - /* skip over x many lines on the top for the prologue... */ - if ((xcsv_file.prologue_lines) && ((linecount - 1) < - xcsv_file.prologue_lines)) { - continue; - } - - /* We should skip over epilogue lines also. Since we don't want to - * pre-read the file to know how many data lines we should be seeing, - * we take this cheap shot at the data and cross our fingers. - */ - - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *) elem; - if (strncmp(buff, ogp->val, strlen(ogp->val)) == 0) { - buff[0] = '\0'; - break; - } - } - - if (strlen(buff)) { - wpt_tmp = waypt_new(); - - s = buff; - s = csv_lineparse(s, xcsv_file.field_delimiter, "", linecount); - - if (QUEUE_EMPTY(&xcsv_file.ifield)) { - fatal(MYNAME ": attempt to read, but style '%s' has no IFIELDs in it.\n", xcsv_file.description? xcsv_file.description : "unknown"); - } - - /* reset the ifield queue */ - elem = QUEUE_FIRST(&xcsv_file.ifield); - - /* now rip the line apart, advancing the queue for each tear - * off the beginning of buff since there's no index into queue. - */ - while (s) { - fmp = (field_map_t *) elem; - xcsv_parse_val(s, wpt_tmp, fmp, &trk); - - elem = QUEUE_NEXT(elem); - - if (elem == &xcsv_file.ifield) { - /* we've wrapped the queue. so stop parsing! */ - while (s) { - s=csv_lineparse(NULL, "\xff","",linecount); - } - break; - } - - s = csv_lineparse(NULL, xcsv_file.field_delimiter, "", - linecount); - } - - if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { - double alt; - GPS_Math_Known_Datum_To_WGS84_M(wpt_tmp->latitude, wpt_tmp->longitude, 0.0, - &wpt_tmp->latitude, &wpt_tmp->longitude, &alt, xcsv_file.gps_datum); - } - - if (utm_easting || utm_northing) { - GPS_Math_UTM_EN_To_Known_Datum(&wpt_tmp->latitude, - &wpt_tmp->longitude, - utm_easting, utm_northing, - utm_zone, utm_zonec, - DATUM_WGS84); - } - - switch(xcsv_file.datatype) { - case 0: - case wptdata: - waypt_add(wpt_tmp); - break; - case trkdata: - if (trk == NULL) { - trk = route_head_alloc(); - csv_track = trk; - track_add_head(trk); - } - track_add_wpt(trk, wpt_tmp); - break; - case rtedata: - if (rte == NULL) { - rte = route_head_alloc(); - csv_route = rte; - route_add_head(rte); - } - route_add_wpt(rte, wpt_tmp); - break; - default: ; - } - } - + break; + /* specials */ + case XT_FILENAME: + writebuff(buff, fmp->printfc, wpt->session->filename); + break; + case XT_FORMAT: + writebuff(buff, fmp->printfc, wpt->session->name); + break; + case -1: + if (strncmp(fmp->key, "LON_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lon * pow((double)10, atof(fmp->key+7))); + } else if (strncmp(fmp->key, "LAT_10E", 7) == 0) { + writebuff(buff, fmp->printfc, lat * pow((double)10, atof(fmp->key+7))); + } + break; + default: + warning(MYNAME ": Unknown style directive: %s\n", fmp->key); + break; } -} + obuff = csv_stringclean(buff, xcsv_file.badchars); -static void -xcsv_resetpathlen(const route_head *head) -{ - pathdist = 0; - oldlat = 999; - oldlon = 999; - csv_route = csv_track = NULL; - switch (xcsv_file.datatype) { - case trkdata: - csv_track = (route_head *) head; - break; - case rtedata: - csv_route = (route_head *) head; - break; - default: - break; + if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { + goto next; } -} -/*****************************************************************************/ -/* xcsv_waypt_pr() - write output file, handling output conversions */ -/* (the output meat) */ -/*****************************************************************************/ -static void -xcsv_waypt_pr(const waypoint *wpt) -{ - char buff[1024]; - char *shortname = NULL; - char *description = NULL; - char * anyname = NULL; - char * write_delimiter; - int i; - field_map_t *fmp; - queue *elem, *tmp; - double latitude, longitude; - int32 utmz; - double utme, utmn; - char utmzc; - - buff[0] = '\0'; - - if ( oldlon < 900 ) { - pathdist += radtomiles(gcdist(RAD(oldlat),RAD(oldlon), - RAD(wpt->latitude),RAD(wpt->longitude))); - } - longitude = oldlon = wpt->longitude; - latitude = oldlat = wpt->latitude; - - if (xcsv_file.field_delimiter && strcmp(xcsv_file.field_delimiter, "\\w") == 0) - write_delimiter = " "; - else - write_delimiter = xcsv_file.field_delimiter; - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(xcsv_file.mkshort_handle, wpt); - else - shortname = csv_stringclean(wpt->description, xcsv_file.badchars); - } else { - /* no shortname available -- let shortname default on output */ - } - } else{ - shortname = csv_stringclean(wpt->shortname, xcsv_file.badchars); - } - if (! wpt->description) { - if (shortname) { - description = csv_stringclean(shortname, xcsv_file.badchars); - } else { - /* no description -- let description default on output */ - } + /* As a special case (pronounced "horrible hack") we allow + * ""%s"" to smuggle bad characters through. + */ + if (0 == strcmp(fmp->printfc, "\"%s\"")) { + gbfprintf(xcsv_file.xcsvfp, "\"%s\"", obuff); } else { - description = csv_stringclean(wpt->description, xcsv_file.badchars); + gbfprintf(xcsv_file.xcsvfp, "%s", obuff); } - if (prefer_shortnames) { - if (description) { - xfree(description); - } - description = shortname; - } else if (description) { - char *odesc = description; - description = xstrdup(odesc); - xfree(odesc); - } - if ((xcsv_file.gps_datum > -1) && (xcsv_file.gps_datum != GPS_DATUM_WGS84)) { - double alt; - GPS_Math_WGS84_To_Known_Datum_M(latitude, longitude, 0.0, - &latitude, &longitude, &alt, xcsv_file.gps_datum); - } - - i = 0; - QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { - char *obuff; - double lat = latitude; - double lon = longitude; - /* - * A klunky concept. This should evaluate to true for any - * field if we think we don't have realistic value for it. - * This is used by the 'optional' attribute for suppressing - * fields on output. - */ - int field_is_unknown = 0; - - fmp = (field_map_t *) elem; - - if ((i != 0) && !(fmp->options & OPTIONS_NODELIM)) - gbfprintf (xcsv_file.xcsvfp, write_delimiter); - - if (fmp->options & OPTIONS_ABSOLUTE) { - lat = fabs(lat); - lon = fabs(lon); - } - - i++; -#define writebuff(b, fmt, data) snprintf(b, sizeof(b), fmt, data) - switch(fmp->hashed_key) { - case XT_IGNORE: - /* IGNORE -- Write the char printf conversion */ - writebuff(buff, fmp->printfc, ""); - break; - case XT_INDEX: - writebuff(buff, fmp->printfc, waypt_out_count + atoi(fmp->val)); - break; - case XT_CONSTANT: { - const char *cp = xcsv_get_char_from_constant_table(fmp->val); - if (cp) { - writebuff(buff, fmp->printfc, cp); - } else { - writebuff(buff, fmp->printfc, fmp->val); - } - } - break; - case XT_SHORTNAME: - writebuff(buff, fmp->printfc, - (shortname && *shortname) ? shortname : fmp->val); - break; - case XT_ANYNAME: - if (wpt->shortname) { - anyname = xstrdup(wpt->shortname); - } else - if (wpt->description) { - anyname = mkshort(xcsv_file.mkshort_handle, wpt->description); - } else - if (wpt->notes) { - anyname = xstrdup(wpt->notes); - } else - anyname = xstrdup(fmp->val); - - if ((anyname) && (global_opts.synthesize_shortnames)) { - anyname = xstrdup(shortname); - } - - writebuff(buff, fmp->printfc, anyname); - - xfree(anyname); - break; - case XT_DESCRIPTION: - writebuff(buff, fmp->printfc, - (description && *description) ? description : fmp->val); - break; - case XT_NOTES: - writebuff(buff, fmp->printfc, - (wpt->notes && *wpt->notes) ? wpt->notes : fmp->val); - break; - case XT_URL: { - int off = 0; - if (xcsv_urlbase) { - strcpy(buff, xcsv_urlbase); - off = strlen(xcsv_urlbase); - } - if (wpt->url) - snprintf(buff + off, sizeof(buff) - off, fmp->printfc, wpt->url); - else - strcpy(buff, (fmp->val && *fmp->val) ? fmp->val : "\"\""); - } - break; - case XT_URL_LINK_TEXT: - snprintf(buff, sizeof(buff), fmp->printfc, - (wpt->url_link_text && *wpt->url_link_text) ? wpt->url_link_text : fmp->val); - break; - case XT_ICON_DESCR: - writebuff(buff, fmp->printfc, - (wpt->icon_descr && *wpt->icon_descr) ? - wpt->icon_descr : fmp->val); - break; - - /* LATITUDE CONVERSION***********************************************/ - case XT_LAT_DECIMAL: - /* latitude as a pure decimal value */ - writebuff(buff, fmp->printfc, lat); - break; - case XT_LAT_DECIMALDIR: - /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, fabs(lat), - LAT_DIR(lat)); - break; - case XT_LAT_DIRDECIMAL: - /* latitude as a decimal value with N/S before it */ - snprintf(buff, sizeof(buff), fmp->printfc, - LAT_DIR(lat), - fabs(lat)); - break; - case XT_LAT_INT32DEG: - /* latitude as an integer offset from 0 degrees */ - writebuff(buff, fmp->printfc, - dec_to_intdeg(lat)); - break; - case XT_LAT_DDMMDIR: - /*latitude as (degrees * 100) + decimal minutes, with N/S after it */ - dec_to_human( buff, fmp->printfc, "SN", degrees2ddmm(lat) ); - break; - case XT_LAT_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "SN", lat ); - break; - case XT_LAT_NMEA: - writebuff(buff, fmp->printfc, degrees2ddmm(lat)); - break; - // case XT_LAT_10E is handled outside the switch. - /* LONGITUDE CONVERSIONS*********************************************/ - case XT_LON_DECIMAL: - /* longitude as a pure decimal value */ - writebuff(buff, fmp->printfc, lon); - break; - case XT_LON_DECIMALDIR: - /* latitude as a decimal value with N/S after it */ - snprintf(buff, sizeof(buff), fmp->printfc, - fabs(lon), - LON_DIR(lon)); - break; - case XT_LON_DIRDECIMAL: - /* latitude as a decimal value with N/S before it */ - snprintf(buff, sizeof(buff), fmp->printfc, - LON_DIR(lon), - fabs(lon)); - break; - case XT_LON_INT32DEG: - /* longitudee as an integer offset from 0 degrees */ - writebuff(buff, fmp->printfc, - dec_to_intdeg(lon)); - break; - case XT_LON_DDMMDIR: - /* longidute as (degrees * 100) + decimal minutes, with W/E after it*/ - dec_to_human( buff, fmp->printfc, "WE", degrees2ddmm(lon) ); - break; - case XT_LON_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "WE", lon ); - break; - case XT_LATLON_HUMAN_READABLE: - dec_to_human( buff, fmp->printfc, "SN", lat ); - if ( !isspace(buff[strlen(buff)])) strcat( buff, " " ); - dec_to_human( buff+strlen(buff), fmp->printfc, "WE", - lon ); - break; - case XT_LON_NMEA: - writebuff(buff, fmp->printfc, degrees2ddmm(lon)); - break; - // case XT_LON_10E is handled outside the switch. - /* DIRECTIONS *******************************************************/ - case XT_LAT_DIR: - /* latitude N/S as a char */ - writebuff(buff, fmp->printfc, - LAT_DIR(lat)); - break; - case XT_LON_DIR: - /* longitude E/W as a char */ - writebuff(buff, fmp->printfc, - LON_DIR(lon)); - break; - - /* SPECIAL COORDINATES */ - case XT_MAP_EN_BNG: { - char map[3]; - double north, east; - if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) - fatal(MYNAME ": Position (%.5f/%.5f) outside of BNG.\n", - wpt->latitude, wpt->longitude); - snprintf(buff, sizeof(buff), fmp->printfc, map, (int)(east + 0.5), (int)(north + 0.5)); - } - break; - case XT_UTM: { - char tbuf[100]; - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - snprintf(tbuf, sizeof(tbuf), "%d%c %6.0f %7.0f", - utmz, utmzc, utme, utmn); - writebuff(buff, fmp->printfc, tbuf); - } - break; - case XT_UTM_ZONE: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmz); - break; - case XT_UTM_ZONEC: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmzc); - break; - case XT_UTM_ZONEF: { - char tbuf[10]; - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - tbuf[0] = 0; - snprintf(tbuf, sizeof(tbuf), "%d%c", utmz, utmzc); - writebuff(buff, fmp->printfc, tbuf); - } - break; - case XT_UTM_NORTHING: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utmn); - break; - case XT_UTM_EASTING: - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - writebuff(buff, fmp->printfc, utme); - break; - - /* ALTITUDE CONVERSIONS**********************************************/ - case XT_ALT_FEET: - /* altitude in feet as a decimal value */ - writebuff(buff, fmp->printfc, - METERS_TO_FEET(wpt->altitude)); - break; - case XT_ALT_METERS: - /* altitude in meters as a decimal value */ - writebuff(buff, fmp->printfc, - wpt->altitude); - break; - - /* DISTANCE CONVERSIONS**********************************************/ - case XT_PATH_DISTANCE_MILES: - /* path (route/track) distance in miles */ - writebuff( buff, fmp->printfc, pathdist ); - break; - case XT_PATH_DISTANCE_KM: - /* path (route/track) distance in */ - writebuff( buff, fmp->printfc, pathdist * 5280*12*2.54/100/1000 ); - break; - case XT_PATH_SPEED: - writebuff( buff, fmp->printfc, wpt->speed ); - break; - case XT_PATH_SPEED_KPH: - writebuff( buff, fmp->printfc, MPS_TO_KPH(wpt->speed)); - break; - case XT_PATH_SPEED_MPH: - writebuff( buff, fmp->printfc, MPS_TO_MPH(wpt->speed)); - break; - case XT_PATH_SPEED_KNOTS: - writebuff( buff, fmp->printfc, MPS_TO_KNOTS(wpt->speed)); - break; - case XT_PATH_COURSE: - writebuff( buff, fmp->printfc, wpt->course ); - break; - - /* HEART RATE CONVERSION***********************************************/ - case XT_HEART_RATE: - writebuff(buff, fmp->printfc, wpt->heartrate); - break; - /* CADENCE CONVERSION***********************************************/ - case XT_CADENCE: - writebuff(buff, fmp->printfc, wpt->cadence); - break; - /* TIME CONVERSIONS**************************************************/ - case XT_EXCEL_TIME: - /* creation time as an excel (double) time */ - writebuff(buff, fmp->printfc, TIMET_TO_EXCEL(wpt->creation_time)); - break; - case XT_TIMET_TIME: - /* time as a time_t variable */ - writebuff(buff, fmp->printfc, wpt->creation_time); - break; - case XT_YYYYMMDD_TIME: - writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->creation_time)); - break; - case XT_GMT_TIME: - writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); - break; - case XT_LOCAL_TIME: - writetime(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); - break; - case XT_HMSG_TIME: - writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 1 ); - break; - case XT_HMSL_TIME: - writehms(buff, sizeof buff, fmp->printfc, wpt->creation_time, 0 ); - break; - case XT_ISO_TIME: - writetime(buff, sizeof buff, "%Y-%m-%dT%H:%M:%SZ", wpt->creation_time, 1 ); - break; - case XT_ISO_TIME_MS: - xml_fill_in_time(buff, wpt->creation_time, - wpt->microseconds, XML_LONG_TIME); - break; - case XT_GEOCACHE_LAST_FOUND: - writebuff(buff, fmp->printfc, time_to_yyyymmdd(wpt->gc_data->last_found)); - break; - - /* GEOCACHE STUFF **************************************************/ - case XT_GEOCACHE_DIFF: - /* Geocache Difficulty as a double */ - writebuff(buff, fmp->printfc, wpt->gc_data->diff / 10.0); - field_is_unknown = !wpt->gc_data->diff; - break; - case XT_GEOCACHE_TERR: - /* Geocache Terrain as a double */ - writebuff(buff, fmp->printfc, wpt->gc_data->terr / 10.0); - field_is_unknown = !wpt->gc_data->terr; - break; - case XT_GEOCACHE_CONTAINER: - /* Geocache Container */ - writebuff(buff, fmp->printfc, gs_get_container(wpt->gc_data->container)); - field_is_unknown = wpt->gc_data->container == gc_unknown; - break; - case XT_GEOCACHE_TYPE: - /* Geocache Type */ - writebuff(buff, fmp->printfc, gs_get_cachetype(wpt->gc_data->type)); - field_is_unknown = wpt->gc_data->type == gt_unknown; - break; - case XT_GEOCACHE_HINT: - writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->hint)); - field_is_unknown = !wpt->gc_data->hint; - break; - case XT_GEOCACHE_PLACER: - writebuff(buff, fmp->printfc, NONULL(wpt->gc_data->placer)); - field_is_unknown = !wpt->gc_data->placer; - break; - case XT_GEOCACHE_ISAVAILABLE: - if ( wpt->gc_data->is_available == status_false ) - writebuff(buff, fmp->printfc, "False"); - else if ( wpt->gc_data->is_available == status_true ) - writebuff(buff, fmp->printfc, "True"); - else - writebuff(buff, fmp->printfc, "Unknown"); - break; - case XT_GEOCACHE_ISARCHIVED: - if ( wpt->gc_data->is_archived == status_false ) - writebuff(buff, fmp->printfc, "False"); - else if ( wpt->gc_data->is_archived == status_true ) - writebuff(buff, fmp->printfc, "True"); - else - writebuff(buff, fmp->printfc, "Unknown"); - break; - /* Tracks and Routes ***********************************************/ - case XT_TRACK_NAME: - if (csv_track) writebuff(buff, fmp->printfc, NONULL(csv_track->rte_name)); - break; - case XT_ROUTE_NAME: - if (csv_route) writebuff(buff, fmp->printfc, NONULL(csv_route->rte_name)); - break; - - /* GPS STUFF *******************************************************/ - case XT_GPS_HDOP: - writebuff(buff, fmp->printfc, wpt->hdop); - field_is_unknown = !wpt->hdop; - break; - case XT_GPS_VDOP: - writebuff(buff, fmp->printfc, wpt->vdop); - field_is_unknown = !wpt->vdop; - break; - case XT_GPS_PDOP: - writebuff(buff, fmp->printfc, wpt->pdop); - field_is_unknown = !wpt->pdop; - break; - case XT_GPS_SAT: - writebuff(buff, fmp->printfc, wpt->sat); - field_is_unknown = !wpt->sat; - break; - case XT_GPS_FIX: { - char *fix = NULL; - switch (wpt->fix) { - case fix_unknown: - field_is_unknown = 1; - fix = "Unknown"; - break; - case fix_none: - fix = "None"; - break; - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - } - writebuff(buff, fmp->printfc, fix); - } - break; - /* GMSD ************************************************************/ - case XT_COUNTRY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(country, "")); - } - break; - case XT_STATE: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(state, "")); - } - break; - case XT_CITY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(city, "")); - } - break; - case XT_POSTAL_CODE: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(postal_code, "")); - } - break; - case XT_STREET_ADDR: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(addr, "")); - } - break; - case XT_PHONE_NR: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(phone_nr, "")); - } - break; - case XT_FACILITY: { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - writebuff(buff, fmp->printfc, GMSD_GET(facility, "")); - } - break; - /* specials */ - case XT_FILENAME: - writebuff(buff, fmp->printfc, wpt->session->filename); - break; - case XT_FORMAT: - writebuff(buff, fmp->printfc, wpt->session->name); - break; - case -1: - if (strncmp(fmp->key, "LON_10E", 7) == 0) { - writebuff(buff, fmp->printfc, lon * pow((double)10, atof(fmp->key+7))); - } else - if (strncmp(fmp->key, "LAT_10E", 7) == 0) { - writebuff(buff, fmp->printfc, lat * pow((double)10, atof(fmp->key+7))); - } - break; - default: - warning( MYNAME ": Unknown style directive: %s\n", fmp->key); - break; - } - obuff = csv_stringclean(buff, xcsv_file.badchars); - - if (field_is_unknown && fmp->options & OPTIONS_OPTIONAL) { - goto next; - } - - - /* As a special case (pronounced "horrible hack") we allow - * ""%s"" to smuggle bad characters through. - */ - if (0 == strcmp(fmp->printfc, "\"%s\"")) { - gbfprintf (xcsv_file.xcsvfp, "\"%s\"", obuff); - } else { - gbfprintf (xcsv_file.xcsvfp, "%s", obuff); - } - next: - xfree(obuff); - } + xfree(obuff); + } - gbfprintf (xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); - if (description && description != shortname) - xfree(description); + if (description && description != shortname) { + xfree(description); + } - if (shortname) - xfree(shortname); + if (shortname) { + xfree(shortname); + } - /* increment the index counter */ - waypt_out_count++; + /* increment the index counter */ + waypt_out_count++; } static void xcsv_noop(const route_head *wp) { - /* no-op */ + /* no-op */ } /*****************************************************************************/ @@ -2026,75 +2099,79 @@ xcsv_noop(const route_head *wp) void xcsv_data_write(void) { - queue *elem, *tmp; - ogue_t *ogp; - time_t time; - struct tm tm; - char tbuf[32]; - - /* reset the index counter */ - waypt_out_count = 0; - - time = gpsbabel_time; - if (time == 0) /* testo script ? */ - tm = *gmtime(&time); - else - tm = *localtime(&time); - - /* output prologue lines, if any. */ - QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { - char *cout, *ctmp; - ogp = (ogue_t *) elem; - - cout = xstrdup((ogp->val) ? ogp->val : ""); - - while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { - xfree(cout); - cout = ctmp; - } - - while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__DATE__")) { - strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); - ctmp = strsub(cout, "__DATE__", tbuf); - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__TIME__")) { - strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); - ctmp = strsub(cout, "__TIME__", tbuf); - xfree(cout); - cout = ctmp; - } - - while (strstr(cout, "__DATE_AND_TIME__")) { - strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); - ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); - xfree(cout); - cout = ctmp; - } - - gbfprintf(xcsv_file.xcsvfp, "%s", cout); - xfree(cout); - gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + queue *elem, *tmp; + ogue_t *ogp; + time_t time; + struct tm tm; + char tbuf[32]; + + /* reset the index counter */ + waypt_out_count = 0; + + time = gpsbabel_time; + if (time == 0) { /* testo script ? */ + tm = *gmtime(&time); + } else { + tm = *localtime(&time); + } + + /* output prologue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + char *cout, *ctmp; + ogp = (ogue_t *) elem; + + cout = xstrdup((ogp->val) ? ogp->val : ""); + + while ((ctmp = strsub(cout, "__FILE__", xcsv_file.fname))) { + xfree(cout); + cout = ctmp; } - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) - waypt_disp_all(xcsv_waypt_pr); - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) - route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) - track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + while ((ctmp = strsub(cout, "__VERSION__", (time == 0) ? "" : gpsbabel_version))) { + xfree(cout); + cout = ctmp; + } - /* output epilogue lines, if any. */ - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *) elem; - gbfprintf (xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + while (strstr(cout, "__DATE__")) { + strftime(tbuf, sizeof(tbuf), "%m/%d/%Y", &tm); + ctmp = strsub(cout, "__DATE__", tbuf); + xfree(cout); + cout = ctmp; + } + + while (strstr(cout, "__TIME__")) { + strftime(tbuf, sizeof(tbuf), "%H:%S:%M", &tm); + ctmp = strsub(cout, "__TIME__", tbuf); + xfree(cout); + cout = ctmp; } + + while (strstr(cout, "__DATE_AND_TIME__")) { + strftime(tbuf, sizeof(tbuf), "%a %b %d %H:%M:%S %Y", &tm); + ctmp = strsub(cout, "__DATE_AND_TIME__", tbuf); + xfree(cout); + cout = ctmp; + } + + gbfprintf(xcsv_file.xcsvfp, "%s", cout); + xfree(cout); + gbfprintf(xcsv_file.xcsvfp, "%s", xcsv_file.record_delimiter); + } + + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { + waypt_disp_all(xcsv_waypt_pr); + } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == rtedata)) { + route_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == trkdata)) { + track_disp_all(xcsv_resetpathlen,xcsv_noop,xcsv_waypt_pr); + } + + /* output epilogue lines, if any. */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *) elem; + gbfprintf(xcsv_file.xcsvfp, "%s%s", ogp->val, xcsv_file.record_delimiter); + } } #endif diff --git a/gpsbabel/csv_util.h b/gpsbabel/csv_util.h index ab29e3771..1d7c06386 100644 --- a/gpsbabel/csv_util.h +++ b/gpsbabel/csv_util.h @@ -31,7 +31,7 @@ char * csv_lineparse(const char *stringstart, const char *delimited_by, const char *enclosed_in, const int line_no); void -human_to_dec( const char *instr, double *outlat, double *outlon, int which ); +human_to_dec(const char *instr, double *outlat, double *outlon, int which); char * #ifndef DEBUG_MEM @@ -41,28 +41,28 @@ CSV_STRINGCLEAN(const char *string, const char *chararray,DEBUG_PARAMS); #define csv_stringclean(s,c) CSV_STRINGCLEAN(s,c,__FILE__,__LINE__) #endif -void +void xcsv_data_read(void); -void +void xcsv_data_write(void); -void -xcsv_file_init(void); +void +xcsv_file_init(void); -void +void xcsv_prologue_add(char *); -void +void xcsv_epilogue_add(char *); -void +void xcsv_ifield_add(char *, char *, char *); -void +void xcsv_ofield_add(char *, char *, char *, int options); -void +void xcsv_destroy_style(void); const char * @@ -77,65 +77,65 @@ xcsv_get_char_from_constant_table(char *key); #define OPTIONS_ABSOLUTE 2 #define OPTIONS_OPTIONAL 3 typedef struct field_map { - queue Q; - char * key; - char * val; - char * printfc; - int hashed_key; - int options; + queue Q; + char * key; + char * val; + char * printfc; + int hashed_key; + int options; } field_map_t; /* a queuing struct for prologues / epilogues */ typedef struct ogue { - queue Q; - char * val; + queue Q; + char * val; } ogue_t; /* something to map config file constants to chars */ typedef struct char_map { - const char * key; - const char * chars; + const char * key; + const char * chars; } char_map_t; -/* - * a type describing all the wonderful elements of xcsv files, in a +/* + * a type describing all the wonderful elements of xcsv files, in a * nutshell. */ typedef struct { - int is_internal; /* bool - is internal (1) or parsed (0) */ - - int prologue_lines; /* # of lines to ignore at top of the file */ - int epilogue_lines; /* # of lines to ignore at bottom of file */ - - /* header lines for writing at the top of the file. */ - queue prologue; - - /* footer lines for writing at the bottom of the file. */ - queue epilogue; - - char * field_delimiter; /* comma, quote, etc... */ - char * record_delimiter; /* newline, c/r, etc... */ - - char * badchars; /* characters we never write to output */ - - queue ifield; /* input field mapping */ - queue * ofield; /* output field mapping */ - - int ifield_ct; /* actual # of ifields */ - int ofield_ct; /* actual # of ofields */ - - gbfile * xcsvfp; /* ptr to current *open* data file */ - char * fname; /* ptr to filename of above. */ - - char * description; /* Description for help text */ - char * extension; /* preferred filename extension (for wrappers)*/ - - short_handle mkshort_handle;/* handle for mkshort() */ - ff_type type; /* format type for GUI wrappers. */ - - int gps_datum; /* result of GPS_Lookup_Datum_Index */ - gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ - /* ... or ZERO to keep the old behaviour */ + int is_internal; /* bool - is internal (1) or parsed (0) */ + + int prologue_lines; /* # of lines to ignore at top of the file */ + int epilogue_lines; /* # of lines to ignore at bottom of file */ + + /* header lines for writing at the top of the file. */ + queue prologue; + + /* footer lines for writing at the bottom of the file. */ + queue epilogue; + + char * field_delimiter; /* comma, quote, etc... */ + char * record_delimiter; /* newline, c/r, etc... */ + + char * badchars; /* characters we never write to output */ + + queue ifield; /* input field mapping */ + queue * ofield; /* output field mapping */ + + int ifield_ct; /* actual # of ifields */ + int ofield_ct; /* actual # of ofields */ + + gbfile * xcsvfp; /* ptr to current *open* data file */ + char * fname; /* ptr to filename of above. */ + + char * description; /* Description for help text */ + char * extension; /* preferred filename extension (for wrappers)*/ + + short_handle mkshort_handle;/* handle for mkshort() */ + ff_type type; /* format type for GUI wrappers. */ + + int gps_datum; /* result of GPS_Lookup_Datum_Index */ + gpsdata_type datatype; /* can be wptdata, rtedata or trkdata */ + /* ... or ZERO to keep the old behaviour */ } xcsv_file_t; diff --git a/gpsbabel/defs.h b/gpsbabel/defs.h index 841caaf30..7377c0656 100644 --- a/gpsbabel/defs.h +++ b/gpsbabel/defs.h @@ -96,8 +96,8 @@ #define KNOTS_TO_MPS(a) (KPH_TO_MPS((a)*1.852)) /* - * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in - * C99 (albeit with slightly different semantics) but it isn't in C89. + * Snprintf is in SUS (so it's in most UNIX-like substance) and it's in + * C99 (albeit with slightly different semantics) but it isn't in C89. * This tweaks allows us to use snprintf on the holdout. */ #if __WIN32__ @@ -126,10 +126,10 @@ # define GB_PATHSEP '/' #endif -/* +/* * Toss in some GNU C-specific voodoo for checking. */ -#if __GNUC__ +#if __GNUC__ # define PRINTFLIKE(x,y) __attribute__ ((__format__ (__printf__, (x), (y)))) # define NORETURN void __attribute__ ((__noreturn__)) #else @@ -157,30 +157,30 @@ ((struct_type *)((char *)(memberp) - offsetof(struct_type, member_name))) typedef enum { - fix_unknown=-1, - fix_none=0, - fix_2d=1, - fix_3d, - fix_dgps, - fix_pps + fix_unknown=-1, + fix_none=0, + fix_2d=1, + fix_3d, + fix_dgps, + fix_pps } fix_type; typedef enum { - status_unknown=0, - status_true, - status_false + status_unknown=0, + status_true, + status_false } status_type; - + /* * Define globally on which kind of data gpsbabel is working. * Important for "file types" that are essentially a communication * protocol for a receiver, like the Magellan serial data. */ typedef enum { - trkdata = 1 , - wptdata, - rtedata, - posndata + trkdata = 1 , + wptdata, + rtedata, + posndata } gpsdata_type; #define NOTHINGMASK 0 @@ -197,16 +197,16 @@ typedef enum { #define doing_posn ((global_opts.masked_objective & POSNDATAMASK) == POSNDATAMASK) typedef struct { - int synthesize_shortnames; - int debug_level; - gpsdata_type objective; - unsigned int masked_objective; - int verbose_status; /* set by GUI wrappers for status */ - int smart_icons; - int smart_names; - cet_cs_vec_t *charset; - char *charset_name; - inifile_t *inifile; + int synthesize_shortnames; + int debug_level; + gpsdata_type objective; + unsigned int masked_objective; + int verbose_status; /* set by GUI wrappers for status */ + int smart_icons; + int smart_names; + cet_cs_vec_t *charset; + char *charset_name; + inifile_t *inifile; } global_options; extern global_options global_opts; @@ -225,70 +225,70 @@ extern int geocaches_present; #define XML_LONG_TIME 2 /* - * Extended data if waypoint happens to represent a geocache. This is + * Extended data if waypoint happens to represent a geocache. This is * totally voluntary data... */ typedef enum { - gt_unknown = 0 , - gt_traditional, - gt_multi, - gt_virtual, - gt_letterbox, - gt_event, - gt_suprise, - gt_webcam, - gt_earth, - gt_locationless, - gt_benchmark, /* Extension to Groundspeak for GSAK */ - gt_cito, - gt_ape, - gt_mega, - gt_wherigo + gt_unknown = 0 , + gt_traditional, + gt_multi, + gt_virtual, + gt_letterbox, + gt_event, + gt_suprise, + gt_webcam, + gt_earth, + gt_locationless, + gt_benchmark, /* Extension to Groundspeak for GSAK */ + gt_cito, + gt_ape, + gt_mega, + gt_wherigo } geocache_type; typedef enum { - gc_unknown = 0, - gc_micro, - gc_other, - gc_regular, - gc_large, - gc_virtual, - gc_small + gc_unknown = 0, + gc_micro, + gc_other, + gc_regular, + gc_large, + gc_virtual, + gc_small } geocache_container; typedef struct { - int is_html; - char *utfstring; + int is_html; + char *utfstring; } utf_string; typedef struct { - int id; /* The decimal cache number */ - geocache_type type:5; - geocache_container container:4; - unsigned int diff:6; /* (multiplied by ten internally) */ - unsigned int terr:6; /* (likewise) */ - status_type is_archived:2; - status_type is_available:2; - time_t exported; - time_t last_found; - char *placer; /* Placer name */ - int placer_id; /* Placer id */ - char *hint; /* all these UTF8, XML entities removed, May be not HTML. */ - utf_string desc_short; - utf_string desc_long; + int id; /* The decimal cache number */ + geocache_type type:5; + geocache_container container:4; + unsigned int diff:6; /* (multiplied by ten internally) */ + unsigned int terr:6; /* (likewise) */ + status_type is_archived:2; + status_type is_available:2; + time_t exported; + time_t last_found; + char *placer; /* Placer name */ + int placer_id; /* Placer id */ + char *hint; /* all these UTF8, XML entities removed, May be not HTML. */ + utf_string desc_short; + utf_string desc_long; } geocache_data ; typedef struct xml_tag { - char *tagname; - char *cdata; - int cdatalen; - char *parentcdata; - int parentcdatalen; - char **attributes; - struct xml_tag *parent; - struct xml_tag *sibling; - struct xml_tag *child; + char *tagname; + char *cdata; + int cdatalen; + char *parentcdata; + int parentcdatalen; + char **attributes; + struct xml_tag *parent; + struct xml_tag *sibling; + struct xml_tag *child; } xml_tag ; typedef void (*fs_destroy)(void *); @@ -296,12 +296,12 @@ typedef void (*fs_copy)(void **, void *); typedef void (*fs_convert)(void *); typedef struct format_specific_data { - long type; - struct format_specific_data *next; - - fs_destroy destroy; - fs_copy copy; - fs_convert convert; + long type; + struct format_specific_data *next; + + fs_destroy destroy; + fs_copy copy; + fs_convert convert; } format_specific_data; typedef struct { @@ -310,17 +310,17 @@ typedef struct { } gb_color; -format_specific_data *fs_chain_copy( format_specific_data *source ); -void fs_chain_destroy( format_specific_data *chain ); -format_specific_data *fs_chain_find( format_specific_data *chain, long type ); -void fs_chain_add( format_specific_data **chain, format_specific_data *data ); +format_specific_data *fs_chain_copy(format_specific_data *source); +void fs_chain_destroy(format_specific_data *chain); +format_specific_data *fs_chain_find(format_specific_data *chain, long type); +void fs_chain_add(format_specific_data **chain, format_specific_data *data); typedef struct fs_xml { - format_specific_data fs; - xml_tag *tag; + format_specific_data fs; + xml_tag *tag; } fs_xml; -fs_xml *fs_xml_alloc( long type ); +fs_xml *fs_xml_alloc(long type); #define FS_GPX 0x67707800L #define FS_AN1W 0x616e3177L @@ -333,33 +333,33 @@ fs_xml *fs_xml_alloc( long type ); * Structures and functions for multiple URLs per waypoint. */ typedef struct url_link { - struct url_link *url_next; - char *url; - char *url_link_text; + struct url_link *url_next; + char *url; + char *url_link_text; } url_link; /* * Misc bitfields inside struct waypoint; */ typedef struct { - unsigned int icon_descr_is_dynamic:1; - unsigned int shortname_is_synthetic:1; - unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ - unsigned int fmt_use:1; /* lightweight "extra data" */ - /* "flagged fields" */ - unsigned int temperature:1; /* temperature field is set */ - unsigned int proximity:1; /* proximity field is set */ - unsigned int course:1; /* course field is set */ - unsigned int speed:1; /* speed field is set */ - unsigned int depth:1; /* depth field is set */ - /* !ToDo! - unsigned int altitude:1; /+ altitude field is set +/ - ... and others - */ - unsigned int is_split:1; /* the waypoint represents a split */ - unsigned int new_trkseg:1; /* True if first in new trkseg. */ - - + unsigned int icon_descr_is_dynamic:1; + unsigned int shortname_is_synthetic:1; + unsigned int cet_converted:1; /* strings are converted to UTF8; interesting only for input */ + unsigned int fmt_use:1; /* lightweight "extra data" */ + /* "flagged fields" */ + unsigned int temperature:1; /* temperature field is set */ + unsigned int proximity:1; /* proximity field is set */ + unsigned int course:1; /* course field is set */ + unsigned int speed:1; /* speed field is set */ + unsigned int depth:1; /* depth field is set */ + /* !ToDo! + unsigned int altitude:1; /+ altitude field is set +/ + ... and others + */ + unsigned int is_split:1; /* the waypoint represents a split */ + unsigned int new_trkseg:1; /* True if first in new trkseg. */ + + } wp_flags; // These are dicey as they're collected on read. Subsequent filters may change @@ -380,162 +380,162 @@ const global_trait* get_traits(); #define WAYPT_UNSET(wpt,member) wpt->wpt_flags.member = 0 #define WAYPT_HAS(wpt,member) (wpt->wpt_flags.member) /* - * This is a waypoint, as stored in the GPSR. It tries to not + * This is a waypoint, as stored in the GPSR. It tries to not * cater to any specific model or protocol. Anything that needs to * be truncated, edited, or otherwise trimmed should be done on the * way to the target. */ typedef struct { - queue Q; /* Master waypoint q. Not for use + queue Q; /* Master waypoint q. Not for use by modules. */ - double latitude; /* Degrees */ - double longitude; /* Degrees */ - double altitude; /* Meters. */ - - /* - * The "thickness" of a waypoint; adds an element of 3D. Can be - * used to construct rudimentary polygons for, say, airspace - * definitions. The units are meters. - */ - double depth; - - /* - * An alarm trigger value that can be considered to be a circle - * surrounding a waypoint (or cylinder if depth is also defined). - * The units are meters. - */ - double proximity; - - /* shortname is a waypoint name as stored in receiver. It should - * strive to be, well, short, and unique. Enforcing length and - * character restrictions is the job of the output. A typical - * minimum length for shortname is 6 characters for NMEA units, - * 8 for Magellan and 10 for Vista. These are only guidelines. - */ - char *shortname; - /* - * description is typically a human readable description of the - * waypoint. It may be used as a comment field in some receivers. - * These are probably under 40 bytes, but that's only a guideline. - */ - char *description; - /* - * notes are relatively long - over 100 characters - prose associated - * with the above. Unlike shortname and description, these are never - * used to compute anything else and are strictly "passed through". - * Few formats support this. - */ - char *notes; - - /* This is a bit icky. Multiple waypoint support is an - * afterthought and I don't want to change our data structures. - * So we have the first in the waypoint itself and subsequent - * ones in a linked list. - * We also use an implicit anonymous union here, so these three - * members must match struct url_link... - */ - struct url_link *url_next; - char *url; - char *url_link_text; - - wp_flags wpt_flags; - const char *icon_descr; - time_t creation_time; /* standardized in UTC/GMT */ - int microseconds; /* Optional millionths of a second. */ - - /* - * route priority is for use by the simplify filter. If we have - * some reason to believe that the route point is more important, - * we can give it a higher (numerically; 0 is the lowest) priority. - * This causes it to be removed last. - * This is currently used by the saroute input filter to give named - * waypoints (representing turns) a higher priority. - * This is also used by the google input filter because they were - * nice enough to use exactly the same priority scheme. - */ - int route_priority; - - /* Optional dilution of precision: positional, horizontal, veritcal. - * 1 <= dop <= 50 - */ - float hdop; - float vdop; - float pdop; - float course; /* Optional: degrees true */ - float speed; /* Optional: meters per second. */ - fix_type fix; /* Optional: 3d, 2d, etc. */ - int sat; /* Optional: number of sats used for fix */ - - unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ - unsigned char cadence; /* revolutions per minute */ - float power; /* watts, as measured by cyclists */ - float temperature; /* Degrees celsius */ - const geocache_data *gc_data; - format_specific_data *fs; - session_t *session; /* pointer to a session struct */ - void *extra_data; /* Extra data added by, say, a filter. */ + double latitude; /* Degrees */ + double longitude; /* Degrees */ + double altitude; /* Meters. */ + + /* + * The "thickness" of a waypoint; adds an element of 3D. Can be + * used to construct rudimentary polygons for, say, airspace + * definitions. The units are meters. + */ + double depth; + + /* + * An alarm trigger value that can be considered to be a circle + * surrounding a waypoint (or cylinder if depth is also defined). + * The units are meters. + */ + double proximity; + + /* shortname is a waypoint name as stored in receiver. It should + * strive to be, well, short, and unique. Enforcing length and + * character restrictions is the job of the output. A typical + * minimum length for shortname is 6 characters for NMEA units, + * 8 for Magellan and 10 for Vista. These are only guidelines. + */ + char *shortname; + /* + * description is typically a human readable description of the + * waypoint. It may be used as a comment field in some receivers. + * These are probably under 40 bytes, but that's only a guideline. + */ + char *description; + /* + * notes are relatively long - over 100 characters - prose associated + * with the above. Unlike shortname and description, these are never + * used to compute anything else and are strictly "passed through". + * Few formats support this. + */ + char *notes; + + /* This is a bit icky. Multiple waypoint support is an + * afterthought and I don't want to change our data structures. + * So we have the first in the waypoint itself and subsequent + * ones in a linked list. + * We also use an implicit anonymous union here, so these three + * members must match struct url_link... + */ + struct url_link *url_next; + char *url; + char *url_link_text; + + wp_flags wpt_flags; + const char *icon_descr; + time_t creation_time; /* standardized in UTC/GMT */ + int microseconds; /* Optional millionths of a second. */ + + /* + * route priority is for use by the simplify filter. If we have + * some reason to believe that the route point is more important, + * we can give it a higher (numerically; 0 is the lowest) priority. + * This causes it to be removed last. + * This is currently used by the saroute input filter to give named + * waypoints (representing turns) a higher priority. + * This is also used by the google input filter because they were + * nice enough to use exactly the same priority scheme. + */ + int route_priority; + + /* Optional dilution of precision: positional, horizontal, veritcal. + * 1 <= dop <= 50 + */ + float hdop; + float vdop; + float pdop; + float course; /* Optional: degrees true */ + float speed; /* Optional: meters per second. */ + fix_type fix; /* Optional: 3d, 2d, etc. */ + int sat; /* Optional: number of sats used for fix */ + + unsigned char heartrate; /* Beats/min. likely to get moved to fs. */ + unsigned char cadence; /* revolutions per minute */ + float power; /* watts, as measured by cyclists */ + float temperature; /* Degrees celsius */ + const geocache_data *gc_data; + format_specific_data *fs; + session_t *session; /* pointer to a session struct */ + void *extra_data; /* Extra data added by, say, a filter. */ } waypoint; typedef struct { - queue Q; /* Link onto parent list. */ - queue waypoint_list; /* List of child waypoints */ - char *rte_name; - char *rte_desc; - char *rte_url; - int rte_num; - int rte_waypt_ct; /* # waypoints in waypoint list */ - format_specific_data *fs; - unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ - gb_color line_color; /* Optional line color for rendering */ - int line_width; /* in pixels (sigh). < 0 is unknown. */ - session_t *session; /* pointer to a session struct */ + queue Q; /* Link onto parent list. */ + queue waypoint_list; /* List of child waypoints */ + char *rte_name; + char *rte_desc; + char *rte_url; + int rte_num; + int rte_waypt_ct; /* # waypoints in waypoint list */ + format_specific_data *fs; + unsigned short cet_converted; /* strings are converted to UTF8; interesting only for input */ + gb_color line_color; /* Optional line color for rendering */ + int line_width; /* in pixels (sigh). < 0 is unknown. */ + session_t *session; /* pointer to a session struct */ } route_head; /* * Structure of recomputed track/roue data. */ typedef struct { - double distance_meters; - double max_alt; /* unknown_alt => invalid */ - double min_alt; /* -unknown_alt => invalid */ - double max_spd; /* Meters/sec */ - double min_spd; /* Meters/sec */ - double avg_hrt; /* Avg Heartrate */ - double avg_cad; /* Avg Cadence */ - time_t start; /* Min time */ - time_t end; /* Max time */ - int min_hrt; /* Min Heartrate */ - int max_hrt; /* Max Heartrate */ - int max_cad; /* Max Cadence */ + double distance_meters; + double max_alt; /* unknown_alt => invalid */ + double min_alt; /* -unknown_alt => invalid */ + double max_spd; /* Meters/sec */ + double min_spd; /* Meters/sec */ + double avg_hrt; /* Avg Heartrate */ + double avg_cad; /* Avg Cadence */ + time_t start; /* Min time */ + time_t end; /* Max time */ + int min_hrt; /* Min Heartrate */ + int max_hrt; /* Max Heartrate */ + int max_cad; /* Max Cadence */ } computed_trkdata; /* * Bounding box information. */ typedef struct { - double max_lat; - double max_lon; - double max_alt; /* unknown_alt => invalid */ - double min_lat; - double min_lon; - double min_alt; /* -unknown_alt => invalid */ + double max_lat; + double max_lon; + double max_alt; /* unknown_alt => invalid */ + double min_lat; + double min_lon; + double min_alt; /* -unknown_alt => invalid */ } bounds; typedef struct { - volatile int request_terminate; + volatile int request_terminate; } posn_status; extern posn_status tracking_status; -typedef void (*ff_init) (char const *); -typedef void (*ff_deinit) (void); -typedef void (*ff_read) (void); -typedef void (*ff_write) (void); -typedef void (*ff_exit) (void); -typedef void (*ff_writeposn) (waypoint *); -typedef waypoint * (*ff_readposn) (posn_status *); +typedef void (*ff_init)(char const *); +typedef void (*ff_deinit)(void); +typedef void (*ff_read)(void); +typedef void (*ff_write)(void); +typedef void (*ff_exit)(void); +typedef void (*ff_writeposn)(waypoint *); +typedef waypoint * (*ff_readposn)(posn_status *); #ifndef DEBUG_MEM char * get_option(const char *iarglist, const char *argname); @@ -545,19 +545,19 @@ char *GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS); #define get_option(iarglist, argname) GET_OPTION(iarglist, argname, __FILE__, __LINE__) #endif -typedef void (*filter_init) (char const *); -typedef void (*filter_process) (void); -typedef void (*filter_deinit) (void); -typedef void (*filter_exit) (void); +typedef void (*filter_init)(char const *); +typedef void (*filter_process)(void); +typedef void (*filter_deinit)(void); +typedef void (*filter_exit)(void); -typedef void (*waypt_cb) (const waypoint *); +typedef void (*waypt_cb)(const waypoint *); typedef void (*route_hdr)(const route_head *); typedef void (*route_trl)(const route_head *); -void waypt_add (waypoint *); -waypoint * waypt_dupe (const waypoint *); +void waypt_add(waypoint *); +waypoint * waypt_dupe(const waypoint *); waypoint * waypt_new(void); -void waypt_del (waypoint *); -void waypt_free (waypoint *); +void waypt_del(waypoint *); +void waypt_free(waypoint *); void waypt_disp_all(waypt_cb); void waypt_disp_session(const session_t *se, waypt_cb cb); void waypt_init_bounds(bounds *bounds); @@ -571,7 +571,7 @@ void waypt_flush_all(void); unsigned int waypt_count(void); void set_waypt_count(unsigned int nc); void waypt_add_url(waypoint *wpt, char *link, char *url_link_text); -void free_gpx_extras (xml_tag * tag); +void free_gpx_extras(xml_tag * tag); void xcsv_setup_internal_style(const char *style_buf); void xcsv_read_internal_style(const char *style_buf); waypoint * find_waypt_by_name(const char *name); @@ -584,7 +584,7 @@ geocache_type gs_mktype(const char *t); geocache_container gs_mkcont(const char *t); route_head *route_head_alloc(void); -void route_add (waypoint *); +void route_add(waypoint *); void route_add_wpt(route_head *rte, waypoint *wpt); void route_del_wpt(route_head *rte, waypoint *wpt); void track_add_wpt(route_head *rte, waypoint *wpt); @@ -601,7 +601,7 @@ void route_disp_all(route_hdr, route_trl, waypt_cb); void track_disp_all(route_hdr, route_trl, waypt_cb); void route_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc); void track_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc); -void route_flush( queue *); +void route_flush(queue *); void route_flush_all(void); void route_flush_all_routes(void); void route_flush_all_tracks(void); @@ -611,23 +611,23 @@ unsigned int route_waypt_count(void); unsigned int route_count(void); unsigned int track_waypt_count(void); unsigned int track_count(void); -void route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ); +void route_copy(int *dst_count, int *dst_wpt_count, queue **dst, queue *src); void route_backup(signed int *count, queue **head_bak); -void route_restore( queue *head_bak); -void route_append( queue *src ); +void route_restore(queue *head_bak); +void route_append(queue *src); void track_backup(signed int *count, queue **head_bak); -void track_restore( queue *head_bak); -void track_append( queue *src ); -void route_flush( queue *head ); -void track_recompute( const route_head *trk, computed_trkdata **); +void track_restore(queue *head_bak); +void track_append(queue *src); +void route_flush(queue *head); +void track_recompute(const route_head *trk, computed_trkdata **); /* * All shortname functions take a shortname handle as the first arg. * This is an opaque pointer. Callers must not fondle the contents of it. */ typedef struct short_handle * short_handle; -#ifndef DEBUG_MEM -char *mkshort (short_handle, const char *); +#ifndef DEBUG_MEM +char *mkshort(short_handle, const char *); void *mkshort_new_handle(void); #else char *MKSHORT(short_handle, const char *, DEBUG_PARAMS); @@ -652,8 +652,8 @@ void setshort_is_utf8(short_handle h, const int is_utf8); */ #define VMFL_NOZERO (1 << 0) typedef struct vmem { - void *mem; /* visible memory object */ - size_t size; /* allocated size of object */ + void *mem; /* visible memory object */ + size_t size; /* allocated size of object */ } vmem_t; vmem_t vmem_alloc(size_t, int flags); void vmem_free(vmem_t*); @@ -668,7 +668,7 @@ void vmem_realloc(vmem_t*, size_t); #define ARGTYPE_FILE 0x00000005 #define ARGTYPE_OUTFILE 0x00000006 -/* REQUIRED means that the option is required to be set. +/* REQUIRED means that the option is required to be set. * See also BEGIN/END_REQ */ #define ARGTYPE_REQUIRED 0x40000000 @@ -677,19 +677,19 @@ void vmem_realloc(vmem_t*, size_t); #define ARGTYPE_HIDDEN 0x20000000 /* BEGIN/END_EXCL mark the beginning and end of an exclusive range of - * options. No more than one of the options in the range may be selected + * options. No more than one of the options in the range may be selected * or set. If exactly one must be set, use with BEGIN/END_REQ * Both of these flags set is just like neither set, so avoid doing that. */ #define ARGTYPE_BEGIN_EXCL 0x10000000 #define ARGTYPE_END_EXCL 0x08000000 -/* BEGIN/END_REQ mark the beginning and end of a required range of +/* BEGIN/END_REQ mark the beginning and end of a required range of * options. One or more of the options in the range MUST be selected or set. - * If exactly one must be set, use with BEGIN/END_EXCL + * If exactly one must be set, use with BEGIN/END_EXCL * Both of these flags set is synonymous with REQUIRED, so use that instead * for "groups" of exactly one option. */ #define ARGTYPE_BEGIN_REQ 0x04000000 -#define ARGTYPE_END_REQ 0x02000000 +#define ARGTYPE_END_REQ 0x02000000 #define ARGTYPE_TYPEMASK 0x00000fff #define ARGTYPE_FLAGMASK 0xfffff000 @@ -698,32 +698,32 @@ void vmem_realloc(vmem_t*, size_t); #define ARG_TERMINATOR {0, 0, 0, 0, 0, ARG_NOMINMAX} typedef struct arglist { - const char *argstring; - char **argval; - const char *helpstring; - const char *defaultvalue; - const gbuint32 argtype; - const char *minvalue; /* minimum value for numeric options */ - const char *maxvalue; /* maximum value for numeric options */ - char *argvalptr; /* !!! internal helper. Not used in definitions !!! */ + const char *argstring; + char **argval; + const char *helpstring; + const char *defaultvalue; + const gbuint32 argtype; + const char *minvalue; /* minimum value for numeric options */ + const char *maxvalue; /* maximum value for numeric options */ + char *argvalptr; /* !!! internal helper. Not used in definitions !!! */ } arglist_t; typedef enum { - ff_type_file = 1, /* normal format: useful to a GUI. */ - ff_type_internal, /* fmt not useful with default options */ - ff_type_serial /* format describes a serial protocol (GUI can display port names) */ + ff_type_file = 1, /* normal format: useful to a GUI. */ + ff_type_internal, /* fmt not useful with default options */ + ff_type_serial /* format describes a serial protocol (GUI can display port names) */ } ff_type; typedef enum { - ff_cap_rw_wpt, - ff_cap_rw_trk, - ff_cap_rw_rte + ff_cap_rw_wpt, + ff_cap_rw_trk, + ff_cap_rw_rte } ff_cap_array; typedef enum { - ff_cap_none, - ff_cap_read = 1, - ff_cap_write = 2 + ff_cap_none, + ff_cap_read = 1, + ff_cap_write = 2 } ff_cap; #define FF_CAP_RW_ALL \ @@ -736,38 +736,38 @@ typedef enum { * Format capabilities for realtime positioning. */ typedef struct position_ops { - ff_init rd_init; - ff_readposn rd_position; - ff_deinit rd_deinit; + ff_init rd_init; + ff_readposn rd_position; + ff_deinit rd_deinit; - ff_init wr_init; - ff_writeposn wr_position; - ff_deinit wr_deinit; + ff_init wr_init; + ff_writeposn wr_position; + ff_deinit wr_deinit; } position_ops_t; /* * Describe the file format to the caller. */ typedef struct ff_vecs { - ff_type type; - ff_cap cap[3]; - ff_init rd_init; - ff_init wr_init; - ff_deinit rd_deinit; - ff_deinit wr_deinit; - ff_read read; - ff_write write; - ff_exit exit; - arglist_t *args; - const char *encode; - int fixed_encode; - position_ops_t position_ops; - const char *name; /* dyn. initialized by find_vec */ + ff_type type; + ff_cap cap[3]; + ff_init rd_init; + ff_init wr_init; + ff_deinit rd_deinit; + ff_deinit wr_deinit; + ff_read read; + ff_write write; + ff_exit exit; + arglist_t *args; + const char *encode; + int fixed_encode; + position_ops_t position_ops; + const char *name; /* dyn. initialized by find_vec */ } ff_vecs_t; typedef struct style_vecs { - const char *name; - const char *style_buf; + const char *name; + const char *style_buf; } style_vecs_t; extern style_vecs_t style_list[]; @@ -790,7 +790,7 @@ ff_vecs_t *find_vec(char * const, char **); void assign_option(const char *vecname, arglist_t *ap, const char *val); void disp_vec_options(const char *vecname, arglist_t *ap); void disp_vecs(void); -void disp_vec( const char *vecname ); +void disp_vec(const char *vecname); void init_vecs(void); void exit_vecs(void); void disp_formats(int version); @@ -813,16 +813,16 @@ char *xstrappend(char *src, const char *addon); #define xxstrdup(s, file, line) xstrdup(s) #define xxstrappend(src, addon, file, line) xstrappend(src, addon) #else /* DEBUG_MEM */ -void *XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS ); -void *XMALLOC(size_t size, DEBUG_PARAMS ); -void *XREALLOC(void *p, size_t s, DEBUG_PARAMS ); -void XFREE(void *mem, DEBUG_PARAMS ); -char *XSTRDUP(const char *s, DEBUG_PARAMS ); -char *XSTRNDUP(const char *src, size_t size, DEBUG_PARAMS ); -char *XSTRNDUPT(const char *src, size_t size, DEBUG_PARAMS ); -char *XSTRAPPEND(char *src, const char *addon, DEBUG_PARAMS ); +void *XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS); +void *XMALLOC(size_t size, DEBUG_PARAMS); +void *XREALLOC(void *p, size_t s, DEBUG_PARAMS); +void XFREE(void *mem, DEBUG_PARAMS); +char *XSTRDUP(const char *s, DEBUG_PARAMS); +char *XSTRNDUP(const char *src, size_t size, DEBUG_PARAMS); +char *XSTRNDUPT(const char *src, size_t size, DEBUG_PARAMS); +char *XSTRAPPEND(char *src, const char *addon, DEBUG_PARAMS); void debug_mem_open(); -void debug_mem_output( char *format, ... ); +void debug_mem_output(char *format, ...); void debug_mem_close(); #define xcalloc(nmemb, size) XCALLOC(nmemb, size, __FILE__, __LINE__) #define xmalloc(size) XMALLOC(size, __FILE__, __LINE__) @@ -879,7 +879,7 @@ char * pretty_deg_format(double lat, double lon, char fmt, const char *sep, int char * get_filename(const char *fname); /* extract the filename portion */ -/* +/* * Character encoding transformations. */ @@ -890,45 +890,45 @@ char * get_filename(const char *fname); /* extract the filename portion */ #define CET_CHARSET_MS_ANSI "MS-ANSI" #define CET_CHARSET_LATIN1 "ISO-8859-1" -#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) +#define str_utf8_to_cp1252(str) cet_str_utf8_to_cp1252((str)) #define str_cp1252_to_utf8(str) cet_str_cp1252_to_utf8((str)) -#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) +#define str_utf8_to_iso8859_1(str) cet_str_utf8_to_iso8859_1((str)) #define str_iso8859_1_to_utf8(str) cet_str_iso8859_1_to_utf8((str)) /* this lives in gpx.c */ -time_t xml_parse_time( const char *cdatastr, int * microsecs ); - -xml_tag *xml_findfirst( xml_tag *root, const char *tagname ); -xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, const char *tagname ); -char *xml_attribute( xml_tag *tag, const char *attrname ); +time_t xml_parse_time(const char *cdatastr, int * microsecs); -char * rot13( const char *str ); +xml_tag *xml_findfirst(xml_tag *root, const char *tagname); +xml_tag *xml_findnext(xml_tag *root, xml_tag *cur, const char *tagname); +char *xml_attribute(xml_tag *tag, const char *attrname); + +char * rot13(const char *str); /* * PalmOS records like fixed-point numbers, which should be rounded * to deal with possible floating-point representation errors. */ -signed int si_round( double d ); +signed int si_round(double d); -/* +/* * Data types for Palm/OS files. */ typedef struct { - unsigned char data[4]; + unsigned char data[4]; } pdb_32; typedef struct { - unsigned char data[2]; + unsigned char data[2]; } pdb_16; typedef struct { - unsigned char data[8]; + unsigned char data[8]; } pdb_double; typedef struct { - unsigned char data[4]; + unsigned char data[4]; } pdb_float; /* @@ -976,13 +976,13 @@ double ddmm2degrees(double ddmm_val); double degrees2ddmm(double deg_val); typedef enum { - grid_unknown = -1, - grid_lat_lon_ddd = 0, - grid_lat_lon_dmm = 1, - grid_lat_lon_dms = 2, - grid_bng = 3, - grid_utm = 4, - grid_swiss = 5 + grid_unknown = -1, + grid_lat_lon_ddd = 0, + grid_lat_lon_dmm = 1, + grid_lat_lon_dms = 2, + grid_bng = 3, + grid_utm = 4, + grid_swiss = 5 } grid_type; #define GRID_INDEX_MIN grid_lat_lon_ddd @@ -1003,7 +1003,7 @@ int gb_ptr2int(const void *p); * From parse.c */ int parse_coordinates(const char *str, int datum, const grid_type grid, - double *latitude, double *longitude, const char *module); + double *latitude, double *longitude, const char *module); int parse_distance(const char *str, double *val, double scale, const char *module); int parse_speed(const char *str, double *val, const double scale, const char *module); time_t parse_date(const char *str, const char *format, const char *module); @@ -1018,11 +1018,11 @@ unsigned long get_crc32_s(const void * data); * From units.c */ typedef enum { - units_unknown = 0, - units_statute = 1, - units_metric = 2, - units_nautical =3, - units_aviation =4 + units_unknown = 0, + units_statute = 1, + units_metric = 2, + units_nautical =3, + units_aviation =4 } fmt_units; int fmt_setunits(fmt_units); diff --git a/gpsbabel/delbin.c b/gpsbabel/delbin.c index 4fdc19ec2..7c958dae1 100644 --- a/gpsbabel/delbin.c +++ b/gpsbabel/delbin.c @@ -60,10 +60,10 @@ added in the PN-40 2.5 firmware. //----------------------------------------------------------------------------- // interface to platform-specific device I/O typedef struct { - void (*init)(const char* name); - void (*deinit)(void); - unsigned (*packet_read)(void*); - unsigned (*packet_write)(const void*, unsigned); + void (*init)(const char* name); + void (*deinit)(void); + unsigned(*packet_read)(void*); + unsigned(*packet_write)(const void*, unsigned); } delbin_os_ops_t; // really static, only extern so it can be forward declared @@ -87,9 +87,9 @@ static unsigned delbin_os_packet_size; // Multiple unit support. #define DELBIN_MAX_UNITS 32 static struct { - unsigned int unit_number; - const char *unit_serial_number; - const char *unit_name; + unsigned int unit_number; + const char *unit_serial_number; + const char *unit_name; } delbin_unit_info[DELBIN_MAX_UNITS]; static int n_delbin_units; @@ -109,21 +109,33 @@ static char *opt_gcsym = NULL; static arglist_t delbin_args[] = { - { "get_posn", &opt_getposn, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &opt_logs, "Include groundspeak logs when writing", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "long_notes", &opt_long_notes, "Use long waypoint notes regardless of PN version", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nukewpt", &opt_nuke_wpt, "Delete all waypoints before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"nuketrk", &opt_nuke_trk, "Delete all tracks before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"nukerte", &opt_nuke_rte, "Delete all routes before sending", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - {"hint_at_end", &opt_hint_at_end, "If true, geocache hint at end of text", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gcsym", &opt_gcsym, "If set to 0, prefer user-provided symbols over Groundspeaks ones for geocaches", NULL, ARGTYPE_BOOL, ARG_NOMINMAX, "1" }, - ARG_TERMINATOR + { + "get_posn", &opt_getposn, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &opt_logs, "Include groundspeak logs when writing", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "long_notes", &opt_long_notes, "Use long waypoint notes regardless of PN version", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nukewpt", &opt_nuke_wpt, "Delete all waypoints before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nuketrk", &opt_nuke_trk, "Delete all tracks before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukerte", &opt_nuke_rte, "Delete all routes before sending", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + {"hint_at_end", &opt_hint_at_end, "If true, geocache hint at end of text", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gcsym", &opt_gcsym, "If set to 0, prefer user-provided symbols over Groundspeaks ones for geocaches", NULL, ARGTYPE_BOOL, ARG_NOMINMAX, "1" }, + ARG_TERMINATOR }; // Whether device understands message 0xb016 @@ -209,10 +221,10 @@ typedef enum { } nuke_dest; typedef struct { - gbuint8 type; - gbuint8 mode; - gbuint8 location; - char object_name[64]; + gbuint8 type; + gbuint8 mode; + gbuint8 location; + char object_name[64]; } msg_delete_t; // Output Waypoint Message @@ -220,23 +232,23 @@ typedef struct { // Input Waypoint Message // Message ID: 0xB014 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 elevation[4]; // F32 meters - gbuint8 color; - gbuint8 symbol; - gbuint8 name_size; - char name[1]; - // note_size[2] U16 - // note[note_size] + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 elevation[4]; // F32 meters + gbuint8 color; + gbuint8 symbol; + gbuint8 name_size; + char name[1]; + // note_size[2] U16 + // note[note_size] } msg_waypoint_t; // undocumented, seen with PN-40 2.5 firmware @@ -245,12 +257,12 @@ typedef struct { // input waypoint note // Message ID: 0xB016 typedef struct { - gbuint8 index[2]; - gbuint8 total[2]; - gbuint8 name_size; - char name[1]; - // note_size[2] - // note[note_size] + gbuint8 index[2]; + gbuint8 total[2]; + gbuint8 name_size; + char name[1]; + // note_size[2] + // note[note_size] } msg_waypoint_note_t; // Output Track Point Message @@ -258,72 +270,72 @@ typedef struct { // Input Track Point Message // Message ID: 0xB036 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 number; - struct { - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 elevation[4]; // F32 meters - gbuint8 speed[2]; // U16 km/h * 10 - gbuint8 heading[2]; // U16 deg * 100 - gbuint8 status; - } point[1]; + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 number; + struct { + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 elevation[4]; // F32 meters + gbuint8 speed[2]; // U16 km/h * 10 + gbuint8 heading[2]; // U16 deg * 100 + gbuint8 status; + } point[1]; } msg_track_point_t; // Output Track Header (Name) Message // Message ID: 0xB032 typedef struct { - gbuint8 total_tracks[2]; // U16 - gbuint8 number[2]; // U16 - char name[32]; - gbuint8 total_points[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 color[2]; // U16 - gbuint8 distance[4]; // U32 m - gbuint8 duration[4]; // U32 sec - gbuint8 comment_size[2]; // U16 - char comment[1]; + gbuint8 total_tracks[2]; // U16 + gbuint8 number[2]; // U16 + char name[32]; + gbuint8 total_points[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 color[2]; // U16 + gbuint8 distance[4]; // U32 m + gbuint8 duration[4]; // U32 sec + gbuint8 comment_size[2]; // U16 + char comment[1]; } msg_track_header_t; // Input Upload Track Header Message // Message ID: 0xB035 typedef struct { - char name[32]; - gbuint8 total_points[4]; // U32 - gbuint8 year; - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 color[2]; // U16 - gbuint8 comment_size[2]; // U16 - char comment[1]; + char name[32]; + gbuint8 total_points[4]; // U32 + gbuint8 year; + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 color[2]; // U16 + gbuint8 comment_size[2]; // U16 + char comment[1]; } msg_track_header_in_t; // Output Route Shape Message // Message ID: 0xB054 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - gbuint8 number; - gbuint8 reserved; - struct { - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - } point[1]; + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + gbuint8 number; + gbuint8 reserved; + struct { + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + } point[1]; } msg_route_shape_t; // Output Route Point Message @@ -331,142 +343,142 @@ typedef struct { // Input Route Itin Point Message // Message ID: 0xB056 typedef struct { - gbuint8 total[4]; // U32 - gbuint8 index[4]; // U32 - char name[32]; - gbuint8 latitude[4]; // S32 rad * 100000000 - gbuint8 longitude[4]; // S32 rad * 100000000 - gbuint8 time_from_start[4]; // U32 sec - gbuint8 distance_from_start[4]; // F32 km - gbuint8 bearing_in[2]; // U16 deg * 100 - gbuint8 bearing_out[2]; // U16 deg * 100 - gbuint8 bearing_next[2]; // U16 deg * 100 - gbuint8 itinerary_type; - gbuint8 turn_type; - gbuint8 road_class[2]; // U16 - gbuint8 feature_code[4]; // U32 - gbuint8 exit_label_size; - char exit_label[1]; - // comment_size U8 - // comment[comment_size] - // shape_pt_count U32 + gbuint8 total[4]; // U32 + gbuint8 index[4]; // U32 + char name[32]; + gbuint8 latitude[4]; // S32 rad * 100000000 + gbuint8 longitude[4]; // S32 rad * 100000000 + gbuint8 time_from_start[4]; // U32 sec + gbuint8 distance_from_start[4]; // F32 km + gbuint8 bearing_in[2]; // U16 deg * 100 + gbuint8 bearing_out[2]; // U16 deg * 100 + gbuint8 bearing_next[2]; // U16 deg * 100 + gbuint8 itinerary_type; + gbuint8 turn_type; + gbuint8 road_class[2]; // U16 + gbuint8 feature_code[4]; // U32 + gbuint8 exit_label_size; + char exit_label[1]; + // comment_size U8 + // comment[comment_size] + // shape_pt_count U32 } msg_route_point_t; // Output Route Header (Name) Message // Message ID: 0xB052 typedef struct { - gbuint8 total[2]; // U16 - gbuint8 index[2]; // U16 - char name[64]; - gbuint8 type; - gbuint8 total_route_point[4]; // U32 - gbuint8 total_shape_point[4]; // U32 + gbuint8 total[2]; // U16 + gbuint8 index[2]; // U16 + char name[64]; + gbuint8 type; + gbuint8 total_route_point[4]; // U32 + gbuint8 total_shape_point[4]; // U32 } msg_route_header_t; // Input Upload Route Header Message // Message ID: 0xB055 typedef struct { - char name[64]; - gbuint8 type; - gbuint8 total_route_point[4]; // U32 - gbuint8 total_shape_point[4]; // U32 + char name[64]; + gbuint8 type; + gbuint8 total_route_point[4]; // U32 + gbuint8 total_shape_point[4]; // U32 } msg_route_header_in_t; // Output Navigation Message // Message ID: 0xA010 typedef struct { - gbuint8 gps_week[2]; // U16 - gbuint8 time_of_week[8]; // D64 sec - gbuint8 year[2]; // U16 - gbuint8 month; - gbuint8 day; - gbuint8 hour; - gbuint8 minute; - gbuint8 second; - gbuint8 satellites; - gbuint8 latitude[8]; // D64 deg - gbuint8 longitude[8]; // D64 deg - gbuint8 elevation[8]; // D64 meters - gbuint8 geoid_offset[2]; // S16 meters * 10 - gbuint8 speed[4]; // F32 km/h - gbuint8 heading[2]; // U16 deg * 100 - gbuint8 magnetic_variation[2]; // S16 deg * 100 - gbuint8 fix_status; + gbuint8 gps_week[2]; // U16 + gbuint8 time_of_week[8]; // D64 sec + gbuint8 year[2]; // U16 + gbuint8 month; + gbuint8 day; + gbuint8 hour; + gbuint8 minute; + gbuint8 second; + gbuint8 satellites; + gbuint8 latitude[8]; // D64 deg + gbuint8 longitude[8]; // D64 deg + gbuint8 elevation[8]; // D64 meters + gbuint8 geoid_offset[2]; // S16 meters * 10 + gbuint8 speed[4]; // F32 km/h + gbuint8 heading[2]; // U16 deg * 100 + gbuint8 magnetic_variation[2]; // S16 deg * 100 + gbuint8 fix_status; } msg_navigation_t; // Output Satellite Info Message // Message ID: 0xA020 typedef struct { - gbuint8 gps_week[2]; // U16 - gbuint8 time_of_week[8]; // D64 sec - gbuint8 hdop[2]; // U16 - gbuint8 vdop[2]; // U16 - gbuint8 pdop[2]; // U16 - gbuint8 number; - struct { - gbuint8 prn; - gbuint8 azimuth[2]; // S16 deg? * 100 - gbuint8 elevation[2]; // S16 deg? * 100 - gbuint8 Cn0[2]; // U16 snr * 100 - gbuint8 status; - } sat[1]; + gbuint8 gps_week[2]; // U16 + gbuint8 time_of_week[8]; // D64 sec + gbuint8 hdop[2]; // U16 + gbuint8 vdop[2]; // U16 + gbuint8 pdop[2]; // U16 + gbuint8 number; + struct { + gbuint8 prn; + gbuint8 azimuth[2]; // S16 deg? * 100 + gbuint8 elevation[2]; // S16 deg? * 100 + gbuint8 Cn0[2]; // U16 snr * 100 + gbuint8 status; + } sat[1]; } msg_satellite_t; // Output Version Message // Message ID: 0xA001 typedef struct { - gbuint8 firmware_version[4]; - char company[32]; - char product[32]; - char firmware[32]; - char gps_firmware[48]; - char serial[16]; - char extra[16]; + gbuint8 firmware_version[4]; + char company[32]; + char product[32]; + char firmware[32]; + char gps_firmware[48]; + char serial[16]; + char extra[16]; } msg_version_t; // Output Device Capabilities Message // Message ID: 0xB001 typedef struct { - gbuint8 max_waypoints[4]; // U32 - gbuint8 max_tracks[2]; // U16 - gbuint8 max_track_points[4]; // U32 - gbuint8 max_routes[2]; // U16 - gbuint8 max_route_points[4]; // U32 - gbuint8 max_route_shape_points[4]; // U32 - gbuint8 max_maps[2]; // U16 - gbuint8 min_map_version[2]; // U16 - gbuint8 max_map_version[2]; // U16 - gbuint8 total_internal_file_memory[4]; // U32 - gbuint8 avail_internal_file_memory[4]; // U32 - gbuint8 total_external_file_memory[4]; // U32 - gbuint8 avail_external_file_memory[4]; // U32 + gbuint8 max_waypoints[4]; // U32 + gbuint8 max_tracks[2]; // U16 + gbuint8 max_track_points[4]; // U32 + gbuint8 max_routes[2]; // U16 + gbuint8 max_route_points[4]; // U32 + gbuint8 max_route_shape_points[4]; // U32 + gbuint8 max_maps[2]; // U16 + gbuint8 min_map_version[2]; // U16 + gbuint8 max_map_version[2]; // U16 + gbuint8 total_internal_file_memory[4]; // U32 + gbuint8 avail_internal_file_memory[4]; // U32 + gbuint8 total_external_file_memory[4]; // U32 + gbuint8 avail_external_file_memory[4]; // U32 } msg_capabilities_t; //----------------------------------------------------------------------------- #if __APPLE__ || __linux - #include +#include #endif static void debug_out(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - fputs(MYNAME ": ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + fputs(MYNAME ": ", stderr); + vfprintf(stderr, fmt, ap); + va_end(ap); } static void debug_out_time(const char* s) { #if __APPLE__ || __linux - struct timeval tv; - gettimeofday(&tv, NULL); - debug_out("%u.%03u %s", (unsigned)tv.tv_sec & 0xf, (unsigned)tv.tv_usec / 1000, s); + struct timeval tv; + gettimeofday(&tv, NULL); + debug_out("%u.%03u %s", (unsigned)tv.tv_sec & 0xf, (unsigned)tv.tv_usec / 1000, s); #else - debug_out("%u %s", (unsigned)time(NULL) & 0xf, s); + debug_out("%u %s", (unsigned)time(NULL) & 0xf, s); #endif } @@ -475,16 +487,16 @@ debug_out_time(const char* s) static gbuint16 checksum(const gbuint8* p, unsigned n) { - int x = 0; - unsigned i; - for (i = n / 2; i > 0; i--) { - x += *p++; - x += *p++ << 8; - } - if (n & 1) { - x += *p; - } - return (gbuint16)-x; + int x = 0; + unsigned i; + for (i = n / 2; i > 0; i--) { + x += *p++; + x += *p++ << 8; + } + if (n & 1) { + x += *p; + } + return (gbuint16)-x; } //----------------------------------------------------------------------------- @@ -493,111 +505,111 @@ checksum(const gbuint8* p, unsigned n) static unsigned packet_read(void* buf) { - unsigned n = delbin_os_ops.packet_read(buf); - if (n == 0) { - fatal(MYNAME ": read 0\n"); - } - if (global_opts.debug_level >= DBGLVL_H) { - unsigned j; - const gbuint8* p = buf; - - debug_out_time("pcktrd"); - for (j = 0; j < n; j++) { - warning(" %02x", p[j]); - } - if (global_opts.debug_level >= DBGLVL_H2) { - warning(" "); - for (j = 0; j < n; j++) { - int c = p[j]; - warning("%c", isprint(c) ? c : '.'); - } - } - warning("\n"); - } - return n; + unsigned n = delbin_os_ops.packet_read(buf); + if (n == 0) { + fatal(MYNAME ": read 0\n"); + } + if (global_opts.debug_level >= DBGLVL_H) { + unsigned j; + const gbuint8* p = buf; + + debug_out_time("pcktrd"); + for (j = 0; j < n; j++) { + warning(" %02x", p[j]); + } + if (global_opts.debug_level >= DBGLVL_H2) { + warning(" "); + for (j = 0; j < n; j++) { + int c = p[j]; + warning("%c", isprint(c) ? c : '.'); + } + } + warning("\n"); + } + return n; } static void packet_write(const void* buf, unsigned size) { - unsigned n; - if (global_opts.debug_level >= DBGLVL_H) { - unsigned j; - const gbuint8* p = buf; - - debug_out_time("pcktwr"); - for (j = 0; j < size; j++) { - warning(" %02x", p[j]); - } - if (global_opts.debug_level >= DBGLVL_H2) { - warning(" "); - for (j = 0; j < size; j++) { - int c = p[j]; - warning("%c", isprint(c) ? c : '.'); - } - } - warning("\n"); - } - n = delbin_os_ops.packet_write(buf, size); - if (n != size) { - fatal(MYNAME ": short write %u %u\n", size, n); - } + unsigned n; + if (global_opts.debug_level >= DBGLVL_H) { + unsigned j; + const gbuint8* p = buf; + + debug_out_time("pcktwr"); + for (j = 0; j < size; j++) { + warning(" %02x", p[j]); + } + if (global_opts.debug_level >= DBGLVL_H2) { + warning(" "); + for (j = 0; j < size; j++) { + int c = p[j]; + warning("%c", isprint(c) ? c : '.'); + } + } + warning("\n"); + } + n = delbin_os_ops.packet_write(buf, size); + if (n != size) { + fatal(MYNAME ": short write %u %u\n", size, n); + } } //----------------------------------------------------------------------------- // dynamically sized buffer with space reserved for message header and trailer typedef struct { - // message data size - unsigned size; - // buffer size - unsigned capacity; - gbuint8* buf; - // convenience pointer to message data area - void* data; + // message data size + unsigned size; + // buffer size + unsigned capacity; + gbuint8* buf; + // convenience pointer to message data area + void* data; } message_t; static void message_init(message_t* m) { - m->capacity = 100; - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; + m->capacity = 100; + m->buf = xmalloc(m->capacity); + m->data = m->buf + 2 + 8; } static void message_init_size(message_t* m, unsigned size) { - m->size = size; - m->capacity = 2 + 8 + size + 4; - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; + m->size = size; + m->capacity = 2 + 8 + size + 4; + m->buf = xmalloc(m->capacity); + m->data = m->buf + 2 + 8; } static void message_free(message_t* m) { - xfree(m->buf); - m->buf = NULL; - m->data = NULL; + xfree(m->buf); + m->buf = NULL; + m->data = NULL; } static void message_ensure_size(message_t* m, unsigned size) { - m->size = size; - if (m->capacity < 2 + 8 + size + 4) { - m->capacity = 2 + 8 + size + 4; - xfree(m->buf); - m->buf = xmalloc(m->capacity); - m->data = m->buf + 2 + 8; - } + m->size = size; + if (m->capacity < 2 + 8 + size + 4) { + m->capacity = 2 + 8 + size + 4; + xfree(m->buf); + m->buf = xmalloc(m->capacity); + m->data = m->buf + 2 + 8; + } } static unsigned message_get_id(const message_t* m) { - return le_readu16(m->buf + 4); + return le_readu16(m->buf + 4); } //----------------------------------------------------------------------------- @@ -605,85 +617,86 @@ message_get_id(const message_t* m) static void message_write(unsigned msg_id, message_t* m) { - unsigned chksum; - unsigned count; - unsigned n; - gbuint8* p = m->buf; - - // header (2 start bytes filled in later) - p[2] = 0xdb; - p[3] = 0xfe; - le_write16(p + 4, msg_id); - // "data size" includes 4 trailer bytes - le_write16(p + 6, m->size + 4); - chksum = checksum(p + 2, 6); - le_write16(p + 8, chksum); - // message data (filled in by caller) - chksum = checksum(m->data, m->size); - n = 2 + 8 + m->size; - // trailer (checksum and marker bytes) - le_write16(p + n, chksum); - p[n + 2] = 0xad; - p[n + 3] = 0xbc; - // size of message not counting packet start bytes - count = 8 + m->size + 4; - do { - const gbuint8 save0 = p[0]; - const gbuint8 save1 = p[1]; - n = delbin_os_packet_size - 2; - if (n > count) { - n = count; - } - // doc. says 0x20, device sends 0, probably ignored - p[0] = 0x20; - // valid bytes in packet after first 2 - p[1] = n; - packet_write(p, 2 + n); - p[0] = save0; - p[1] = save1; - p += n; - count -= n; - } while (count != 0); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": sent %x\n", msg_id); + unsigned chksum; + unsigned count; + unsigned n; + gbuint8* p = m->buf; + + // header (2 start bytes filled in later) + p[2] = 0xdb; + p[3] = 0xfe; + le_write16(p + 4, msg_id); + // "data size" includes 4 trailer bytes + le_write16(p + 6, m->size + 4); + chksum = checksum(p + 2, 6); + le_write16(p + 8, chksum); + // message data (filled in by caller) + chksum = checksum(m->data, m->size); + n = 2 + 8 + m->size; + // trailer (checksum and marker bytes) + le_write16(p + n, chksum); + p[n + 2] = 0xad; + p[n + 3] = 0xbc; + // size of message not counting packet start bytes + count = 8 + m->size + 4; + do { + const gbuint8 save0 = p[0]; + const gbuint8 save1 = p[1]; + n = delbin_os_packet_size - 2; + if (n > count) { + n = count; + } + // doc. says 0x20, device sends 0, probably ignored + p[0] = 0x20; + // valid bytes in packet after first 2 + p[1] = n; + packet_write(p, 2 + n); + p[0] = save0; + p[1] = save1; + p += n; + count -= n; + } while (count != 0); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": sent %x\n", msg_id); + } } // read from the payload of a single packet static unsigned read_depacketize_1(gbuint8** p, unsigned n, int new_packet) { - static gbuint8 buf[256]; - static unsigned buf_i, buf_n; - if (new_packet) { - buf_n = 0; - } - while (buf_n == 0) { - packet_read(buf); - if (buf[1] <= delbin_os_packet_size - 2) { - buf_n = buf[1]; - buf_i = 2; - } - } - *p = buf + buf_i; - if (n > buf_n) { - n = buf_n; - } - buf_n -= n; - buf_i += n; - return n; + static gbuint8 buf[256]; + static unsigned buf_i, buf_n; + if (new_packet) { + buf_n = 0; + } + while (buf_n == 0) { + packet_read(buf); + if (buf[1] <= delbin_os_packet_size - 2) { + buf_n = buf[1]; + buf_i = 2; + } + } + *p = buf + buf_i; + if (n > buf_n) { + n = buf_n; + } + buf_n -= n; + buf_i += n; + return n; } // read from packet payloads until request is fulfilled static void read_depacketize(gbuint8* buf, unsigned n) { - while (n) { - gbuint8* p; - unsigned nn = read_depacketize_1(&p, n, FALSE); - memcpy(buf, p, nn); - n -= nn; - buf += nn; - } + while (n) { + gbuint8* p; + unsigned nn = read_depacketize_1(&p, n, FALSE); + memcpy(buf, p, nn); + n -= nn; + buf += nn; + } } // Get one valid message. @@ -691,71 +704,72 @@ read_depacketize(gbuint8* buf, unsigned n) static unsigned message_read_1(unsigned msg_id, message_t* m) { - unsigned id; - for (;;) { - unsigned total; - unsigned n; - gbuint8 buf[8]; - gbuint8* p; - - n = read_depacketize_1(&p, 8, FALSE); - memset(buf, 0, 8); - memcpy(buf, p, n); - while (buf[0] != 0xdb || buf[1] != 0xfe || checksum(buf, 6) != le_readu16(buf + 6)) { - // try for a message start at the beginning of next packet - n = read_depacketize_1(&p, 8, TRUE); - memset(buf, 0, 8); - memcpy(buf, p, n); - } - id = le_readu16(buf + 2); - total = le_readu16(buf + 4); - message_ensure_size(m, total - 4); - // copy in message head, really only need id field, do the rest for debugging - m->buf[0] = m->buf[1] = 0; - memcpy(m->buf + 2, buf, 8); - // read message body and trailer - read_depacketize(m->data, total); - p = (gbuint8*)m->data + m->size; - if (checksum(m->data, m->size) == le_readu16(p) && - p[2] == 0xad && p[3] == 0xbc) - { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": received %x\n", id); - break; - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": corrupted message %x\n", id); - if (id == msg_id) { - id = 0; - break; - } - } - return id; + unsigned id; + for (;;) { + unsigned total; + unsigned n; + gbuint8 buf[8]; + gbuint8* p; + + n = read_depacketize_1(&p, 8, FALSE); + memset(buf, 0, 8); + memcpy(buf, p, n); + while (buf[0] != 0xdb || buf[1] != 0xfe || checksum(buf, 6) != le_readu16(buf + 6)) { + // try for a message start at the beginning of next packet + n = read_depacketize_1(&p, 8, TRUE); + memset(buf, 0, 8); + memcpy(buf, p, n); + } + id = le_readu16(buf + 2); + total = le_readu16(buf + 4); + message_ensure_size(m, total - 4); + // copy in message head, really only need id field, do the rest for debugging + m->buf[0] = m->buf[1] = 0; + memcpy(m->buf + 2, buf, 8); + // read message body and trailer + read_depacketize(m->data, total); + p = (gbuint8*)m->data + m->size; + if (checksum(m->data, m->size) == le_readu16(p) && + p[2] == 0xad && p[3] == 0xbc) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": received %x\n", id); + } + break; + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": corrupted message %x\n", id); + } + if (id == msg_id) { + id = 0; + break; + } + } + return id; } // Send MSG_ACK for given message static void message_ack(unsigned id, const message_t* m) { - message_t ack; - char* p1; - const char* p2 = m->data; - switch (id) { - case MSG_ACK: - case MSG_NACK: - case MSG_NAVIGATION: - case MSG_SATELLITE_INFO: - // don't ack these - return; - } - message_init_size(&ack, 4); - p1 = ack.data; - // ack payload is id and body checksum of acked message - le_write16(p1, id); - p1[2] = p2[m->size]; - p1[3] = p2[m->size + 1]; - message_write(MSG_ACK, &ack); - message_free(&ack); + message_t ack; + char* p1; + const char* p2 = m->data; + switch (id) { + case MSG_ACK: + case MSG_NACK: + case MSG_NAVIGATION: + case MSG_SATELLITE_INFO: + // don't ack these + return; + } + message_init_size(&ack, 4); + p1 = ack.data; + // ack payload is id and body checksum of acked message + le_write16(p1, id); + p1[2] = p2[m->size]; + p1[3] = p2[m->size + 1]; + message_write(MSG_ACK, &ack); + message_free(&ack); } // Get specific message, ignoring others. Sends ACK for non-interval messages. @@ -763,90 +777,94 @@ message_ack(unsigned id, const message_t* m) static int message_read(unsigned msg_id, message_t* m) { - unsigned id; - time_t time_start = time(NULL); - - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": looking for %x\n", msg_id); - for (;;) { - id = message_read_1(msg_id, m); - if (id == 0) { - break; - } - if (id == MSG_ERROR) { - const gbuint8* p = m->data; - fatal(MYNAME ": device error %u: \"%s\"\n", *p, p + 1); - } - message_ack(id, m); - if (id == msg_id || time(NULL) - time_start >= READ_TIMEOUT) { - break; - } - } - return id == msg_id; + unsigned id; + time_t time_start = time(NULL); + + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": looking for %x\n", msg_id); + } + for (;;) { + id = message_read_1(msg_id, m); + if (id == 0) { + break; + } + if (id == MSG_ERROR) { + const gbuint8* p = m->data; + fatal(MYNAME ": device error %u: \"%s\"\n", *p, p + 1); + } + message_ack(id, m); + if (id == msg_id || time(NULL) - time_start >= READ_TIMEOUT) { + break; + } + } + return id == msg_id; } // Read a sequence of messages, up to a MSG_TRANSFER_COMPLETE static int get_batch(message_t** array, unsigned* n) { - int success = 1; - unsigned array_max = 100; - message_t* a = xmalloc(array_max * sizeof(message_t)); - unsigned i = 0; - unsigned id; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": begin get_batch\n"); - do { - time_t time_start = time(NULL); - if (i == array_max) { - message_t* old_a = a; - array_max += array_max; - a = xmalloc(array_max * sizeof(message_t)); - memcpy(a, old_a, i * sizeof(message_t)); - xfree(old_a); - } - message_init(&a[i]); - for (;;) { - id = message_read_1(0, &a[i]); - switch (id) { - case MSG_NAVIGATION: - if (time(NULL) - time_start >= READ_TIMEOUT) { - success = 0; - break; - } - // fall through - case MSG_ACK: - case MSG_NACK: - case MSG_SATELLITE_INFO: - continue; - } - break; - } - message_ack(id, &a[i]); - i++; - } while (success && id != MSG_TRANSFER_COMPLETE); - if (success) { - *array = a; - *n = i - 1; - message_free(&a[*n]); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end get_batch, %u messages\n", *n); - } else { - while (i--) { - message_free(&a[i]); - } - xfree(a); - *array = NULL; - *n = 0; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end get_batch, failed\n"); - } - return success; + int success = 1; + unsigned array_max = 100; + message_t* a = xmalloc(array_max * sizeof(message_t)); + unsigned i = 0; + unsigned id; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": begin get_batch\n"); + } + do { + time_t time_start = time(NULL); + if (i == array_max) { + message_t* old_a = a; + array_max += array_max; + a = xmalloc(array_max * sizeof(message_t)); + memcpy(a, old_a, i * sizeof(message_t)); + xfree(old_a); + } + message_init(&a[i]); + for (;;) { + id = message_read_1(0, &a[i]); + switch (id) { + case MSG_NAVIGATION: + if (time(NULL) - time_start >= READ_TIMEOUT) { + success = 0; + break; + } + // fall through + case MSG_ACK: + case MSG_NACK: + case MSG_SATELLITE_INFO: + continue; + } + break; + } + message_ack(id, &a[i]); + i++; + } while (success && id != MSG_TRANSFER_COMPLETE); + if (success) { + *array = a; + *n = i - 1; + message_free(&a[*n]); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end get_batch, %u messages\n", *n); + } + } else { + while (i--) { + message_free(&a[i]); + } + xfree(a); + *array = NULL; + *n = 0; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end get_batch, failed\n"); + } + } + return success; } static struct { - unsigned msg_id; - message_t msg; + unsigned msg_id; + message_t msg; } *batch_array; static unsigned batch_array_max; static unsigned batch_array_i; @@ -855,84 +873,87 @@ static unsigned batch_array_i; static void add_to_batch(unsigned id, message_t* m) { - if (batch_array_i == batch_array_max) { - void* old = batch_array; - if (batch_array_max == 0) { - batch_array_max = 50; - } - batch_array_max += batch_array_max; - batch_array = xmalloc(batch_array_max * sizeof(*batch_array)); - if (batch_array_i) { - memcpy(batch_array, old, batch_array_i * sizeof(*batch_array)); - xfree(old); - } - } - batch_array[batch_array_i].msg_id = id; - batch_array[batch_array_i].msg = *m; - batch_array_i++; - memset(m, 0, sizeof(*m)); + if (batch_array_i == batch_array_max) { + void* old = batch_array; + if (batch_array_max == 0) { + batch_array_max = 50; + } + batch_array_max += batch_array_max; + batch_array = xmalloc(batch_array_max * sizeof(*batch_array)); + if (batch_array_i) { + memcpy(batch_array, old, batch_array_i * sizeof(*batch_array)); + xfree(old); + } + } + batch_array[batch_array_i].msg_id = id; + batch_array[batch_array_i].msg = *m; + batch_array_i++; + memset(m, 0, sizeof(*m)); } // send an accumulated sequence of messages static void send_batch(void) { - message_t m; - const unsigned n = batch_array_i; - unsigned i; - unsigned progress = 0; - - message_init(&m); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": begin send_batch, %u messages\n", n); - for (i = 0; i < n; i++) { - unsigned timeout_count = 0; - time_t time_start = time(NULL); - - // Can't really trigger this off either i or n as we don't - // know how the various packets map to actual waypts. - if (global_opts.verbose_status && - (batch_array[i].msg_id == MSG_WAYPOINT_IN)) { - waypt_status_disp(waypoint_n, ++progress); - } - - message_write(batch_array[i].msg_id, &batch_array[i].msg); - for (;;) { - unsigned id = message_read_1(0, &m); - switch (id) { - case MSG_ACK: - break; - case MSG_NAVIGATION: - if (time(NULL) - time_start >= 2) { - if (timeout_count) { - fatal(MYNAME ": send_batch timed out\n"); - } - timeout_count++; - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": re-sending %x\n", batch_array[i].msg_id); - message_write(batch_array[i].msg_id, &batch_array[i].msg); - time_start = time(NULL); - } - // fall through - case MSG_NACK: - case MSG_SATELLITE_INFO: - continue; - default: - warning(MYNAME ": unexpected response message %x during send_batch\n", id); - continue; - } - break; - } - } - message_read(MSG_TRANSFER_COMPLETE, &m); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": end send_batch\n"); - for (i = n; i--;) { - message_free(&batch_array[i].msg); - } - xfree(batch_array); - message_free(&m); - batch_array_i = batch_array_max = 0; + message_t m; + const unsigned n = batch_array_i; + unsigned i; + unsigned progress = 0; + + message_init(&m); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": begin send_batch, %u messages\n", n); + } + for (i = 0; i < n; i++) { + unsigned timeout_count = 0; + time_t time_start = time(NULL); + + // Can't really trigger this off either i or n as we don't + // know how the various packets map to actual waypts. + if (global_opts.verbose_status && + (batch_array[i].msg_id == MSG_WAYPOINT_IN)) { + waypt_status_disp(waypoint_n, ++progress); + } + + message_write(batch_array[i].msg_id, &batch_array[i].msg); + for (;;) { + unsigned id = message_read_1(0, &m); + switch (id) { + case MSG_ACK: + break; + case MSG_NAVIGATION: + if (time(NULL) - time_start >= 2) { + if (timeout_count) { + fatal(MYNAME ": send_batch timed out\n"); + } + timeout_count++; + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": re-sending %x\n", batch_array[i].msg_id); + } + message_write(batch_array[i].msg_id, &batch_array[i].msg); + time_start = time(NULL); + } + // fall through + case MSG_NACK: + case MSG_SATELLITE_INFO: + continue; + default: + warning(MYNAME ": unexpected response message %x during send_batch\n", id); + continue; + } + break; + } + } + message_read(MSG_TRANSFER_COMPLETE, &m); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": end send_batch\n"); + } + for (i = n; i--;) { + message_free(&batch_array[i].msg); + } + xfree(batch_array); + message_free(&m); + batch_array_i = batch_array_max = 0; } //----------------------------------------------------------------------------- @@ -941,13 +962,13 @@ send_batch(void) static double delbin_rad2deg(gbint32 x) { - return x * ((180 / M_PI) / 100000000); + return x * ((180 / M_PI) / 100000000); } static gbint32 delbin_deg2rad(double x) { - return (gbint32)(x * ((M_PI / 180) * 100000000)); + return (gbint32)(x * ((M_PI / 180) * 100000000)); } //----------------------------------------------------------------------------- @@ -956,137 +977,144 @@ delbin_deg2rad(double x) static time_t decode_time(const gbuint8* p) { - struct tm t; - t.tm_year = p[0]; - t.tm_mon = p[1] - 1; - t.tm_mday = p[2]; - t.tm_hour = p[3]; - t.tm_min = p[4]; - t.tm_sec = p[5]; - return mkgmtime(&t); + struct tm t; + t.tm_year = p[0]; + t.tm_mon = p[1] - 1; + t.tm_mday = p[2]; + t.tm_hour = p[3]; + t.tm_min = p[4]; + t.tm_sec = p[5]; + return mkgmtime(&t); } static waypoint* decode_waypoint(const void* data) { - waypoint* wp = waypt_new(); - const msg_waypoint_t* p = data; - const char* s; - float f; - - wp->creation_time = decode_time(&p->year); - wp->latitude = delbin_rad2deg(le_read32(p->latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->longitude)); - f = le_read_float(p->elevation); - if (f > UNKNOWN_ELEV) { - wp->altitude = f; - } - wp->icon_descr = waypoint_symbol(p->symbol); - if (wp->icon_descr) { - wp->icon_descr = xstrdup(wp->icon_descr); - } - if (p->name_size && p->name[0]) { - wp->description = xstrdup(p->name); - } - s = p->name + p->name_size; - if (le_readu16(s) && s[2]) { - wp->notes = xstrdup(s + 2); - } - return wp; + waypoint* wp = waypt_new(); + const msg_waypoint_t* p = data; + const char* s; + float f; + + wp->creation_time = decode_time(&p->year); + wp->latitude = delbin_rad2deg(le_read32(p->latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->longitude)); + f = le_read_float(p->elevation); + if (f > UNKNOWN_ELEV) { + wp->altitude = f; + } + wp->icon_descr = waypoint_symbol(p->symbol); + if (wp->icon_descr) { + wp->icon_descr = xstrdup(wp->icon_descr); + } + if (p->name_size && p->name[0]) { + wp->description = xstrdup(p->name); + } + s = p->name + p->name_size; + if (le_readu16(s) && s[2]) { + wp->notes = xstrdup(s + 2); + } + return wp; } static void read_waypoints(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - waypoint* wp = NULL; - unsigned n_point; - unsigned notes_i = 0; - unsigned notes_max = 0; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of waypoints - for (;;) { - m.size = 0; - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading waypoint count failed\n"); - } - n_point = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u waypoints\n", n_point); - if (n_point == 0) { - message_free(&m); - return; - } - // get waypoint messages - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_WAYPOINTS_SIZE; - memset(m.data, 0, m.size); - // This byte is documented as reserved. Setting it to 3 is required to get - // extended notes (message 0xb015) with PN-40 firmware 2.5. - // Whether it has any effect with earlier firmware or the PN-20 is unknown. - ((char*)m.data)[1] = 3; - message_write(MSG_REQUEST_WAYPOINTS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading waypoints failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading waypoints, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - // process waypoint messages - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_WAYPOINT_OUT) { - wp = decode_waypoint(msg_array[i].data); - waypt_add(wp); - notes_i = 0; - notes_max = 0; - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": read waypoint '%s'\n", wp->description); - } else if (wp && id == MSG_WAYPOINT_NOTE_OUT) { - const msg_waypoint_note_t* p = msg_array[i].data; - const char* s = p->name + p->name_size; - unsigned nn = le_readu16(s); - if (notes_max < notes_i + nn) { - char* old = wp->notes; - if (notes_max == 0) { - notes_max = nn; - } - do { - notes_max += notes_max; - } while (notes_max < notes_i + nn); - wp->notes = xmalloc(notes_max); - if (old) { - memcpy(wp->notes, old, notes_i); - xfree(old); - } - } - if (nn) { - memcpy(wp->notes + notes_i, s + 2, nn); - notes_i += nn; - if (wp->notes[notes_i - 1] == 0) { - notes_i--; - } - } - } else { - fatal(MYNAME ": unexpected message %x while reading waypoints\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + waypoint* wp = NULL; + unsigned n_point; + unsigned notes_i = 0; + unsigned notes_max = 0; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of waypoints + for (;;) { + m.size = 0; + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading waypoint count failed\n"); + } + } + n_point = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u waypoints\n", n_point); + } + if (n_point == 0) { + message_free(&m); + return; + } + // get waypoint messages + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_WAYPOINTS_SIZE; + memset(m.data, 0, m.size); + // This byte is documented as reserved. Setting it to 3 is required to get + // extended notes (message 0xb015) with PN-40 firmware 2.5. + // Whether it has any effect with earlier firmware or the PN-20 is unknown. + ((char*)m.data)[1] = 3; + message_write(MSG_REQUEST_WAYPOINTS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading waypoints failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading waypoints, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + // process waypoint messages + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_WAYPOINT_OUT) { + wp = decode_waypoint(msg_array[i].data); + waypt_add(wp); + notes_i = 0; + notes_max = 0; + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": read waypoint '%s'\n", wp->description); + } + } else if (wp && id == MSG_WAYPOINT_NOTE_OUT) { + const msg_waypoint_note_t* p = msg_array[i].data; + const char* s = p->name + p->name_size; + unsigned nn = le_readu16(s); + if (notes_max < notes_i + nn) { + char* old = wp->notes; + if (notes_max == 0) { + notes_max = nn; + } + do { + notes_max += notes_max; + } while (notes_max < notes_i + nn); + wp->notes = xmalloc(notes_max); + if (old) { + memcpy(wp->notes, old, notes_i); + xfree(old); + } + } + if (nn) { + memcpy(wp->notes + notes_i, s + 2, nn); + notes_i += nn; + if (wp->notes[notes_i - 1] == 0) { + notes_i--; + } + } + } else { + fatal(MYNAME ": unexpected message %x while reading waypoints\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); } //----------------------------------------------------------------------------- @@ -1095,331 +1123,370 @@ read_waypoints(void) static void encode_time(time_t time_, gbuint8* p) { - const struct tm* t = gmtime(&time_); - p[0] = t->tm_year; - p[1] = t->tm_mon + 1; - p[2] = t->tm_mday; - p[3] = t->tm_hour; - p[4] = t->tm_min; - p[5] = t->tm_sec; + const struct tm* t = gmtime(&time_); + p[0] = t->tm_year; + p[1] = t->tm_mon + 1; + p[2] = t->tm_mday; + p[3] = t->tm_hour; + p[4] = t->tm_min; + p[5] = t->tm_sec; } static void get_gc_notes(const waypoint* wp, int* symbol, char** notes, unsigned* notes_size) { - fs_xml* fs_gpx; - xml_tag* root = NULL; - gbfile* fd = gbfopen(NULL, "w", MYNAME); - const char* size = NULL; - int gc_sym = 0; - - switch (wp->gc_data->type) { - case gt_traditional: gc_sym = 160; break; - case gt_multi: gc_sym = 161; break; - case gt_virtual: gc_sym = 169; break; - case gt_letterbox: gc_sym = 163; break; - case gt_event: gc_sym = 165; break; - case gt_suprise: gc_sym = 162; break; - case gt_webcam: gc_sym = 170; break; - case gt_earth: gc_sym = 168; break; - case gt_benchmark: gc_sym = 172; break; - case gt_cito: gc_sym = 167; break; - case gt_mega: gc_sym = 166; break; - case gt_wherigo: gc_sym = 164; break; - case gt_unknown: - case gt_locationless: - case gt_ape: - break; - } - if (0 == strcmp(wp->icon_descr, "Geocache Found")) - gc_sym = 124; - if (wp->description) { - gbfputs(wp->description, fd); - if (wp->gc_data->placer) { - gbfprintf(fd, " by %s", wp->gc_data->placer); - } - gbfputc('\n', fd); - } - - gbfprintf(fd, "Cache ID: %s\n", wp->shortname); - if (gc_sym && opt_gcsym && atoi(opt_gcsym)) { - gbfprintf(fd, "%s\n", waypoint_symbol(gc_sym)); - *symbol = gc_sym; - } else if (wp->icon_descr) { - gbfprintf(fd, "%s\n", wp->icon_descr); - } - switch (wp->gc_data->container) { - case gc_micro: size = "Micro"; break; - case gc_small: size = "Small"; break; - case gc_regular: size = "Regular"; break; - case gc_large: size = "Large"; break; - case gc_unknown: size = "Not Chosen" ; break; - case gc_other: size = "Other"; break; - // Device has no symbol for this, but this is what Topo sends. - case gc_virtual: size = "Virtual"; break; - default: - break; - } - if (size) { - gbfprintf(fd, "SIZE: %s\n", size); - } - if (wp->gc_data->diff % 10) { - gbfprintf(fd, "D%.1f", wp->gc_data->diff / 10.0); - } else { - gbfprintf(fd, "D%u", wp->gc_data->diff / 10); - } - if (wp->gc_data->terr % 10) { - gbfprintf(fd, "/T%.1f\n", wp->gc_data->terr / 10.0); - } else { - gbfprintf(fd, "/T%u\n", wp->gc_data->terr / 10); - } - if (wp->gc_data->hint && !opt_hint_at_end) { - gbfprintf(fd, "HINT: %s\n", wp->gc_data->hint); - } - if (wp->gc_data->desc_short.utfstring || wp->gc_data->desc_long.utfstring) { - gbfputs("DESC: ", fd); - if (wp->gc_data->desc_short.utfstring) { - char* s1 = strip_html(&wp->gc_data->desc_short); - char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); - gbfprintf(fd, "%s\n", s2); - xfree(s2); - xfree(s1); - } - if (wp->gc_data->desc_long.utfstring) { - char* s1 = strip_html(&wp->gc_data->desc_long); - char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); - gbfputs(s2, fd); - xfree(s2); - xfree(s1); - } - } - fs_gpx = (fs_xml*)fs_chain_find(wp->fs, FS_GPX); - if (opt_logs && fs_gpx && fs_gpx->tag) { - root = xml_findfirst(fs_gpx->tag, "groundspeak:logs"); - } - if (root) { - xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); - if (curlog) { - gbfputs("\nLOG:\n", fd); - } - for (; curlog; curlog = xml_findnext(root, curlog, "groundspeak:log")) { - xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); - if (logpart) { - gbfprintf(fd, "%s\n", logpart->cdata); - } - logpart = xml_findfirst(curlog, "groundspeak:date"); - if (logpart) { - time_t logtime = xml_parse_time(logpart->cdata, NULL); - const struct tm* logtm = gmtime(&logtime); - gbfprintf(fd, "%d-%02d-%02d ", logtm->tm_year + 1900, logtm->tm_mon + 1, logtm->tm_mday); - } - logpart = xml_findfirst(curlog, "groundspeak:finder"); - if (logpart) { - char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); - gbfputs(s, fd); - xfree(s); - } - logpart = xml_findfirst(curlog, "groundspeak:text"); - if (logpart) { - char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); - gbfprintf(fd, ", %s", s); - xfree(s); - } - gbfputc('\n', fd); - } - } - if (wp->gc_data->hint && opt_hint_at_end) { - gbfprintf(fd, "\nHINT: %s\n", wp->gc_data->hint); - } - gbfputc(0, fd); - *notes_size = fd->memlen; - *notes = xmalloc(*notes_size); - memcpy(*notes, fd->handle.mem, *notes_size); - gbfclose(fd); + fs_xml* fs_gpx; + xml_tag* root = NULL; + gbfile* fd = gbfopen(NULL, "w", MYNAME); + const char* size = NULL; + int gc_sym = 0; + + switch (wp->gc_data->type) { + case gt_traditional: + gc_sym = 160; + break; + case gt_multi: + gc_sym = 161; + break; + case gt_virtual: + gc_sym = 169; + break; + case gt_letterbox: + gc_sym = 163; + break; + case gt_event: + gc_sym = 165; + break; + case gt_suprise: + gc_sym = 162; + break; + case gt_webcam: + gc_sym = 170; + break; + case gt_earth: + gc_sym = 168; + break; + case gt_benchmark: + gc_sym = 172; + break; + case gt_cito: + gc_sym = 167; + break; + case gt_mega: + gc_sym = 166; + break; + case gt_wherigo: + gc_sym = 164; + break; + case gt_unknown: + case gt_locationless: + case gt_ape: + break; + } + if (0 == strcmp(wp->icon_descr, "Geocache Found")) { + gc_sym = 124; + } + if (wp->description) { + gbfputs(wp->description, fd); + if (wp->gc_data->placer) { + gbfprintf(fd, " by %s", wp->gc_data->placer); + } + gbfputc('\n', fd); + } + + gbfprintf(fd, "Cache ID: %s\n", wp->shortname); + if (gc_sym && opt_gcsym && atoi(opt_gcsym)) { + gbfprintf(fd, "%s\n", waypoint_symbol(gc_sym)); + *symbol = gc_sym; + } else if (wp->icon_descr) { + gbfprintf(fd, "%s\n", wp->icon_descr); + } + switch (wp->gc_data->container) { + case gc_micro: + size = "Micro"; + break; + case gc_small: + size = "Small"; + break; + case gc_regular: + size = "Regular"; + break; + case gc_large: + size = "Large"; + break; + case gc_unknown: + size = "Not Chosen" ; + break; + case gc_other: + size = "Other"; + break; + // Device has no symbol for this, but this is what Topo sends. + case gc_virtual: + size = "Virtual"; + break; + default: + break; + } + if (size) { + gbfprintf(fd, "SIZE: %s\n", size); + } + if (wp->gc_data->diff % 10) { + gbfprintf(fd, "D%.1f", wp->gc_data->diff / 10.0); + } else { + gbfprintf(fd, "D%u", wp->gc_data->diff / 10); + } + if (wp->gc_data->terr % 10) { + gbfprintf(fd, "/T%.1f\n", wp->gc_data->terr / 10.0); + } else { + gbfprintf(fd, "/T%u\n", wp->gc_data->terr / 10); + } + if (wp->gc_data->hint && !opt_hint_at_end) { + gbfprintf(fd, "HINT: %s\n", wp->gc_data->hint); + } + if (wp->gc_data->desc_short.utfstring || wp->gc_data->desc_long.utfstring) { + gbfputs("DESC: ", fd); + if (wp->gc_data->desc_short.utfstring) { + char* s1 = strip_html(&wp->gc_data->desc_short); + char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); + gbfprintf(fd, "%s\n", s2); + xfree(s2); + xfree(s1); + } + if (wp->gc_data->desc_long.utfstring) { + char* s1 = strip_html(&wp->gc_data->desc_long); + char* s2 = cet_str_utf8_to_any(s1, global_opts.charset); + gbfputs(s2, fd); + xfree(s2); + xfree(s1); + } + } + fs_gpx = (fs_xml*)fs_chain_find(wp->fs, FS_GPX); + if (opt_logs && fs_gpx && fs_gpx->tag) { + root = xml_findfirst(fs_gpx->tag, "groundspeak:logs"); + } + if (root) { + xml_tag* curlog = xml_findfirst(root, "groundspeak:log"); + if (curlog) { + gbfputs("\nLOG:\n", fd); + } + for (; curlog; curlog = xml_findnext(root, curlog, "groundspeak:log")) { + xml_tag* logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + gbfprintf(fd, "%s\n", logpart->cdata); + } + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + time_t logtime = xml_parse_time(logpart->cdata, NULL); + const struct tm* logtm = gmtime(&logtime); + gbfprintf(fd, "%d-%02d-%02d ", logtm->tm_year + 1900, logtm->tm_mon + 1, logtm->tm_mday); + } + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); + gbfputs(s, fd); + xfree(s); + } + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char* s = cet_str_utf8_to_any(logpart->cdata, global_opts.charset); + gbfprintf(fd, ", %s", s); + xfree(s); + } + gbfputc('\n', fd); + } + } + if (wp->gc_data->hint && opt_hint_at_end) { + gbfprintf(fd, "\nHINT: %s\n", wp->gc_data->hint); + } + gbfputc(0, fd); + *notes_size = fd->memlen; + *notes = xmalloc(*notes_size); + memcpy(*notes, fd->handle.mem, *notes_size); + gbfclose(fd); } static void write_waypoint_notes(const char* notes, unsigned size, const char* name) { - message_t m; - const unsigned name_size = strlen(name) + 1; - const unsigned bytes_per_msg = (10 * (delbin_os_packet_size - 2)) - name_size - 20; - const unsigned msg_count = (size + (bytes_per_msg - 1)) / bytes_per_msg; - unsigned i = 1; - - do { - char* pp; - unsigned n = bytes_per_msg; - msg_waypoint_note_t* p; - message_init_size(&m, 2 + 2 + 1 + name_size + 2 + bytes_per_msg); - p = m.data; - le_write16(p->index, i++); - le_write16(p->total, msg_count); - p->name_size = name_size; - memcpy(p->name, name, p->name_size); - pp = p->name + p->name_size; - if (n > size) { - n = size; - } - le_write16(pp, n); - pp += 2; - memcpy(pp, notes, n); - pp += n; - if (*(pp - 1)) { - *pp++ = 0; - } - notes += n; - size -= n; - m.size = pp - (char*)p; - add_to_batch(MSG_WAYPOINT_NOTE_IN, &m); - } while (size != 0); + message_t m; + const unsigned name_size = strlen(name) + 1; + const unsigned bytes_per_msg = (10 * (delbin_os_packet_size - 2)) - name_size - 20; + const unsigned msg_count = (size + (bytes_per_msg - 1)) / bytes_per_msg; + unsigned i = 1; + + do { + char* pp; + unsigned n = bytes_per_msg; + msg_waypoint_note_t* p; + message_init_size(&m, 2 + 2 + 1 + name_size + 2 + bytes_per_msg); + p = m.data; + le_write16(p->index, i++); + le_write16(p->total, msg_count); + p->name_size = name_size; + memcpy(p->name, name, p->name_size); + pp = p->name + p->name_size; + if (n > size) { + n = size; + } + le_write16(pp, n); + pp += 2; + memcpy(pp, notes, n); + pp += n; + if (*(pp - 1)) { + *pp++ = 0; + } + notes += n; + size -= n; + m.size = pp - (char*)p; + add_to_batch(MSG_WAYPOINT_NOTE_IN, &m); + } while (size != 0); } static void add_nuke(nuke_type type) { - message_t m; - msg_delete_t* p; + message_t m; + msg_delete_t* p; - message_init_size(&m, MSG_DELETE_SIZE); - p = m.data; - p->type = type; - p->mode = nuke_mode_all; - p->location = nuke_dest_internal; - memset(p->object_name, 0, sizeof(p->object_name)); + message_init_size(&m, MSG_DELETE_SIZE); + p = m.data; + p->type = type; + p->mode = nuke_mode_all; + p->location = nuke_dest_internal; + memset(p->object_name, 0, sizeof(p->object_name)); - // MSG_DELETE generates a MSG_TRANSFER_COMPLETE, - // so use the batch facility to wait for it - add_to_batch(MSG_DELETE, &m); - send_batch(); + // MSG_DELETE generates a MSG_TRANSFER_COMPLETE, + // so use the batch facility to wait for it + add_to_batch(MSG_DELETE, &m); + send_batch(); } static void write_waypoint(const waypoint* wp) { - message_t m; - msg_waypoint_t* p; - const char* name = wp->shortname; - unsigned name_size; - char* notes; - unsigned notes_size = 0; - unsigned extended_notes_size = 0; - char* notes_freeable = NULL; - int symbol = -1; - float elev = UNKNOWN_ELEV; - char* pp; - - if (waypt_empty_gc_data(wp)) { - notes = wp->notes; - if (notes == NULL && wp->description && strcmp(wp->shortname, wp->description)) { - notes = wp->description; - } - if (notes) { - notes_size = strlen(notes) + 1; - } - } else { - get_gc_notes(wp, &symbol, ¬es, ¬es_size); - notes_freeable = notes; - if (wp->description) { - name = mkshort(mkshort_handle, wp->description); - } - } - - if (notes_size > 800) { - if (use_extended_notes) { - extended_notes_size = notes_size; - notes_size = 1; - } else { - notes_size = 800; - } - } - - name_size = strlen(name) + 1; - if (name_size > 255) { - name_size = 255; - } - message_init_size(&m, 31 + name_size + notes_size); - p = m.data; - - waypoint_i++; - le_write32(p->total, waypoint_n); - le_write32(p->index, waypoint_i); - encode_time(wp->creation_time, &p->year); - le_write32(p->latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->longitude, delbin_deg2rad(wp->longitude)); - if (wp->altitude > unknown_alt) { - elev = wp->altitude; - } - le_write_float(p->elevation, elev); - if (symbol < 0) { - symbol = 0; - if (wp->icon_descr) { - symbol = waypoint_symbol_index(wp->icon_descr); - } - } - p->symbol = symbol; - p->name_size = name_size; - memcpy(p->name, name, name_size - 1); - p->name[name_size - 1] = 0; - pp = p->name + name_size; - m.size = (pp + 2 + notes_size) - (char*)p; - if (extended_notes_size) { - le_write16(pp, 0xffff); - pp[2] = 0; - } else { - le_write16(pp, notes_size); - if (notes) { - memcpy(pp + 2, notes, notes_size - 1); - pp[2 + notes_size - 1] = 0; - } - } - - add_to_batch(MSG_WAYPOINT_IN, &m); - - if (extended_notes_size) { - write_waypoint_notes(notes, extended_notes_size, name); - } - if (notes_freeable) { - xfree(notes_freeable); - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": wrote waypoint %u '%s'\n", waypoint_i, name); + message_t m; + msg_waypoint_t* p; + const char* name = wp->shortname; + unsigned name_size; + char* notes; + unsigned notes_size = 0; + unsigned extended_notes_size = 0; + char* notes_freeable = NULL; + int symbol = -1; + float elev = UNKNOWN_ELEV; + char* pp; + + if (waypt_empty_gc_data(wp)) { + notes = wp->notes; + if (notes == NULL && wp->description && strcmp(wp->shortname, wp->description)) { + notes = wp->description; + } + if (notes) { + notes_size = strlen(notes) + 1; + } + } else { + get_gc_notes(wp, &symbol, ¬es, ¬es_size); + notes_freeable = notes; + if (wp->description) { + name = mkshort(mkshort_handle, wp->description); + } + } + + if (notes_size > 800) { + if (use_extended_notes) { + extended_notes_size = notes_size; + notes_size = 1; + } else { + notes_size = 800; + } + } + + name_size = strlen(name) + 1; + if (name_size > 255) { + name_size = 255; + } + message_init_size(&m, 31 + name_size + notes_size); + p = m.data; + + waypoint_i++; + le_write32(p->total, waypoint_n); + le_write32(p->index, waypoint_i); + encode_time(wp->creation_time, &p->year); + le_write32(p->latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->longitude, delbin_deg2rad(wp->longitude)); + if (wp->altitude > unknown_alt) { + elev = wp->altitude; + } + le_write_float(p->elevation, elev); + if (symbol < 0) { + symbol = 0; + if (wp->icon_descr) { + symbol = waypoint_symbol_index(wp->icon_descr); + } + } + p->symbol = symbol; + p->name_size = name_size; + memcpy(p->name, name, name_size - 1); + p->name[name_size - 1] = 0; + pp = p->name + name_size; + m.size = (pp + 2 + notes_size) - (char*)p; + if (extended_notes_size) { + le_write16(pp, 0xffff); + pp[2] = 0; + } else { + le_write16(pp, notes_size); + if (notes) { + memcpy(pp + 2, notes, notes_size - 1); + pp[2 + notes_size - 1] = 0; + } + } + + add_to_batch(MSG_WAYPOINT_IN, &m); + + if (extended_notes_size) { + write_waypoint_notes(notes, extended_notes_size, name); + } + if (notes_freeable) { + xfree(notes_freeable); + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": wrote waypoint %u '%s'\n", waypoint_i, name); + } } static void write_waypoints(void) { - message_t m; - unsigned device_n = 0; - - waypoint_i = 0; - waypoint_n = waypt_count(); - if (waypoint_n > device_max_waypoint) { - fatal(MYNAME ": waypoint count (%u) exceeds device limit (%u)\n", - waypoint_n, device_max_waypoint); - } - - message_init_size(&m, 0); - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m)) { - device_n = le_readu32(m.data); - } - - waypt_disp_all(write_waypoint); - send_batch(); - - if (device_n + waypoint_n > device_max_waypoint) { - m.size = 0; - message_write(MSG_WAYPOINT_COUNT, &m); - if (message_read(MSG_WAYPOINT_COUNT, &m) && - le_readu32(m.data) == device_max_waypoint) - { - warning(MYNAME ": waypoint count (%u already on device + %u added = %u)" - " exceeds device limit (%u), some may have been discarded\n", - device_n, waypoint_n, device_n + waypoint_n, device_max_waypoint); - } - } - message_free(&m); + message_t m; + unsigned device_n = 0; + + waypoint_i = 0; + waypoint_n = waypt_count(); + if (waypoint_n > device_max_waypoint) { + fatal(MYNAME ": waypoint count (%u) exceeds device limit (%u)\n", + waypoint_n, device_max_waypoint); + } + + message_init_size(&m, 0); + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m)) { + device_n = le_readu32(m.data); + } + + waypt_disp_all(write_waypoint); + send_batch(); + + if (device_n + waypoint_n > device_max_waypoint) { + m.size = 0; + message_write(MSG_WAYPOINT_COUNT, &m); + if (message_read(MSG_WAYPOINT_COUNT, &m) && + le_readu32(m.data) == device_max_waypoint) { + warning(MYNAME ": waypoint count (%u already on device + %u added = %u)" + " exceeds device limit (%u), some may have been discarded\n", + device_n, waypoint_n, device_n + waypoint_n, device_max_waypoint); + } + } + message_free(&m); } //----------------------------------------------------------------------------- @@ -1428,182 +1495,196 @@ write_waypoints(void) static void decode_sat_fix(waypoint* wp, const gbuint8 status) { - switch (status & 3) { - case 1: wp->fix = fix_none; break; - case 2: wp->fix = fix_2d; break; - case 3: - wp->fix = fix_3d; - if (status & 4) { - wp->fix = fix_dgps; - } - break; - } + switch (status & 3) { + case 1: + wp->fix = fix_none; + break; + case 2: + wp->fix = fix_2d; + break; + case 3: + wp->fix = fix_3d; + if (status & 4) { + wp->fix = fix_dgps; + } + break; + } } static void decode_track_point(const void* data, unsigned* wp_array_i, unsigned max_point) { - const msg_track_point_t* p = data; - const unsigned n = p->number; - unsigned i; - unsigned j = *wp_array_i; - - if (j + n > max_point) { - fatal(MYNAME ": read too many track points\n"); - } - for (i = 0; i < n; i++, j++) { - waypoint* wp = waypt_new(); - float elev = le_read_float(p->point[i].elevation); - wp_array[j] = wp; - wp->creation_time = decode_time(&p->point[i].year); - wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); - if (elev > UNKNOWN_ELEV) { - wp->altitude = elev; - } - wp->speed = le_readu16(p->point[i].speed); - wp->speed *= (100.0f / (60 * 60)); - wp->wpt_flags.speed = 1; - decode_sat_fix(wp, p->point[i].status); - wp->wpt_flags.new_trkseg = (p->point[i].status & 0x10) != 0; - } - *wp_array_i = j; + const msg_track_point_t* p = data; + const unsigned n = p->number; + unsigned i; + unsigned j = *wp_array_i; + + if (j + n > max_point) { + fatal(MYNAME ": read too many track points\n"); + } + for (i = 0; i < n; i++, j++) { + waypoint* wp = waypt_new(); + float elev = le_read_float(p->point[i].elevation); + wp_array[j] = wp; + wp->creation_time = decode_time(&p->point[i].year); + wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); + if (elev > UNKNOWN_ELEV) { + wp->altitude = elev; + } + wp->speed = le_readu16(p->point[i].speed); + wp->speed *= (100.0f / (60 * 60)); + wp->wpt_flags.speed = 1; + decode_sat_fix(wp, p->point[i].status); + wp->wpt_flags.new_trkseg = (p->point[i].status & 0x10) != 0; + } + *wp_array_i = j; } static void read_track(route_head* track) { - message_t m; - message_t* msg_array; - const msg_track_header_t* p; - unsigned msg_array_n; - unsigned wp_array_i = 0; - unsigned n_point; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // read track messages - for (;;) { - m.size = MSG_REQUEST_TRACKS_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 1; // Download single track - strcpy((char*)m.data + 1, track->rte_name); - message_write(MSG_REQUEST_TRACKS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track '%s' failed\n", track->rte_name); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading track '%s', retrying\n", track->rte_name); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_TRACK_HEADER_OUT) { - fatal(MYNAME ": reading track '%s' failed (missing track header)\n", track->rte_name); - } - // process track messages - p = msg_array[0].data; - if (le_readu16(p->comment_size)) { - track->rte_desc = xstrdup(p->comment); - } - track->line_color.bbggrr = track_color(p->color[0]); - n_point = le_readu32(p->total_points); - wp_array = xcalloc(n_point, sizeof(*wp_array)); - message_free(&msg_array[0]); - for (i = 1; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_TRACK_POINT_OUT) { - decode_track_point(msg_array[i].data, &wp_array_i, n_point); - } else { - fatal(MYNAME ": unexpected message %x while reading track '%s'\n", id, track->rte_name); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - if (n_point != wp_array_i) { - fatal(MYNAME ": track point count mismatch, expected %u, got %u\n", n_point, wp_array_i); - } - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": read track '%s' %u points\n", track->rte_name, n_point); - for (i = 0; i < n_point; i++) { - track_add_wpt(track, wp_array[i]); - } - track_add_head(track); - xfree(wp_array); + message_t m; + message_t* msg_array; + const msg_track_header_t* p; + unsigned msg_array_n; + unsigned wp_array_i = 0; + unsigned n_point; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // read track messages + for (;;) { + m.size = MSG_REQUEST_TRACKS_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 1; // Download single track + strcpy((char*)m.data + 1, track->rte_name); + message_write(MSG_REQUEST_TRACKS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track '%s' failed\n", track->rte_name); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading track '%s', retrying\n", track->rte_name); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_TRACK_HEADER_OUT) { + fatal(MYNAME ": reading track '%s' failed (missing track header)\n", track->rte_name); + } + // process track messages + p = msg_array[0].data; + if (le_readu16(p->comment_size)) { + track->rte_desc = xstrdup(p->comment); + } + track->line_color.bbggrr = track_color(p->color[0]); + n_point = le_readu32(p->total_points); + wp_array = xcalloc(n_point, sizeof(*wp_array)); + message_free(&msg_array[0]); + for (i = 1; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_TRACK_POINT_OUT) { + decode_track_point(msg_array[i].data, &wp_array_i, n_point); + } else { + fatal(MYNAME ": unexpected message %x while reading track '%s'\n", id, track->rte_name); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + if (n_point != wp_array_i) { + fatal(MYNAME ": track point count mismatch, expected %u, got %u\n", n_point, wp_array_i); + } + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": read track '%s' %u points\n", track->rte_name, n_point); + } + for (i = 0; i < n_point; i++) { + track_add_wpt(track, wp_array[i]); + } + track_add_head(track); + xfree(wp_array); } static void read_tracks(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - route_head** track_array; - unsigned total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of tracks - for (;;) { - m.size = 0; - message_write(MSG_TRACK_COUNT, &m); - if (message_read(MSG_TRACK_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track count failed\n"); - } - total = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u tracks\n", total); - if (total == 0) { - message_free(&m); - return; - } - - // First get track headers, then request each track with non-zero number of points - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_TRACKS_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 2; // Download all track headers - message_write(MSG_REQUEST_TRACKS, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading track headers failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading track headers, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - track_array = xcalloc(total, sizeof(*track_array)); - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_TRACK_HEADER_OUT) { - const msg_track_header_t* p = msg_array[i].data; - if (le_readu32(p->total_points)) { - track_array[i] = route_head_alloc(); - track_array[i]->rte_name = xstrdup(p->name); - } - } else { - fatal(MYNAME ": unexpected message %x while reading track headers\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - // get each track - for (i = 0; i < total; i++) { - if (track_array[i]) { - read_track(track_array[i]); - } - } - xfree(track_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + route_head** track_array; + unsigned total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of tracks + for (;;) { + m.size = 0; + message_write(MSG_TRACK_COUNT, &m); + if (message_read(MSG_TRACK_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track count failed\n"); + } + } + total = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u tracks\n", total); + } + if (total == 0) { + message_free(&m); + return; + } + + // First get track headers, then request each track with non-zero number of points + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_TRACKS_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 2; // Download all track headers + message_write(MSG_REQUEST_TRACKS, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading track headers failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading track headers, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + track_array = xcalloc(total, sizeof(*track_array)); + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_TRACK_HEADER_OUT) { + const msg_track_header_t* p = msg_array[i].data; + if (le_readu32(p->total_points)) { + track_array[i] = route_head_alloc(); + track_array[i]->rte_name = xstrdup(p->name); + } + } else { + fatal(MYNAME ": unexpected message %x while reading track headers\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + // get each track + for (i = 0; i < total; i++) { + if (track_array[i]) { + read_track(track_array[i]); + } + } + xfree(track_array); } //----------------------------------------------------------------------------- @@ -1612,112 +1693,122 @@ read_tracks(void) static void write_track_points(void) { - message_t m; - const unsigned pt_per_msg = 10; - msg_track_point_t* p = NULL; - unsigned i = 0; - unsigned j = 0; - - do { - const waypoint* wp = wp_array[i]; - float f; - - if (j == 0) { - message_init_size(&m, 9 + 23 * pt_per_msg); - p = m.data; - le_write32(p->total, waypoint_n); - le_write32(p->index, i + 1); - } - assert(p); - encode_time(wp->creation_time, &p->point[j].year); - le_write32(p->point[j].latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->point[j].longitude, delbin_deg2rad(wp->longitude)); - f = UNKNOWN_ELEV; - if (wp->altitude > unknown_alt) { - f = wp->altitude; - } - le_write_float(p->point[j].elevation, f); - f = WAYPT_GET(wp, speed, 0); - f *= (60 * 60) / 100; - le_write16(p->point[j].speed, (gbuint16)f); - f = WAYPT_GET(wp, course, 0); - f *= 100; - le_write16(p->point[j].heading, (gbuint16)f); - switch (wp->fix) { - default: p->point[j].status = 0; break; - case fix_none: p->point[j].status = 1; break; - case fix_2d: p->point[j].status = 2; break; - case fix_3d: p->point[j].status = 3; break; - case fix_dgps: p->point[j].status = 4 | 3; break; - } - if (wp->wpt_flags.new_trkseg) { - p->point[j].status |= 0x10; - } - i++; - j++; - if (j == pt_per_msg || i == waypoint_n) { - p->number = j; - m.size = 9 + 23 * j; - add_to_batch(MSG_TRACK_POINT_IN, &m); - j = 0; - } - } while (i < waypoint_n); + message_t m; + const unsigned pt_per_msg = 10; + msg_track_point_t* p = NULL; + unsigned i = 0; + unsigned j = 0; + + do { + const waypoint* wp = wp_array[i]; + float f; + + if (j == 0) { + message_init_size(&m, 9 + 23 * pt_per_msg); + p = m.data; + le_write32(p->total, waypoint_n); + le_write32(p->index, i + 1); + } + assert(p); + encode_time(wp->creation_time, &p->point[j].year); + le_write32(p->point[j].latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->point[j].longitude, delbin_deg2rad(wp->longitude)); + f = UNKNOWN_ELEV; + if (wp->altitude > unknown_alt) { + f = wp->altitude; + } + le_write_float(p->point[j].elevation, f); + f = WAYPT_GET(wp, speed, 0); + f *= (60 * 60) / 100; + le_write16(p->point[j].speed, (gbuint16)f); + f = WAYPT_GET(wp, course, 0); + f *= 100; + le_write16(p->point[j].heading, (gbuint16)f); + switch (wp->fix) { + default: + p->point[j].status = 0; + break; + case fix_none: + p->point[j].status = 1; + break; + case fix_2d: + p->point[j].status = 2; + break; + case fix_3d: + p->point[j].status = 3; + break; + case fix_dgps: + p->point[j].status = 4 | 3; + break; + } + if (wp->wpt_flags.new_trkseg) { + p->point[j].status |= 0x10; + } + i++; + j++; + if (j == pt_per_msg || i == waypoint_n) { + p->number = j; + m.size = 9 + 23 * j; + add_to_batch(MSG_TRACK_POINT_IN, &m); + j = 0; + } + } while (i < waypoint_n); } static void write_track_begin(const route_head* track) { - waypoint_i = 0; - waypoint_n = track->rte_waypt_ct; - if (waypoint_n) { - wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); - } + waypoint_i = 0; + waypoint_n = track->rte_waypt_ct; + if (waypoint_n) { + wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); + } } static void write_track_point(const waypoint* wp) { - wp_array[waypoint_i++] = (waypoint*)wp; + wp_array[waypoint_i++] = (waypoint*)wp; } static void write_track_end(const route_head* track) { - message_t m; - msg_track_header_in_t* p; - unsigned comment_size = 0; - - if (waypoint_n == 0) { - return; - } - if (track->rte_desc) { - comment_size = strlen(track->rte_desc) + 1; - } - message_init_size(&m, sizeof(msg_track_header_in_t) - 1 + comment_size); - p = m.data; - memset(p->name, 0, sizeof(p->name)); - if (track->rte_name) { - strncpy(p->name, track->rte_name, sizeof(p->name) - 1); - } else { - sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); - } - le_write32(p->total_points, waypoint_n); - encode_time(current_time(), &p->year); - le_write16(p->color, track_color_index(track->line_color.bbggrr)); - le_write16(p->comment_size, comment_size); - if (comment_size) { - memcpy(p->comment, track->rte_desc, comment_size); - } - add_to_batch(MSG_TRACK_HEADER_IN, &m); - write_track_points(); - send_batch(); - xfree(wp_array); + message_t m; + msg_track_header_in_t* p; + unsigned comment_size = 0; + + if (waypoint_n == 0) { + return; + } + if (track->rte_desc) { + comment_size = strlen(track->rte_desc) + 1; + } + message_init_size(&m, sizeof(msg_track_header_in_t) - 1 + comment_size); + p = m.data; + memset(p->name, 0, sizeof(p->name)); + if (track->rte_name) { + strncpy(p->name, track->rte_name, sizeof(p->name) - 1); + } else { + sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); + } + le_write32(p->total_points, waypoint_n); + encode_time(current_time(), &p->year); + le_write16(p->color, track_color_index(track->line_color.bbggrr)); + le_write16(p->comment_size, comment_size); + if (comment_size) { + memcpy(p->comment, track->rte_desc, comment_size); + } + add_to_batch(MSG_TRACK_HEADER_IN, &m); + write_track_points(); + send_batch(); + xfree(wp_array); } static void write_tracks(void) { - track_disp_all(write_track_begin, write_track_end, write_track_point); + track_disp_all(write_track_begin, write_track_end, write_track_point); } //----------------------------------------------------------------------------- @@ -1726,208 +1817,246 @@ write_tracks(void) static void decode_route_shape(const void* data, unsigned* wp_array_i) { - const msg_route_shape_t* p = data; - const unsigned n = p->number; - unsigned i; - unsigned j = *wp_array_i; + const msg_route_shape_t* p = data; + const unsigned n = p->number; + unsigned i; + unsigned j = *wp_array_i; - for (i = 0; i < n; i++, j++) { - char buf[32]; - waypoint* wp = waypt_new(); - wp_array[j] = wp; - wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); - sprintf(buf, "SHP%03u", j); - wp->shortname = xstrdup(buf); - } - *wp_array_i = j; + for (i = 0; i < n; i++, j++) { + char buf[32]; + waypoint* wp = waypt_new(); + wp_array[j] = wp; + wp->latitude = delbin_rad2deg(le_read32(p->point[i].latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->point[i].longitude)); + sprintf(buf, "SHP%03u", j); + wp->shortname = xstrdup(buf); + } + *wp_array_i = j; } static waypoint* decode_route_point(const void* data) { - const msg_route_point_t* p = data; - const char* s = NULL; - gbfile* fd = gbfopen(NULL, "w", MYNAME); - waypoint* wp = waypt_new(); - if (p->name[0]) { - wp->shortname = xstrdup(p->name); - } - // give these a higher priority than the shape points - wp->route_priority = 1; - wp->latitude = delbin_rad2deg(le_read32(p->latitude)); - wp->longitude = delbin_rad2deg(le_read32(p->longitude)); - switch (p->itinerary_type) { - case 1: s = "Start"; break; - case 2: s = "Stop"; break; - case 3: s = "Finish"; break; - case 4: s = "Via"; break; - case 5: s = "Via Hidden"; break; - case 6: - switch (p->turn_type) { - case 1: s = "Turn, Straight"; break; - case 2: s = "Turn, Right"; break; - case 3: s = "Turn, Bear Right"; break; - case 4: s = "Turn, Keep Right"; break; - case 5: s = "Turn, Left"; break; - case 6: s = "Turn, Bear Left"; break; - case 7: s = "Turn, Keep Left"; break; - case 8: s = "Turn, Reverse Direction"; break; - case 9: s = "Turn, Street Name Change"; break; - } - break; - } - if (s) { - gbfprintf(fd, "Type: %s", s); - } - if (p->exit_label_size && p->exit_label[0]) { - gbfprintf(fd, "\nExit: %s", p->exit_label); - } - s = p->exit_label + p->exit_label_size; - if (s[0] && s[1]) { - gbfprintf(fd, "\n%s", s + 1); - } - if (fd->memlen) { - gbfputc(0, fd); - wp->notes = xmalloc(fd->memlen); - memcpy(wp->notes, fd->handle.mem, fd->memlen); - } - gbfclose(fd); - return wp; + const msg_route_point_t* p = data; + const char* s = NULL; + gbfile* fd = gbfopen(NULL, "w", MYNAME); + waypoint* wp = waypt_new(); + if (p->name[0]) { + wp->shortname = xstrdup(p->name); + } + // give these a higher priority than the shape points + wp->route_priority = 1; + wp->latitude = delbin_rad2deg(le_read32(p->latitude)); + wp->longitude = delbin_rad2deg(le_read32(p->longitude)); + switch (p->itinerary_type) { + case 1: + s = "Start"; + break; + case 2: + s = "Stop"; + break; + case 3: + s = "Finish"; + break; + case 4: + s = "Via"; + break; + case 5: + s = "Via Hidden"; + break; + case 6: + switch (p->turn_type) { + case 1: + s = "Turn, Straight"; + break; + case 2: + s = "Turn, Right"; + break; + case 3: + s = "Turn, Bear Right"; + break; + case 4: + s = "Turn, Keep Right"; + break; + case 5: + s = "Turn, Left"; + break; + case 6: + s = "Turn, Bear Left"; + break; + case 7: + s = "Turn, Keep Left"; + break; + case 8: + s = "Turn, Reverse Direction"; + break; + case 9: + s = "Turn, Street Name Change"; + break; + } + break; + } + if (s) { + gbfprintf(fd, "Type: %s", s); + } + if (p->exit_label_size && p->exit_label[0]) { + gbfprintf(fd, "\nExit: %s", p->exit_label); + } + s = p->exit_label + p->exit_label_size; + if (s[0] && s[1]) { + gbfprintf(fd, "\n%s", s + 1); + } + if (fd->memlen) { + gbfputc(0, fd); + wp->notes = xmalloc(fd->memlen); + memcpy(wp->notes, fd->handle.mem, fd->memlen); + } + gbfclose(fd); + return wp; } static void read_route(route_head* route) { - message_t m; - message_t* msg_array; - const msg_route_header_t* p; - unsigned msg_array_n; - unsigned wp_array_i = 0; - unsigned route_total, shape_total, total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - for (;;) { - m.size = MSG_REQUEST_ROUTES_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 1; // Download single route - strcpy((char*)m.data + 1, route->rte_name); - message_write(MSG_REQUEST_ROUTES, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route '%s' failed (timed out)\n", route->rte_name); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading route route '%s', retrying\n", route->rte_name); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_ROUTE_HEADER_OUT) { - fatal(MYNAME ": missing route header\n"); - } - p = msg_array[0].data; - route_total = le_readu32(p->total_route_point); - shape_total = le_readu32(p->total_shape_point); - total = route_total + shape_total; - wp_array = xcalloc(total, sizeof(*wp_array)); - if (global_opts.debug_level >= DBGLVL_L) { - warning(MYNAME ": route '%s' %u points, %u shape points\n", - route->rte_name, route_total, shape_total); - } - message_free(&msg_array[0]); - for (i = 1; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_ROUTE_POINT_OUT) { - wp_array[wp_array_i] = decode_route_point(msg_array[i].data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": route point '%s'\n", wp_array[wp_array_i]->shortname); - wp_array_i++; - } else if (id == MSG_ROUTE_SHAPE_OUT) { - decode_route_shape(msg_array[i].data, &wp_array_i); - } else { - fatal(MYNAME ": unexpected message %x while reading route '%s'\n", id, route->rte_name); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - if (total != wp_array_i) { - fatal(MYNAME ": route point count mismatch, expected %u, got %u\n", total, wp_array_i); - } - for (i = 0; i < total; i++) { - route_add_wpt(route, wp_array[i]); - } - xfree(wp_array); - route_add_head(route); + message_t m; + message_t* msg_array; + const msg_route_header_t* p; + unsigned msg_array_n; + unsigned wp_array_i = 0; + unsigned route_total, shape_total, total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + for (;;) { + m.size = MSG_REQUEST_ROUTES_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 1; // Download single route + strcpy((char*)m.data + 1, route->rte_name); + message_write(MSG_REQUEST_ROUTES, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route '%s' failed (timed out)\n", route->rte_name); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading route route '%s', retrying\n", route->rte_name); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + if (msg_array_n == 0 || message_get_id(&msg_array[0]) != MSG_ROUTE_HEADER_OUT) { + fatal(MYNAME ": missing route header\n"); + } + p = msg_array[0].data; + route_total = le_readu32(p->total_route_point); + shape_total = le_readu32(p->total_shape_point); + total = route_total + shape_total; + wp_array = xcalloc(total, sizeof(*wp_array)); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": route '%s' %u points, %u shape points\n", + route->rte_name, route_total, shape_total); + } + message_free(&msg_array[0]); + for (i = 1; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_ROUTE_POINT_OUT) { + wp_array[wp_array_i] = decode_route_point(msg_array[i].data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": route point '%s'\n", wp_array[wp_array_i]->shortname); + } + wp_array_i++; + } else if (id == MSG_ROUTE_SHAPE_OUT) { + decode_route_shape(msg_array[i].data, &wp_array_i); + } else { + fatal(MYNAME ": unexpected message %x while reading route '%s'\n", id, route->rte_name); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + if (total != wp_array_i) { + fatal(MYNAME ": route point count mismatch, expected %u, got %u\n", total, wp_array_i); + } + for (i = 0; i < total; i++) { + route_add_wpt(route, wp_array[i]); + } + xfree(wp_array); + route_add_head(route); } static void read_routes(void) { - message_t m; - message_t* msg_array; - unsigned msg_array_n; - route_head** route_array; - unsigned total; - unsigned i; - int attempt = ATTEMPT_MAX; - - message_init(&m); - // get number of routes - for (;;) { - m.size = 0; - message_write(MSG_ROUTE_COUNT, &m); - if (message_read(MSG_ROUTE_COUNT, &m)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route count failed\n"); - } - total = le_readu32(m.data); - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": %u routes\n", total); - if (total == 0) { - message_free(&m); - return; - } - - // First get route headers, then request each route - attempt = ATTEMPT_MAX; - for (;;) { - m.size = MSG_REQUEST_ROUTES_SIZE; - memset(m.data, 0, m.size); - ((char*)m.data)[0] = 2; // Download all route headers - message_write(MSG_REQUEST_ROUTES, &m); - if (get_batch(&msg_array, &msg_array_n)) - break; - if (--attempt == 0) - fatal(MYNAME ": reading route headers failed\n"); - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": timed out reading route headers, retrying\n"); - m.size = MSG_BREAK_SIZE; - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - } - message_free(&m); - route_array = xcalloc(total, sizeof(*route_array)); - for (i = 0; i < msg_array_n; i++) { - unsigned id = message_get_id(&msg_array[i]); - if (id == MSG_ROUTE_HEADER_OUT) { - route_array[i] = route_head_alloc(); - route_array[i]->rte_name = xstrdup(((msg_route_header_t*)msg_array[i].data)->name); - } else { - fatal(MYNAME ": unexpected message %x while reading route headers\n", id); - } - message_free(&msg_array[i]); - } - xfree(msg_array); - // get each route - for (i = 0; i < total; i++) { - read_route(route_array[i]); - } - xfree(route_array); + message_t m; + message_t* msg_array; + unsigned msg_array_n; + route_head** route_array; + unsigned total; + unsigned i; + int attempt = ATTEMPT_MAX; + + message_init(&m); + // get number of routes + for (;;) { + m.size = 0; + message_write(MSG_ROUTE_COUNT, &m); + if (message_read(MSG_ROUTE_COUNT, &m)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route count failed\n"); + } + } + total = le_readu32(m.data); + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": %u routes\n", total); + } + if (total == 0) { + message_free(&m); + return; + } + + // First get route headers, then request each route + attempt = ATTEMPT_MAX; + for (;;) { + m.size = MSG_REQUEST_ROUTES_SIZE; + memset(m.data, 0, m.size); + ((char*)m.data)[0] = 2; // Download all route headers + message_write(MSG_REQUEST_ROUTES, &m); + if (get_batch(&msg_array, &msg_array_n)) { + break; + } + if (--attempt == 0) { + fatal(MYNAME ": reading route headers failed\n"); + } + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": timed out reading route headers, retrying\n"); + } + m.size = MSG_BREAK_SIZE; + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + } + message_free(&m); + route_array = xcalloc(total, sizeof(*route_array)); + for (i = 0; i < msg_array_n; i++) { + unsigned id = message_get_id(&msg_array[i]); + if (id == MSG_ROUTE_HEADER_OUT) { + route_array[i] = route_head_alloc(); + route_array[i]->rte_name = xstrdup(((msg_route_header_t*)msg_array[i].data)->name); + } else { + fatal(MYNAME ": unexpected message %x while reading route headers\n", id); + } + message_free(&msg_array[i]); + } + xfree(msg_array); + // get each route + for (i = 0; i < total; i++) { + read_route(route_array[i]); + } + xfree(route_array); } //----------------------------------------------------------------------------- @@ -1940,138 +2069,138 @@ static unsigned* shape_point_counts; static void write_route_shape_points(waypoint** array, unsigned n) { - message_t m; - const unsigned pt_per_msg = 25; - msg_route_shape_t* p = NULL; - unsigned i = 0; - unsigned j = 0; - - do { - if (j == 0) { - message_init_size(&m, 10 + 8 * pt_per_msg); - p = m.data; - le_write32(p->total, n); - le_write32(p->index, i + 1); - p->reserved = 0; - } - assert(p); - le_write32(p->point[j].latitude, delbin_deg2rad(array[i]->latitude)); - le_write32(p->point[j].longitude, delbin_deg2rad(array[i]->longitude)); - i++; - j++; - if (j == pt_per_msg || i == n) { - p->number = j; - m.size = 10 + 8 * j; - add_to_batch(MSG_ROUTE_SHAPE_IN, &m); - j = 0; - } - } while (i < n); + message_t m; + const unsigned pt_per_msg = 25; + msg_route_shape_t* p = NULL; + unsigned i = 0; + unsigned j = 0; + + do { + if (j == 0) { + message_init_size(&m, 10 + 8 * pt_per_msg); + p = m.data; + le_write32(p->total, n); + le_write32(p->index, i + 1); + p->reserved = 0; + } + assert(p); + le_write32(p->point[j].latitude, delbin_deg2rad(array[i]->latitude)); + le_write32(p->point[j].longitude, delbin_deg2rad(array[i]->longitude)); + i++; + j++; + if (j == pt_per_msg || i == n) { + p->number = j; + m.size = 10 + 8 * j; + add_to_batch(MSG_ROUTE_SHAPE_IN, &m); + j = 0; + } + } while (i < n); } static void write_route_points(void) { - unsigned route_point_i = 0; - unsigned i = 0; - - while (i < waypoint_n) { - message_t m; - unsigned shape_n; - const waypoint* wp = wp_array[i]; - msg_route_point_t* p; - char* s; - - message_init_size(&m, sizeof(msg_route_point_t) + 1 + 1 + 4); - p = m.data; - memset(m.data, 0, m.size); - route_point_i++; - shape_n = shape_point_counts[route_point_i]; - le_write32(p->total, route_point_n); - le_write32(p->index, route_point_i); - if (wp->shortname) { - strncpy(p->name, wp->shortname, sizeof(p->name) - 1); - } else { - sprintf(p->name, "RPT%u", route_point_i); - } - le_write32(p->latitude, delbin_deg2rad(wp->latitude)); - le_write32(p->longitude, delbin_deg2rad(wp->longitude)); - p->exit_label_size = 1; - s = p->exit_label + p->exit_label_size; - s[0] = 1; // comment size - le_write32(s + 2, shape_n); - if (route_point_i == 1) { - p->itinerary_type = 1; // start - } else if (route_point_i == route_point_n) { - p->itinerary_type = 3; // finish - } - add_to_batch(MSG_ROUTE_POINT_IN, &m); - i++; - if (shape_n) { - write_route_shape_points(&wp_array[i], shape_n); - i += shape_n; - } - } + unsigned route_point_i = 0; + unsigned i = 0; + + while (i < waypoint_n) { + message_t m; + unsigned shape_n; + const waypoint* wp = wp_array[i]; + msg_route_point_t* p; + char* s; + + message_init_size(&m, sizeof(msg_route_point_t) + 1 + 1 + 4); + p = m.data; + memset(m.data, 0, m.size); + route_point_i++; + shape_n = shape_point_counts[route_point_i]; + le_write32(p->total, route_point_n); + le_write32(p->index, route_point_i); + if (wp->shortname) { + strncpy(p->name, wp->shortname, sizeof(p->name) - 1); + } else { + sprintf(p->name, "RPT%u", route_point_i); + } + le_write32(p->latitude, delbin_deg2rad(wp->latitude)); + le_write32(p->longitude, delbin_deg2rad(wp->longitude)); + p->exit_label_size = 1; + s = p->exit_label + p->exit_label_size; + s[0] = 1; // comment size + le_write32(s + 2, shape_n); + if (route_point_i == 1) { + p->itinerary_type = 1; // start + } else if (route_point_i == route_point_n) { + p->itinerary_type = 3; // finish + } + add_to_batch(MSG_ROUTE_POINT_IN, &m); + i++; + if (shape_n) { + write_route_shape_points(&wp_array[i], shape_n); + i += shape_n; + } + } } static void write_route_begin(const route_head* track) { - waypoint_i = 0; - route_point_n = 0; - shape_point_n = 0; - waypoint_n = track->rte_waypt_ct; - if (waypoint_n) { - wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); - shape_point_counts = xcalloc(waypoint_n, sizeof(*shape_point_counts)); - } + waypoint_i = 0; + route_point_n = 0; + shape_point_n = 0; + waypoint_n = track->rte_waypt_ct; + if (waypoint_n) { + wp_array = xmalloc(waypoint_n * sizeof(*wp_array)); + shape_point_counts = xcalloc(waypoint_n, sizeof(*shape_point_counts)); + } } static void write_route_point(const waypoint* wp) { - const char* s = wp->shortname; - wp_array[waypoint_i++] = (waypoint*)wp; - if (s && s[0] == 'S' && s[1] == 'H' && s[2] == 'P' && s[3] >= '0' && s[3] <= '9') { - shape_point_n++; - shape_point_counts[route_point_n]++; - } else { - route_point_n++; - } + const char* s = wp->shortname; + wp_array[waypoint_i++] = (waypoint*)wp; + if (s && s[0] == 'S' && s[1] == 'H' && s[2] == 'P' && s[3] >= '0' && s[3] <= '9') { + shape_point_n++; + shape_point_counts[route_point_n]++; + } else { + route_point_n++; + } } static void write_route_end(const route_head* route) { - message_t m; - msg_route_header_in_t* p; - - if (waypoint_n == 0) { - return; - } - message_init_size(&m, sizeof(msg_route_header_in_t)); - p = m.data; - memset(p->name, 0, sizeof(p->name)); - if (route->rte_name) { - strncpy(p->name, route->rte_name, sizeof(p->name) - 1); - } else { - sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); - } - p->type = 0; - le_write32(p->total_route_point, route_point_n); - le_write32(p->total_shape_point, shape_point_n); - add_to_batch(MSG_ROUTE_HEADER_IN, &m); - write_route_points(); - send_batch(); - if (wp_array) { - xfree(wp_array); - xfree(shape_point_counts); - } + message_t m; + msg_route_header_in_t* p; + + if (waypoint_n == 0) { + return; + } + message_init_size(&m, sizeof(msg_route_header_in_t)); + p = m.data; + memset(p->name, 0, sizeof(p->name)); + if (route->rte_name) { + strncpy(p->name, route->rte_name, sizeof(p->name) - 1); + } else { + sprintf(p->name, "%lu", (long)wp_array[0]->creation_time); + } + p->type = 0; + le_write32(p->total_route_point, route_point_n); + le_write32(p->total_shape_point, shape_point_n); + add_to_batch(MSG_ROUTE_HEADER_IN, &m); + write_route_points(); + send_batch(); + if (wp_array) { + xfree(wp_array); + xfree(shape_point_counts); + } } static void write_routes(void) { - route_disp_all(write_route_begin, write_route_end, write_route_point); + route_disp_all(write_route_begin, write_route_end, write_route_point); } //----------------------------------------------------------------------------- @@ -2080,54 +2209,53 @@ write_routes(void) static waypoint* decode_navmsg(const void* data) { - waypoint* wp = waypt_new(); - const msg_navigation_t* p = data; - struct tm t; - - t.tm_year = le_readu16(p->year) - 1900; - t.tm_mon = p->month - 1; - t.tm_mday = p->day; - t.tm_hour = p->hour; - t.tm_min = p->minute; - t.tm_sec = p->second; - wp->creation_time = mkgmtime(&t); - wp->sat = p->satellites; - wp->latitude = le_read_double(p->latitude); - wp->longitude = le_read_double(p->longitude); - wp->altitude = le_read_double(p->elevation); - wp->speed = le_read_float(p->speed); - wp->speed *= (1000.0f / (60 * 60)); - wp->wpt_flags.speed = 1; - wp->course = le_readu16(p->heading); - wp->course /= 100; - wp->wpt_flags.course = 1; - decode_sat_fix(wp, p->fix_status); - wp->shortname = xstrdup("Position"); - return wp; + waypoint* wp = waypt_new(); + const msg_navigation_t* p = data; + struct tm t; + + t.tm_year = le_readu16(p->year) - 1900; + t.tm_mon = p->month - 1; + t.tm_mday = p->day; + t.tm_hour = p->hour; + t.tm_min = p->minute; + t.tm_sec = p->second; + wp->creation_time = mkgmtime(&t); + wp->sat = p->satellites; + wp->latitude = le_read_double(p->latitude); + wp->longitude = le_read_double(p->longitude); + wp->altitude = le_read_double(p->elevation); + wp->speed = le_read_float(p->speed); + wp->speed *= (1000.0f / (60 * 60)); + wp->wpt_flags.speed = 1; + wp->course = le_readu16(p->heading); + wp->course /= 100; + wp->wpt_flags.course = 1; + decode_sat_fix(wp, p->fix_status); + wp->shortname = xstrdup("Position"); + return wp; } static waypoint* read_position(void) { - waypoint* wp; - message_t m; - - message_init(&m); - message_read(MSG_NAVIGATION, &m); - wp = decode_navmsg(m.data); - if (wp->fix > fix_none && - message_read_1(MSG_SATELLITE_INFO, &m) == MSG_SATELLITE_INFO) - { - const msg_satellite_t* p = m.data; - wp->hdop = le_readu16(p->hdop); - wp->hdop /= 100; - wp->vdop = le_readu16(p->vdop); - wp->vdop /= 100; - wp->pdop = le_readu16(p->pdop); - wp->pdop /= 100; - } - message_free(&m); - return wp; + waypoint* wp; + message_t m; + + message_init(&m); + message_read(MSG_NAVIGATION, &m); + wp = decode_navmsg(m.data); + if (wp->fix > fix_none && + message_read_1(MSG_SATELLITE_INFO, &m) == MSG_SATELLITE_INFO) { + const msg_satellite_t* p = m.data; + wp->hdop = le_readu16(p->hdop); + wp->hdop /= 100; + wp->vdop = le_readu16(p->vdop); + wp->vdop /= 100; + wp->pdop = le_readu16(p->pdop); + wp->pdop /= 100; + } + message_free(&m); + return wp; } //----------------------------------------------------------------------------- @@ -2135,147 +2263,155 @@ read_position(void) static void delbin_list_units() { - int i; - for (i = 0; i < n_delbin_units; i++) { - printf("%u %s %s\n", - delbin_unit_info[i].unit_number, - delbin_unit_info[i].unit_serial_number, - delbin_unit_info[i].unit_name ); - } + int i; + for (i = 0; i < n_delbin_units; i++) { + printf("%u %s %s\n", + delbin_unit_info[i].unit_number, + delbin_unit_info[i].unit_serial_number, + delbin_unit_info[i].unit_name); + } } static void delbin_rw_init(const char *fname) { - message_t m; - char buf[256]; - - if (!mkshort_handle) - mkshort_handle = mkshort_new_handle(); - // Contrary to doc, it looks like there's a limit of 32 bytes - // and a null terminator is required, at least in F/W 2.6.210726 - // on a PN-40. - setshort_length(mkshort_handle, 31); - setshort_whitespace_ok(mkshort_handle, 1); - setshort_badchars(mkshort_handle, ""); - setshort_mustuniq(mkshort_handle, 1); - - delbin_os_ops.init(fname); - - // Often the first packet is part of an old message, sometimes it can - // confuse the first message read if we don't get rid of it - packet_read(buf); - // Send a break to clear any state from a previous failure - message_init_size(&m, MSG_BREAK_SIZE); - memset(m.data, 0, m.size); - message_write(MSG_BREAK, &m); - // get version info - m.size = 0; - message_write(MSG_VERSION, &m); - if (message_read(MSG_VERSION, &m)) { - const msg_version_t* p = m.data; - if (global_opts.debug_level >= DBGLVL_L) - warning(MYNAME ": device %s %s\n", p->product, p->firmware); - if (opt_long_notes) { - use_extended_notes = TRUE; - } else if (strstr(p->product, "PN-20")) { - use_extended_notes = p->firmware[0] > '1' || - (p->firmware[0] == '1' && p->firmware[2] >= '6'); - } else if (strstr(p->product, "PN-30") || strstr(p->product, "PN-40")) { - use_extended_notes = p->firmware[0] > '2' || - (p->firmware[0] == '2' && p->firmware[2] >= '5'); - } else { - // assume PN-60 or later - use_extended_notes = TRUE; - } - delbin_unit_info[n_delbin_units].unit_number = n_delbin_units; - delbin_unit_info[n_delbin_units].unit_serial_number = xstrndup(p->serial, sizeof(p->serial)); - delbin_unit_info[n_delbin_units].unit_name = xstrndup(p->product, sizeof(p->product)); - n_delbin_units++; - } - message_free(&m); - - if (strlen(fname) > 4) { - if (0 == strcmp(fname+4, "list")) { - delbin_list_units(); - exit(1); - } - } + message_t m; + char buf[256]; + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + // Contrary to doc, it looks like there's a limit of 32 bytes + // and a null terminator is required, at least in F/W 2.6.210726 + // on a PN-40. + setshort_length(mkshort_handle, 31); + setshort_whitespace_ok(mkshort_handle, 1); + setshort_badchars(mkshort_handle, ""); + setshort_mustuniq(mkshort_handle, 1); + + delbin_os_ops.init(fname); + + // Often the first packet is part of an old message, sometimes it can + // confuse the first message read if we don't get rid of it + packet_read(buf); + // Send a break to clear any state from a previous failure + message_init_size(&m, MSG_BREAK_SIZE); + memset(m.data, 0, m.size); + message_write(MSG_BREAK, &m); + // get version info + m.size = 0; + message_write(MSG_VERSION, &m); + if (message_read(MSG_VERSION, &m)) { + const msg_version_t* p = m.data; + if (global_opts.debug_level >= DBGLVL_L) { + warning(MYNAME ": device %s %s\n", p->product, p->firmware); + } + if (opt_long_notes) { + use_extended_notes = TRUE; + } else if (strstr(p->product, "PN-20")) { + use_extended_notes = p->firmware[0] > '1' || + (p->firmware[0] == '1' && p->firmware[2] >= '6'); + } else if (strstr(p->product, "PN-30") || strstr(p->product, "PN-40")) { + use_extended_notes = p->firmware[0] > '2' || + (p->firmware[0] == '2' && p->firmware[2] >= '5'); + } else { + // assume PN-60 or later + use_extended_notes = TRUE; + } + delbin_unit_info[n_delbin_units].unit_number = n_delbin_units; + delbin_unit_info[n_delbin_units].unit_serial_number = xstrndup(p->serial, sizeof(p->serial)); + delbin_unit_info[n_delbin_units].unit_name = xstrndup(p->product, sizeof(p->product)); + n_delbin_units++; + } + message_free(&m); + + if (strlen(fname) > 4) { + if (0 == strcmp(fname+4, "list")) { + delbin_list_units(); + exit(1); + } + } } static void delbin_rw_deinit(void) { - if (mkshort_handle) { - mkshort_del_handle(&mkshort_handle); - } - delbin_os_ops.deinit(); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + delbin_os_ops.deinit(); } static void delbin_read(void) { - if (doing_wpts) { - if (opt_getposn) { - waypt_add(read_position()); - } else { - read_waypoints(); - } - } - if (doing_trks) { - read_tracks(); - } - if (doing_rtes) { - read_routes(); - } + if (doing_wpts) { + if (opt_getposn) { + waypt_add(read_position()); + } else { + read_waypoints(); + } + } + if (doing_trks) { + read_tracks(); + } + if (doing_rtes) { + read_routes(); + } } static void delbin_write(void) { - if (doing_wpts) { - message_t m; - device_max_waypoint = 1000; - message_init_size(&m, 0); - message_write(MSG_CAPABILITIES, &m); - if (message_read(MSG_CAPABILITIES, &m)) { - const msg_capabilities_t* p = m.data; - device_max_waypoint = le_readu32(p->max_waypoints); - } - message_free(&m); - - if (opt_nuke_wpt) add_nuke(nuke_type_wpt); - write_waypoints(); - } - if (doing_trks) { - if (opt_nuke_trk) add_nuke(nuke_type_trk); - write_tracks(); - } - if (doing_rtes) { - if (opt_nuke_rte) add_nuke(nuke_type_rte); - write_routes(); - } + if (doing_wpts) { + message_t m; + device_max_waypoint = 1000; + message_init_size(&m, 0); + message_write(MSG_CAPABILITIES, &m); + if (message_read(MSG_CAPABILITIES, &m)) { + const msg_capabilities_t* p = m.data; + device_max_waypoint = le_readu32(p->max_waypoints); + } + message_free(&m); + + if (opt_nuke_wpt) { + add_nuke(nuke_type_wpt); + } + write_waypoints(); + } + if (doing_trks) { + if (opt_nuke_trk) { + add_nuke(nuke_type_trk); + } + write_tracks(); + } + if (doing_rtes) { + if (opt_nuke_rte) { + add_nuke(nuke_type_rte); + } + write_routes(); + } } static waypoint* delbin_rd_position(posn_status* status) { - return read_position(); + return read_position(); } ff_vecs_t delbin_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - delbin_rw_init, - delbin_rw_init, - delbin_rw_deinit, - delbin_rw_deinit, - delbin_read, - delbin_write, - NULL, - delbin_args, - CET_CHARSET_LATIN1, 1, - { delbin_rw_init, delbin_rd_position, delbin_rw_deinit } + ff_type_serial, + FF_CAP_RW_ALL, + delbin_rw_init, + delbin_rw_init, + delbin_rw_deinit, + delbin_rw_deinit, + delbin_read, + delbin_write, + NULL, + delbin_args, + CET_CHARSET_LATIN1, 1, + { delbin_rw_init, delbin_rd_position, delbin_rw_deinit } }; //============================================================================= @@ -2293,7 +2429,7 @@ ff_vecs_t delbin_vecs = { #define WIN32_LEAN_AND_MEAN #include #include -// If hidsdi.h is not found, you need to download the Windows Driver Kit, +// If hidsdi.h is not found, you need to download the Windows Driver Kit, // from http://www.microsoft.com/whdc/Devtools/wdk/default.mspx // You need to install 'build environments' and 'tools' from the SDK and // follow the instructions in the Install.html to get MSVC to find the right @@ -2306,112 +2442,109 @@ static HANDLE hid_handle; static void win_os_init(const char* fname) { - GUID hid_guid; - HDEVINFO dev_info; - SP_DEVICE_INTERFACE_DATA dev_int_data; - PHIDP_PREPARSED_DATA hid_ppd; - HIDP_CAPS hid_caps; - const char* busy = ""; - unsigned i; - - hid_handle = INVALID_HANDLE_VALUE; - HidD_GetHidGuid(&hid_guid); - dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); - if (dev_info == INVALID_HANDLE_VALUE) { - fatal(MYNAME ": SetupDiGetClassDevs failed %u\n", GetLastError()); - } - dev_int_data.cbSize = sizeof(dev_int_data); - for (i = 0; SetupDiEnumDeviceInterfaces(dev_info, NULL, &hid_guid, i, &dev_int_data); i++) { - union { - SP_DEVICE_INTERFACE_DETAIL_DATA detail_data; - char buf[300]; - } u; - u.detail_data.cbSize = sizeof(u.detail_data); - if (SetupDiGetDeviceInterfaceDetail(dev_info, - &dev_int_data, &u.detail_data, sizeof(u.buf), NULL, NULL)) - { - HANDLE h = CreateFile(u.detail_data.DevicePath, - FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, 0, NULL); - if (h != INVALID_HANDLE_VALUE) { - HIDD_ATTRIBUTES hid_attr; - hid_attr.Size = sizeof(hid_attr); - if (HidD_GetAttributes(h, &hid_attr) && - hid_attr.VendorID == VENDOR_ID && hid_attr.ProductID == PRODUCT_ID) - { - hid_handle = h; - break; - } - CloseHandle(h); - } else if (GetLastError() == ERROR_SHARING_VIOLATION && - strstr(u.detail_data.DevicePath, "1163") && - strstr(u.detail_data.DevicePath, "2020")) - { - busy = " (device busy?)"; - } - } - } - SetupDiDestroyDeviceInfoList(dev_info); - if (hid_handle == INVALID_HANDLE_VALUE) { - fatal(MYNAME ": no DeLorme PN found%s\n", busy); - } - if (!HidD_GetPreparsedData(hid_handle, &hid_ppd)) { - fatal(MYNAME ": HidD_GetPreparsedData failed %u\n", GetLastError()); - } - if (!HidP_GetCaps(hid_ppd, &hid_caps)) { - fatal(MYNAME ": HidP_GetCaps failed %u\n", GetLastError()); - } - // report length includes report id - delbin_os_packet_size = hid_caps.InputReportByteLength - 1; - HidD_FreePreparsedData(hid_ppd); + GUID hid_guid; + HDEVINFO dev_info; + SP_DEVICE_INTERFACE_DATA dev_int_data; + PHIDP_PREPARSED_DATA hid_ppd; + HIDP_CAPS hid_caps; + const char* busy = ""; + unsigned i; + + hid_handle = INVALID_HANDLE_VALUE; + HidD_GetHidGuid(&hid_guid); + dev_info = SetupDiGetClassDevs(&hid_guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); + if (dev_info == INVALID_HANDLE_VALUE) { + fatal(MYNAME ": SetupDiGetClassDevs failed %u\n", GetLastError()); + } + dev_int_data.cbSize = sizeof(dev_int_data); + for (i = 0; SetupDiEnumDeviceInterfaces(dev_info, NULL, &hid_guid, i, &dev_int_data); i++) { + union { + SP_DEVICE_INTERFACE_DETAIL_DATA detail_data; + char buf[300]; + } u; + u.detail_data.cbSize = sizeof(u.detail_data); + if (SetupDiGetDeviceInterfaceDetail(dev_info, + &dev_int_data, &u.detail_data, sizeof(u.buf), NULL, NULL)) { + HANDLE h = CreateFile(u.detail_data.DevicePath, + FILE_READ_DATA | FILE_WRITE_DATA, 0, NULL, OPEN_EXISTING, 0, NULL); + if (h != INVALID_HANDLE_VALUE) { + HIDD_ATTRIBUTES hid_attr; + hid_attr.Size = sizeof(hid_attr); + if (HidD_GetAttributes(h, &hid_attr) && + hid_attr.VendorID == VENDOR_ID && hid_attr.ProductID == PRODUCT_ID) { + hid_handle = h; + break; + } + CloseHandle(h); + } else if (GetLastError() == ERROR_SHARING_VIOLATION && + strstr(u.detail_data.DevicePath, "1163") && + strstr(u.detail_data.DevicePath, "2020")) { + busy = " (device busy?)"; + } + } + } + SetupDiDestroyDeviceInfoList(dev_info); + if (hid_handle == INVALID_HANDLE_VALUE) { + fatal(MYNAME ": no DeLorme PN found%s\n", busy); + } + if (!HidD_GetPreparsedData(hid_handle, &hid_ppd)) { + fatal(MYNAME ": HidD_GetPreparsedData failed %u\n", GetLastError()); + } + if (!HidP_GetCaps(hid_ppd, &hid_caps)) { + fatal(MYNAME ": HidP_GetCaps failed %u\n", GetLastError()); + } + // report length includes report id + delbin_os_packet_size = hid_caps.InputReportByteLength - 1; + HidD_FreePreparsedData(hid_ppd); } static void win_os_deinit(void) { - CloseHandle(hid_handle); + CloseHandle(hid_handle); } static unsigned win_os_packet_read(void* buf) { - DWORD n; - char buf1[257]; - // first byte is report id - if (ReadFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { - unsigned err = GetLastError(); - fatal(MYNAME ": ReadFile failed %u\n", err); - } - if (n > 0) { - n--; - } - memcpy(buf, buf1 + 1, n); - return n; + DWORD n; + char buf1[257]; + // first byte is report id + if (ReadFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { + unsigned err = GetLastError(); + fatal(MYNAME ": ReadFile failed %u\n", err); + } + if (n > 0) { + n--; + } + memcpy(buf, buf1 + 1, n); + return n; } static unsigned win_os_packet_write(const void* buf, unsigned size) { - DWORD n; - char buf1[257]; - // first byte is report id - buf1[0] = 0; - memcpy(buf1 + 1, buf, size); - if (WriteFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { - unsigned err = GetLastError(); - fatal(MYNAME ": WriteFile of %u bytes failed with %u. Size: %u Wrote: %d\n", - delbin_os_packet_size + 1, err, size, (int) n); - } - if (n > size) { - n = size; - } - return n; + DWORD n; + char buf1[257]; + // first byte is report id + buf1[0] = 0; + memcpy(buf1 + 1, buf, size); + if (WriteFile(hid_handle, buf1, delbin_os_packet_size + 1, &n, NULL) == 0) { + unsigned err = GetLastError(); + fatal(MYNAME ": WriteFile of %u bytes failed with %u. Size: %u Wrote: %d\n", + delbin_os_packet_size + 1, err, size, (int) n); + } + if (n > size) { + n = size; + } + return n; } delbin_os_ops_t delbin_os_ops = { - win_os_init, - win_os_deinit, - win_os_packet_read, - win_os_packet_write + win_os_init, + win_os_deinit, + win_os_packet_read, + win_os_packet_write }; #endif // _WIN32 @@ -2445,125 +2578,132 @@ static CFRunLoopRef run_loop; static void* thread_func(void* run_loop_source) { - run_loop = CFRunLoopGetCurrent(); - CFRunLoopAddSource(run_loop, run_loop_source, kCFRunLoopDefaultMode); - CFRunLoopRun(); - return NULL; + run_loop = CFRunLoopGetCurrent(); + CFRunLoopAddSource(run_loop, run_loop_source, kCFRunLoopDefaultMode); + CFRunLoopRun(); + return NULL; } static void interrupt_report_cb(void* target, IOReturn result, void* refcon, void* sender, UInt32 bufferSize) { - memcpy(packet_array[packet_array_head], report_buf, delbin_os_packet_size); - pthread_mutex_lock(&mutex); - if (packet_array_head == packet_array_tail) { - pthread_cond_signal(&cond); - } - packet_array_head++; - packet_array_head &= sizeofarray(packet_array) - 1; - if (packet_array_head == packet_array_tail && global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": packet_array overrun, packets lost\n"); - pthread_mutex_unlock(&mutex); + memcpy(packet_array[packet_array_head], report_buf, delbin_os_packet_size); + pthread_mutex_lock(&mutex); + if (packet_array_head == packet_array_tail) { + pthread_cond_signal(&cond); + } + packet_array_head++; + packet_array_head &= sizeofarray(packet_array) - 1; + if (packet_array_head == packet_array_tail && global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": packet_array overrun, packets lost\n"); + } + pthread_mutex_unlock(&mutex); } static void mac_os_init(const char* fname) { - CFMutableDictionaryRef dict = IOServiceMatching(kIOHIDDeviceKey); - io_service_t service; - IOCFPlugInInterface** plugin; - CFNumberRef cf_num; - CFRunLoopSourceRef run_loop_source; - int i; - kern_return_t kr; - HRESULT hr; - IOReturn ir; - SInt32 unused; - - i = VENDOR_ID; - cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); - CFDictionaryAddValue(dict, CFSTR(kIOHIDVendorIDKey), cf_num); - CFRelease(cf_num); - i = PRODUCT_ID; - cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); - CFDictionaryAddValue(dict, CFSTR(kIOHIDProductIDKey), cf_num); - CFRelease(cf_num); - service = IOServiceGetMatchingService(kIOMasterPortDefault, dict); - if (service == 0) { - fatal(MYNAME ": no DeLorme PN found\n"); - } - kr = IOCreatePlugInInterfaceForService( - service, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &unused); - if (kr) - fatal(MYNAME ": IOCreatePlugInInterfaceForService failed 0x%x\n", (int)kr); - IOObjectRelease(service); - hr = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (void*)&device); - if (hr) - fatal(MYNAME ": QueryInterface failed 0x%x\n", (int)hr); - (*plugin)->Release(plugin); - ir = (*device)->open(device, kIOHIDOptionsTypeSeizeDevice); - if (ir) - fatal(MYNAME ": device open failed 0x%x - %s\n", (int)ir, - mach_error_string(ir)); - ir = (*device)->createAsyncEventSource(device, &run_loop_source); - if (ir) - fatal(MYNAME ": createAsyncEventSource failed 0x%x\n", (int)ir); - delbin_os_packet_size = 64; - report_buf = xmalloc(delbin_os_packet_size); - for (i = sizeofarray(packet_array); i--;) { - packet_array[i] = xmalloc(delbin_os_packet_size); - } - ir = (*device)->setInterruptReportHandlerCallback( - device, report_buf, delbin_os_packet_size, interrupt_report_cb, NULL, NULL); - if (ir) - fatal(MYNAME ": setInterruptReportHandlerCallback failed 0x%x\n", (int)ir); - i = pthread_create(&thread, NULL, thread_func, run_loop_source); - if (i) - fatal(MYNAME ": pthread_create failed %d\n", i); + CFMutableDictionaryRef dict = IOServiceMatching(kIOHIDDeviceKey); + io_service_t service; + IOCFPlugInInterface** plugin; + CFNumberRef cf_num; + CFRunLoopSourceRef run_loop_source; + int i; + kern_return_t kr; + HRESULT hr; + IOReturn ir; + SInt32 unused; + + i = VENDOR_ID; + cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); + CFDictionaryAddValue(dict, CFSTR(kIOHIDVendorIDKey), cf_num); + CFRelease(cf_num); + i = PRODUCT_ID; + cf_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i); + CFDictionaryAddValue(dict, CFSTR(kIOHIDProductIDKey), cf_num); + CFRelease(cf_num); + service = IOServiceGetMatchingService(kIOMasterPortDefault, dict); + if (service == 0) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + kr = IOCreatePlugInInterfaceForService( + service, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &unused); + if (kr) { + fatal(MYNAME ": IOCreatePlugInInterfaceForService failed 0x%x\n", (int)kr); + } + IOObjectRelease(service); + hr = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID122), (void*)&device); + if (hr) { + fatal(MYNAME ": QueryInterface failed 0x%x\n", (int)hr); + } + (*plugin)->Release(plugin); + ir = (*device)->open(device, kIOHIDOptionsTypeSeizeDevice); + if (ir) + fatal(MYNAME ": device open failed 0x%x - %s\n", (int)ir, + mach_error_string(ir)); + ir = (*device)->createAsyncEventSource(device, &run_loop_source); + if (ir) { + fatal(MYNAME ": createAsyncEventSource failed 0x%x\n", (int)ir); + } + delbin_os_packet_size = 64; + report_buf = xmalloc(delbin_os_packet_size); + for (i = sizeofarray(packet_array); i--;) { + packet_array[i] = xmalloc(delbin_os_packet_size); + } + ir = (*device)->setInterruptReportHandlerCallback( + device, report_buf, delbin_os_packet_size, interrupt_report_cb, NULL, NULL); + if (ir) { + fatal(MYNAME ": setInterruptReportHandlerCallback failed 0x%x\n", (int)ir); + } + i = pthread_create(&thread, NULL, thread_func, run_loop_source); + if (i) { + fatal(MYNAME ": pthread_create failed %d\n", i); + } } static void mac_os_deinit(void) { - void* unused; - unsigned i; - CFRunLoopStop(run_loop); - pthread_join(thread, &unused); - (*device)->Release(device); - xfree(report_buf); - for (i = sizeofarray(packet_array); i--;) { - xfree(packet_array[i]); - } + void* unused; + unsigned i; + CFRunLoopStop(run_loop); + pthread_join(thread, &unused); + (*device)->Release(device); + xfree(report_buf); + for (i = sizeofarray(packet_array); i--;) { + xfree(packet_array[i]); + } } static unsigned mac_os_packet_read(void* buf) { - pthread_mutex_lock(&mutex); - while (packet_array_head == packet_array_tail) { - pthread_cond_wait(&cond, &mutex); - } - memcpy(buf, packet_array[packet_array_tail++], delbin_os_packet_size); - packet_array_tail &= sizeofarray(packet_array) - 1; - pthread_mutex_unlock(&mutex); - return delbin_os_packet_size; + pthread_mutex_lock(&mutex); + while (packet_array_head == packet_array_tail) { + pthread_cond_wait(&cond, &mutex); + } + memcpy(buf, packet_array[packet_array_tail++], delbin_os_packet_size); + packet_array_tail &= sizeofarray(packet_array) - 1; + pthread_mutex_unlock(&mutex); + return delbin_os_packet_size; } static unsigned mac_os_packet_write(const void* buf, unsigned size) { - IOReturn r = (*device)->setReport( - device, kIOHIDReportTypeOutput, 0, (void*)buf, size, 2000, NULL, NULL, NULL); - if (r) - fatal("setReport failed 0x%x\n", (int)r); - return size; + IOReturn r = (*device)->setReport( + device, kIOHIDReportTypeOutput, 0, (void*)buf, size, 2000, NULL, NULL, NULL); + if (r) { + fatal("setReport failed 0x%x\n", (int)r); + } + return size; } delbin_os_ops_t delbin_os_ops = { - mac_os_init, - mac_os_deinit, - mac_os_packet_read, - mac_os_packet_write + mac_os_init, + mac_os_deinit, + mac_os_packet_read, + mac_os_packet_write }; #endif // __APPLE__ @@ -2582,79 +2722,79 @@ static int endpoint_out; static void libusb_os_init(const char* fname) { - struct usb_bus* bus; - const struct usb_endpoint_descriptor* endpoint_desc; - - usb_init(); - usb_find_busses(); - usb_find_devices(); - for (bus = usb_busses; usb_dev == NULL && bus; bus = bus->next) { - struct usb_device* d; - for (d = bus->devices; d; d = d->next) { - if (d->descriptor.idVendor == VENDOR_ID && d->descriptor.idProduct == PRODUCT_ID) { - usb_dev = d; - break; - } - } - } - if (usb_dev == NULL) { - fatal(MYNAME ": no DeLorme PN found\n"); - } - usb_handle = usb_open(usb_dev); - if (usb_handle == NULL) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - - // Device has 1 configuration, 1 interface, 2 interrupt endpoints - if (usb_claim_interface(usb_handle, 0) < 0) { + struct usb_bus* bus; + const struct usb_endpoint_descriptor* endpoint_desc; + + usb_init(); + usb_find_busses(); + usb_find_devices(); + for (bus = usb_busses; usb_dev == NULL && bus; bus = bus->next) { + struct usb_device* d; + for (d = bus->devices; d; d = d->next) { + if (d->descriptor.idVendor == VENDOR_ID && d->descriptor.idProduct == PRODUCT_ID) { + usb_dev = d; + break; + } + } + } + if (usb_dev == NULL) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + usb_handle = usb_open(usb_dev); + if (usb_handle == NULL) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + + // Device has 1 configuration, 1 interface, 2 interrupt endpoints + if (usb_claim_interface(usb_handle, 0) < 0) { #if LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP - if (usb_detach_kernel_driver_np(usb_handle, 0) < 0) { - warning(MYNAME ": %s\n", usb_strerror()); - } - if (usb_claim_interface(usb_handle, 0) < 0) + if (usb_detach_kernel_driver_np(usb_handle, 0) < 0) { + warning(MYNAME ": %s\n", usb_strerror()); + } + if (usb_claim_interface(usb_handle, 0) < 0) #endif - { - const char* s = usb_strerror(); - usb_close(usb_handle); - fatal(MYNAME ": %s\n", s); - } - } - endpoint_desc = usb_dev->config[0].interface[0].altsetting[0].endpoint; - delbin_os_packet_size = endpoint_desc[0].wMaxPacketSize; - endpoint_in = endpoint_desc[0].bEndpointAddress; - endpoint_out = endpoint_desc[1].bEndpointAddress; - if ((endpoint_in & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT) { - int t = endpoint_in; - endpoint_in = endpoint_out; - endpoint_out = t; - } + { + const char* s = usb_strerror(); + usb_close(usb_handle); + fatal(MYNAME ": %s\n", s); + } + } + endpoint_desc = usb_dev->config[0].interface[0].altsetting[0].endpoint; + delbin_os_packet_size = endpoint_desc[0].wMaxPacketSize; + endpoint_in = endpoint_desc[0].bEndpointAddress; + endpoint_out = endpoint_desc[1].bEndpointAddress; + if ((endpoint_in & USB_ENDPOINT_DIR_MASK) == USB_ENDPOINT_OUT) { + int t = endpoint_in; + endpoint_in = endpoint_out; + endpoint_out = t; + } } static void libusb_os_deinit(void) { - usb_release_interface(usb_handle, 0); - usb_close(usb_handle); + usb_release_interface(usb_handle, 0); + usb_close(usb_handle); } static unsigned libusb_os_packet_read(void* buf) { - int n = usb_interrupt_read(usb_handle, endpoint_in, buf, delbin_os_packet_size, 2000); - if (n < 0) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - return n; + int n = usb_interrupt_read(usb_handle, endpoint_in, buf, delbin_os_packet_size, 2000); + if (n < 0) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + return n; } static unsigned libusb_os_packet_write(const void* buf, unsigned size) { - int n = usb_interrupt_write(usb_handle, endpoint_out, (char*)buf, size, 2000); - if (n < 0) { - fatal(MYNAME ": %s\n", usb_strerror()); - } - return n; + int n = usb_interrupt_write(usb_handle, endpoint_out, (char*)buf, size, 2000); + if (n < 0) { + fatal(MYNAME ": %s\n", usb_strerror()); + } + return n; } #if HAVE_LINUX_HID @@ -2663,10 +2803,10 @@ static const delbin_os_ops_t libusb_os_ops = delbin_os_ops_t delbin_os_ops = #endif { - libusb_os_init, - libusb_os_deinit, - libusb_os_packet_read, - libusb_os_packet_write + libusb_os_init, + libusb_os_deinit, + libusb_os_packet_read, + libusb_os_packet_write }; #endif // HAVE_LIBUSB @@ -2694,161 +2834,165 @@ static int linuxhid_os_init_status; static void linuxhid_os_init(const char* fname) { - struct hidraw_devinfo info; - struct hiddev_field_info finfo; - DIR* dir = NULL; - struct dirent* d; - - fd_hidraw = fd_hiddev = -1; - if (fname && memcmp(fname, "hid:", 4) == 0) { - char* raw_name = xstrdup(fname + 4); - char* dev_name = strchr(raw_name, ','); - if (dev_name == NULL) { - fatal(MYNAME ": missing hiddev path\n"); - } - *dev_name++ = 0; - fd_hidraw = open(raw_name, O_RDONLY); - if (fd_hidraw < 0) { - fatal(MYNAME ": %s: %s\n", raw_name, strerror(errno)); - } - fd_hiddev = open(dev_name, O_WRONLY); - if (fd_hiddev < 0) { - fatal(MYNAME ": %s: %s\n", dev_name, strerror(errno)); - } - xfree(raw_name); - } else { - dir = opendir("/dev"); - } - while (dir && (d = readdir(dir)) != NULL) { - if (strncmp(d->d_name, "hidraw", 6) == 0) { - int fd1, fd2; - char raw_name[32]; - char dev_name[32]; - sprintf(raw_name, "/dev/%s", d->d_name); - fd1 = open(raw_name, O_RDONLY); - if (fd1 < 0) { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": %s: %s\n", raw_name, strerror(errno)); - continue; - } - sprintf(dev_name, "/dev/usb/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); - fd2 = open(dev_name, O_WRONLY); - if (fd2 < 0 && errno == ENOENT) { - sprintf(dev_name, "/dev/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); - fd2 = open(dev_name, O_WRONLY); - } - if (fd2 < 0) { - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": %s: %s\n", dev_name, strerror(errno)); - close(fd1); - continue; - } - if (ioctl(fd1, HIDIOCGRAWINFO, &info) == 0 && - info.vendor == VENDOR_ID && info.product == PRODUCT_ID) - { - fd_hidraw = fd1; - fd_hiddev = fd2; - break; - } - close(fd1); - close(fd2); - } - } - if (dir) { - closedir(dir); - } - if (fd_hidraw < 0) { - if (linuxhid_os_init_status == 0) - fatal(MYNAME ": no DeLorme PN found\n"); - return; - } - finfo.report_type = HID_REPORT_TYPE_INPUT; - finfo.report_id = 0; - finfo.field_index = 0; - if (ioctl(fd_hiddev, HIDIOCGFIELDINFO, &finfo) < 0) { - warning(MYNAME ": HIDIOCGFIELDINFO: %s\n", strerror(errno)); - if (linuxhid_os_init_status == 0) - exit(1); - return; - } - delbin_os_packet_size = finfo.maxusage; - linuxhid_os_init_status = 0; + struct hidraw_devinfo info; + struct hiddev_field_info finfo; + DIR* dir = NULL; + struct dirent* d; + + fd_hidraw = fd_hiddev = -1; + if (fname && memcmp(fname, "hid:", 4) == 0) { + char* raw_name = xstrdup(fname + 4); + char* dev_name = strchr(raw_name, ','); + if (dev_name == NULL) { + fatal(MYNAME ": missing hiddev path\n"); + } + *dev_name++ = 0; + fd_hidraw = open(raw_name, O_RDONLY); + if (fd_hidraw < 0) { + fatal(MYNAME ": %s: %s\n", raw_name, strerror(errno)); + } + fd_hiddev = open(dev_name, O_WRONLY); + if (fd_hiddev < 0) { + fatal(MYNAME ": %s: %s\n", dev_name, strerror(errno)); + } + xfree(raw_name); + } else { + dir = opendir("/dev"); + } + while (dir && (d = readdir(dir)) != NULL) { + if (strncmp(d->d_name, "hidraw", 6) == 0) { + int fd1, fd2; + char raw_name[32]; + char dev_name[32]; + sprintf(raw_name, "/dev/%s", d->d_name); + fd1 = open(raw_name, O_RDONLY); + if (fd1 < 0) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": %s: %s\n", raw_name, strerror(errno)); + } + continue; + } + sprintf(dev_name, "/dev/usb/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); + fd2 = open(dev_name, O_WRONLY); + if (fd2 < 0 && errno == ENOENT) { + sprintf(dev_name, "/dev/hiddev%s", raw_name + sizeof("/dev/hidraw") - 1); + fd2 = open(dev_name, O_WRONLY); + } + if (fd2 < 0) { + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": %s: %s\n", dev_name, strerror(errno)); + } + close(fd1); + continue; + } + if (ioctl(fd1, HIDIOCGRAWINFO, &info) == 0 && + info.vendor == VENDOR_ID && info.product == PRODUCT_ID) { + fd_hidraw = fd1; + fd_hiddev = fd2; + break; + } + close(fd1); + close(fd2); + } + } + if (dir) { + closedir(dir); + } + if (fd_hidraw < 0) { + if (linuxhid_os_init_status == 0) { + fatal(MYNAME ": no DeLorme PN found\n"); + } + return; + } + finfo.report_type = HID_REPORT_TYPE_INPUT; + finfo.report_id = 0; + finfo.field_index = 0; + if (ioctl(fd_hiddev, HIDIOCGFIELDINFO, &finfo) < 0) { + warning(MYNAME ": HIDIOCGFIELDINFO: %s\n", strerror(errno)); + if (linuxhid_os_init_status == 0) { + exit(1); + } + return; + } + delbin_os_packet_size = finfo.maxusage; + linuxhid_os_init_status = 0; } static void linuxhid_os_deinit(void) { - close(fd_hidraw); - close(fd_hiddev); + close(fd_hidraw); + close(fd_hiddev); } static unsigned linuxhid_os_packet_read(void* buf) { - int n = read(fd_hidraw, buf, delbin_os_packet_size); - if (n < 0) { - fatal(MYNAME ": %s\n", strerror(errno)); - } - return n; + int n = read(fd_hidraw, buf, delbin_os_packet_size); + if (n < 0) { + fatal(MYNAME ": %s\n", strerror(errno)); + } + return n; } static unsigned linuxhid_os_packet_write(const void* buf, unsigned size) { - struct hiddev_usage_ref_multi urefm; - struct hiddev_report_info rinfo; - const gbuint8* p = buf; - unsigned i; - - for (i = 0; i < size; i++) { - urefm.values[i] = p[i]; - } - urefm.num_values = size; - memset(&urefm.uref, 0, sizeof(urefm.uref)); - urefm.uref.report_type = HID_REPORT_TYPE_OUTPUT; - if (ioctl(fd_hiddev, HIDIOCSUSAGES, &urefm)) { - fatal(MYNAME ": HIDIOCSUSAGES: %s\n", strerror(errno)); - } - memset(&rinfo, 0, sizeof(rinfo)); - rinfo.report_type = HID_REPORT_TYPE_OUTPUT; - if (ioctl(fd_hiddev, HIDIOCSREPORT, &rinfo)) { - fatal(MYNAME ": HIDIOCSREPORT: %s\n", strerror(errno)); - } - return size; + struct hiddev_usage_ref_multi urefm; + struct hiddev_report_info rinfo; + const gbuint8* p = buf; + unsigned i; + + for (i = 0; i < size; i++) { + urefm.values[i] = p[i]; + } + urefm.num_values = size; + memset(&urefm.uref, 0, sizeof(urefm.uref)); + urefm.uref.report_type = HID_REPORT_TYPE_OUTPUT; + if (ioctl(fd_hiddev, HIDIOCSUSAGES, &urefm)) { + fatal(MYNAME ": HIDIOCSUSAGES: %s\n", strerror(errno)); + } + memset(&rinfo, 0, sizeof(rinfo)); + rinfo.report_type = HID_REPORT_TYPE_OUTPUT; + if (ioctl(fd_hiddev, HIDIOCSREPORT, &rinfo)) { + fatal(MYNAME ": HIDIOCSREPORT: %s\n", strerror(errno)); + } + return size; } static const delbin_os_ops_t linuxhid_os_ops = { - linuxhid_os_init, - linuxhid_os_deinit, - linuxhid_os_packet_read, - linuxhid_os_packet_write + linuxhid_os_init, + linuxhid_os_deinit, + linuxhid_os_packet_read, + linuxhid_os_packet_write }; static void linux_os_init(const char* fname) { - // tell linuxhid_os_init not to exit - linuxhid_os_init_status = 1; - linuxhid_os_init(fname); - if (linuxhid_os_init_status == 0) { - delbin_os_ops = linuxhid_os_ops; - } else { + // tell linuxhid_os_init not to exit + linuxhid_os_init_status = 1; + linuxhid_os_init(fname); + if (linuxhid_os_init_status == 0) { + delbin_os_ops = linuxhid_os_ops; + } else { #if HAVE_LIBUSB - if (global_opts.debug_level >= DBGLVL_M) - warning(MYNAME ": HID init failed, falling back to libusb\n"); - delbin_os_ops = libusb_os_ops; - delbin_os_ops.init(fname); + if (global_opts.debug_level >= DBGLVL_M) { + warning(MYNAME ": HID init failed, falling back to libusb\n"); + } + delbin_os_ops = libusb_os_ops; + delbin_os_ops.init(fname); #else - fatal(MYNAME ": no DeLorme PN found\n"); + fatal(MYNAME ": no DeLorme PN found\n"); #endif - } + } } delbin_os_ops_t delbin_os_ops = { - linux_os_init, - NULL, - NULL, - NULL + linux_os_init, + NULL, + NULL, + NULL }; #endif // HAVE_LINUX_HID @@ -2859,7 +3003,7 @@ delbin_os_ops_t delbin_os_ops = { static void stub_os_init(const char* fname) { - fatal(MYNAME ": OS not supported\n"); + fatal(MYNAME ": OS not supported\n"); } static void stub_os_deinit(void) @@ -2868,333 +3012,333 @@ stub_os_deinit(void) static unsigned stub_os_packet_read(void* buf) { - return 0; + return 0; } static unsigned stub_os_packet_write(const void* buf, unsigned size) { - return 0; + return 0; } delbin_os_ops_t delbin_os_ops = { - stub_os_init, - stub_os_deinit, - stub_os_packet_read, - stub_os_packet_write + stub_os_init, + stub_os_deinit, + stub_os_packet_read, + stub_os_packet_write }; #endif // end OS device I/O implementations section //============================================================================= static const int track_color_bgr[] = { - 0x0000ff, // red - 0x00ffff, // yellow - 0x008000, // green - 0xff0000, // blue - 0x808080, // gray - 0xffffff, // white - 0, // black - 0xffff00, // cyan - 0xff00ff, // magenta - 0x00a5ff, // orange - 0x82004b, // indigo - 0xeea5ee // violet + 0x0000ff, // red + 0x00ffff, // yellow + 0x008000, // green + 0xff0000, // blue + 0x808080, // gray + 0xffffff, // white + 0, // black + 0xffff00, // cyan + 0xff00ff, // magenta + 0x00a5ff, // orange + 0x82004b, // indigo + 0xeea5ee // violet }; static int track_color(unsigned i) { - int bgr = -1; - if (i < sizeofarray(track_color_bgr)) { - bgr = track_color_bgr[i]; - } - return bgr; + int bgr = -1; + if (i < sizeofarray(track_color_bgr)) { + bgr = track_color_bgr[i]; + } + return bgr; } static unsigned track_color_index(int bgr) { - unsigned i = sizeofarray(track_color_bgr); - do { - i--; - } while (i != 0 && track_color_bgr[i] != bgr); - return i; + unsigned i = sizeofarray(track_color_bgr); + do { + i--; + } while (i != 0 && track_color_bgr[i] != bgr); + return i; } static const char* const waypoint_symbol_name[] = { - // 0 - "Red Map Pin", - "Dark Red Map Pin", - "Yellow Map Pin", - "Dark Yellow Map Pin", - "Green Map Pin", - "Dark Green Map Pin", - "Turquoise Map Pin", - "Dark Turquoise Map Pin", - "Blue Map Pin", - "Dark Blue Map Pin", - // 10 - "Gray Map Pin", - "Dark Gray Map Pin", - "Red Flag", - "Dark Red Flag", - "Yellow Flag", - "Dark Yellow Flag", - "Green Flag", - "Dark Green Flag", - "Turquoise Flag", - "Dark Turquoise Flag", - // 20 - "Blue Flag", - "Dark Blue Flag", - "Gray Flag", - "Dark Gray Flag", - "Red Dot", - "Dark Red Dot", - "Yellow Dot", - "Dark Yellow Dot", - "Green Dot", - "Dark Green Dot", - // 30 - "Turquoise Dot", - "Dark Turquoise Dot", - "Blue Dot", - "Dark Blue Dot", - "Gray Dot", - "Dark Gray Dot", - "Small Red Dot", - "Small Dark Red Dot", - "Small Yellow Dot", - "Small Dark Yellow Dot", - // 40 - "Small Green Dot", - "Small Dark Green Dot", - "Small Turquoise Dot", - "Small Dark Turquoise Dot", - "Small Blue Dot", - "Small Dark Blue Dot", - "Small Gray Dot", - "Small Dark Gray Dot", - "Arrow Up", - "Arrow Down", - // 50 - "Arrow Left", - "Arrow Right", - "Arrow Up Left", - "Arrow Up Right", - "Arrow Down Left", - "Arrow Down Right", - "Green Star", - "Yellow Square", - "Red X", - "Turquoise Circle", - // 60 - "Purple Triangle", - "American Flag", - "Stop", - "Parking", - "First Aid", - "Dining", - "Railroad Crossing", - "Heliport", - "Restroom", - "Information", - // 70 - "Diver Down", - "Exit", - "Health Facility", - "Police", - "Post Office", - "Mining", - "Danger", - "Money", - "Exclamation", - "Car", - // 80 - "Jeep", - "Truck", - "Tow Truck", - "Motor Home", - "School Bus", - "Four-wheeler", - "Snowmobile", - "Sailboat", - "Powerboat", - "Boat Launch", - // 90 - "Anchor", - "Buoy", - "Shipwreck", - "Glider Area", - "Private Airport", - "Public Airport", - "Military Airport", - "Military Base", - "House", - "Church", - // 100 - "Building", - "School", - "Lighthouse", - "Bridge", - "Radio Tower", - "Dam", - "Tunnel", - "Toll Booth", - "Gas Station", - "Lodging", - // 110 - "Telephone", - "Traffic Light", - "Fire Hydrant", - "Cemetery", - "Picnic Table", - "Tent", - "Shelter", - "Camper", - "Fire", - "Shower", - // 120 - "Drinking Water", - "Binoculars", - "Camera", - "Geocache", - "Geocache Found", - "Fishing Pole", - "Ice Fishing Trap Set", - "Ice Fishing Trap Up", - "Moose", - "Deer", - // 130 - "Bear", - "Bird", - "Duck", - "Fish", - "Deer Tracks", - "Animal Tracks", - "Bird Tracks", - "Birch Tree", - "Evergreen Tree", - "Deciduous Tree", - // 140 - "Flower Garden", - "Mountain", - "Cave", - "Beach", - "Hiking", - "Swimming", - "Bicycling", - "Kayaking", - "Canoeing", - "Water Skiing", - // 150 - "Cross-country Skiing", - "Downhill Skiing", - "Ice Skating", - "Dogsledding", - "Shooting", - "Golf Course", - "Ballpark", - // 157-182 added in PN-40 2.5 firmware - "Cache Found", - "Didn't Find It", - "My Cache", - // 160 - "Traditional Cache", - "Multi-Cache", - "Unknown Cache", - "Letterbox Hybrid", - "Whereigo Cache", - "Event Cache", - "Mega-Event Cache", - "Cache In Trash Out Event", - "EarthCache", - "Virtual Cache", - // 170 - "Webcam Cache", - "Waymark", - "NGS Benchmark", - "Write Note", - "Needs Maintenance", - "Final Location", - "Parking Area", - "Question to Answer", - "Reference Point", - "Stages of a Multicache", - // 180 - "Trailhead", - "Temporarily Disable Listing", - "Enable Listing", - // 183-222 added in PN-40 2.7 firmware - "Crane Truck", - "Forest Fire", - "Oil Derrick", - "Wind Turbine", - "Letter A", - "Letter B", - "Letter C", - // 190 - "Letter D", - "Letter E", - "Letter F", - "Letter G", - "Letter H", - "Letter I", - "Letter J", - "Letter K", - "Letter L", - "Letter M", - // 200 - "Letter N", - "Letter O", - "Letter P", - "Letter Q", - "Letter R", - "Letter S", - "Letter T", - "Letter U", - "Letter V", - "Letter W", - // 210 - "Letter X", - "Letter Y", - "Letter Z", - "Numeral 0", - "Numeral 1", - "Numeral 2", - "Numeral 3", - "Numeral 4", - "Numeral 5", - "Numeral 6", - // 220 - "Numeral 7", - "Numeral 8", - "Numeral 9" + // 0 + "Red Map Pin", + "Dark Red Map Pin", + "Yellow Map Pin", + "Dark Yellow Map Pin", + "Green Map Pin", + "Dark Green Map Pin", + "Turquoise Map Pin", + "Dark Turquoise Map Pin", + "Blue Map Pin", + "Dark Blue Map Pin", + // 10 + "Gray Map Pin", + "Dark Gray Map Pin", + "Red Flag", + "Dark Red Flag", + "Yellow Flag", + "Dark Yellow Flag", + "Green Flag", + "Dark Green Flag", + "Turquoise Flag", + "Dark Turquoise Flag", + // 20 + "Blue Flag", + "Dark Blue Flag", + "Gray Flag", + "Dark Gray Flag", + "Red Dot", + "Dark Red Dot", + "Yellow Dot", + "Dark Yellow Dot", + "Green Dot", + "Dark Green Dot", + // 30 + "Turquoise Dot", + "Dark Turquoise Dot", + "Blue Dot", + "Dark Blue Dot", + "Gray Dot", + "Dark Gray Dot", + "Small Red Dot", + "Small Dark Red Dot", + "Small Yellow Dot", + "Small Dark Yellow Dot", + // 40 + "Small Green Dot", + "Small Dark Green Dot", + "Small Turquoise Dot", + "Small Dark Turquoise Dot", + "Small Blue Dot", + "Small Dark Blue Dot", + "Small Gray Dot", + "Small Dark Gray Dot", + "Arrow Up", + "Arrow Down", + // 50 + "Arrow Left", + "Arrow Right", + "Arrow Up Left", + "Arrow Up Right", + "Arrow Down Left", + "Arrow Down Right", + "Green Star", + "Yellow Square", + "Red X", + "Turquoise Circle", + // 60 + "Purple Triangle", + "American Flag", + "Stop", + "Parking", + "First Aid", + "Dining", + "Railroad Crossing", + "Heliport", + "Restroom", + "Information", + // 70 + "Diver Down", + "Exit", + "Health Facility", + "Police", + "Post Office", + "Mining", + "Danger", + "Money", + "Exclamation", + "Car", + // 80 + "Jeep", + "Truck", + "Tow Truck", + "Motor Home", + "School Bus", + "Four-wheeler", + "Snowmobile", + "Sailboat", + "Powerboat", + "Boat Launch", + // 90 + "Anchor", + "Buoy", + "Shipwreck", + "Glider Area", + "Private Airport", + "Public Airport", + "Military Airport", + "Military Base", + "House", + "Church", + // 100 + "Building", + "School", + "Lighthouse", + "Bridge", + "Radio Tower", + "Dam", + "Tunnel", + "Toll Booth", + "Gas Station", + "Lodging", + // 110 + "Telephone", + "Traffic Light", + "Fire Hydrant", + "Cemetery", + "Picnic Table", + "Tent", + "Shelter", + "Camper", + "Fire", + "Shower", + // 120 + "Drinking Water", + "Binoculars", + "Camera", + "Geocache", + "Geocache Found", + "Fishing Pole", + "Ice Fishing Trap Set", + "Ice Fishing Trap Up", + "Moose", + "Deer", + // 130 + "Bear", + "Bird", + "Duck", + "Fish", + "Deer Tracks", + "Animal Tracks", + "Bird Tracks", + "Birch Tree", + "Evergreen Tree", + "Deciduous Tree", + // 140 + "Flower Garden", + "Mountain", + "Cave", + "Beach", + "Hiking", + "Swimming", + "Bicycling", + "Kayaking", + "Canoeing", + "Water Skiing", + // 150 + "Cross-country Skiing", + "Downhill Skiing", + "Ice Skating", + "Dogsledding", + "Shooting", + "Golf Course", + "Ballpark", + // 157-182 added in PN-40 2.5 firmware + "Cache Found", + "Didn't Find It", + "My Cache", + // 160 + "Traditional Cache", + "Multi-Cache", + "Unknown Cache", + "Letterbox Hybrid", + "Whereigo Cache", + "Event Cache", + "Mega-Event Cache", + "Cache In Trash Out Event", + "EarthCache", + "Virtual Cache", + // 170 + "Webcam Cache", + "Waymark", + "NGS Benchmark", + "Write Note", + "Needs Maintenance", + "Final Location", + "Parking Area", + "Question to Answer", + "Reference Point", + "Stages of a Multicache", + // 180 + "Trailhead", + "Temporarily Disable Listing", + "Enable Listing", + // 183-222 added in PN-40 2.7 firmware + "Crane Truck", + "Forest Fire", + "Oil Derrick", + "Wind Turbine", + "Letter A", + "Letter B", + "Letter C", + // 190 + "Letter D", + "Letter E", + "Letter F", + "Letter G", + "Letter H", + "Letter I", + "Letter J", + "Letter K", + "Letter L", + "Letter M", + // 200 + "Letter N", + "Letter O", + "Letter P", + "Letter Q", + "Letter R", + "Letter S", + "Letter T", + "Letter U", + "Letter V", + "Letter W", + // 210 + "Letter X", + "Letter Y", + "Letter Z", + "Numeral 0", + "Numeral 1", + "Numeral 2", + "Numeral 3", + "Numeral 4", + "Numeral 5", + "Numeral 6", + // 220 + "Numeral 7", + "Numeral 8", + "Numeral 9" }; static const char* waypoint_symbol(unsigned i) { - const char* p = NULL; - if (i < sizeofarray(waypoint_symbol_name)) { - p = waypoint_symbol_name[i]; - } - return p; + const char* p = NULL; + if (i < sizeofarray(waypoint_symbol_name)) { + p = waypoint_symbol_name[i]; + } + return p; } static unsigned waypoint_symbol_index(const char* name) { - static unsigned last_result; - static char last_name[32]; - unsigned i = last_result; - - if (strncmp(name, last_name, sizeof(last_name)) != 0) { - i = sizeofarray(waypoint_symbol_name); - do { - i--; - } while (i != 0 && case_ignore_strcmp(name, waypoint_symbol_name[i]) != 0); - strncpy(last_name, name, sizeof(last_name)); - last_result = i; - } - return i; + static unsigned last_result; + static char last_name[32]; + unsigned i = last_result; + + if (strncmp(name, last_name, sizeof(last_name)) != 0) { + i = sizeofarray(waypoint_symbol_name); + do { + i--; + } while (i != 0 && case_ignore_strcmp(name, waypoint_symbol_name[i]) != 0); + strncpy(last_name, name, sizeof(last_name)); + last_result = i; + } + return i; } // vi: ts=4 sw=4 noexpandtab diff --git a/gpsbabel/delgpl.c b/gpsbabel/delgpl.c index a30b7d5b6..3a6991769 100644 --- a/gpsbabel/delgpl.c +++ b/gpsbabel/delgpl.c @@ -27,15 +27,15 @@ #define MYNAME "GPL" typedef struct gpl_point { - unsigned int status; - unsigned int dummy1; - double lat; - double lon; - double alt; /* in feet */ - double heading; - double speed; /* mph */ - unsigned int tm; - unsigned int dummy3; + unsigned int status; + unsigned int dummy1; + double lat; + double lon; + double alt; /* in feet */ + double heading; + double speed; /* mph */ + unsigned int tm; + unsigned int dummy3; } gpl_point_t; static gbfile *gplfile_in; @@ -44,118 +44,136 @@ static gbfile *gplfile_out; static void gpl_rd_init(const char *fname) { - gplfile_in = gbfopen_le(fname, "rb", MYNAME); - if (sizeof(struct gpl_point) != 56) { - fatal(MYNAME ": gpl_point is %lu instead of 56.\n", - (unsigned long) sizeof(struct gpl_point)); - } + gplfile_in = gbfopen_le(fname, "rb", MYNAME); + if (sizeof(struct gpl_point) != 56) { + fatal(MYNAME ": gpl_point is %lu instead of 56.\n", + (unsigned long) sizeof(struct gpl_point)); + } } static void gpl_read(void) { - waypoint *wpt_tmp; - route_head *track_head; - gpl_point_t gp; - double alt_feet; - - track_head = route_head_alloc(); - track_add_head(track_head); - - while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = le_read_double(&gp.lat); - wpt_tmp->longitude = le_read_double(&gp.lon); - alt_feet = le_read_double(&gp.alt); - wpt_tmp->altitude = FEET_TO_METERS(alt_feet); - if (wpt_tmp->altitude <= unknown_alt + 1) - wpt_tmp->altitude = unknown_alt; - wpt_tmp->creation_time = le_read32(&gp.tm); - - switch (le_read32(&gp.status)) { - case 1: wpt_tmp->fix = fix_none; break; - case 2: wpt_tmp->fix = fix_2d; break; - case 3: wpt_tmp->fix = fix_3d; break; - case 5: wpt_tmp->fix = fix_dgps; break; - } - - WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading)); - WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed)); - WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600); - // 2008 and 2009 seem to throw track points in that go back - // in time. The only thing I see "special" about those - // trackpoints is that these fields are zeroed. Toss them. - if ((wpt_tmp->speed == 0.0) && (wpt_tmp->course == 0.0)) { - continue; - } - track_add_wpt(track_head, wpt_tmp); - } + waypoint *wpt_tmp; + route_head *track_head; + gpl_point_t gp; + double alt_feet; + + track_head = route_head_alloc(); + track_add_head(track_head); + + while (gbfread(&gp, sizeof(gp), 1, gplfile_in) > 0) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = le_read_double(&gp.lat); + wpt_tmp->longitude = le_read_double(&gp.lon); + alt_feet = le_read_double(&gp.alt); + wpt_tmp->altitude = FEET_TO_METERS(alt_feet); + if (wpt_tmp->altitude <= unknown_alt + 1) { + wpt_tmp->altitude = unknown_alt; + } + wpt_tmp->creation_time = le_read32(&gp.tm); + + switch (le_read32(&gp.status)) { + case 1: + wpt_tmp->fix = fix_none; + break; + case 2: + wpt_tmp->fix = fix_2d; + break; + case 3: + wpt_tmp->fix = fix_3d; + break; + case 5: + wpt_tmp->fix = fix_dgps; + break; + } + + WAYPT_SET(wpt_tmp, course, le_read_double(&gp.heading)); + WAYPT_SET(wpt_tmp, speed, le_read_double(&gp.speed)); + WAYPT_SET(wpt_tmp, speed, MILES_TO_METERS(wpt_tmp->speed)/3600); + // 2008 and 2009 seem to throw track points in that go back + // in time. The only thing I see "special" about those + // trackpoints is that these fields are zeroed. Toss them. + if ((wpt_tmp->speed == 0.0) && (wpt_tmp->course == 0.0)) { + continue; + } + track_add_wpt(track_head, wpt_tmp); + } } static void gpl_rd_deinit(void) { - gbfclose(gplfile_in); + gbfclose(gplfile_in); } static void gpl_wr_init(const char *fname) { - gplfile_out = gbfopen_le(fname, "wb", MYNAME); + gplfile_out = gbfopen_le(fname, "wb", MYNAME); } static void gpl_wr_deinit(void) { - gbfclose(gplfile_out); + gbfclose(gplfile_out); } static void gpl_trackpt(const waypoint *wpt) { - double alt_feet = METERS_TO_FEET(wpt->altitude); - int status = 3; - gpl_point_t gp; - double speed = 3600*METERS_TO_MILES(wpt->speed); - double heading = wpt->course; - - switch(wpt->fix) { - case fix_none: status = 1; break; - case fix_2d: status = 2; break; - case fix_3d: status = 3; break; - case fix_dgps: status = 5; break; - default: status = 3; // a strategic lie for fix_unknown. - } - - memset(&gp, 0, sizeof(gp)); - le_write32(&gp.status, status); - le_write_double(&gp.lat, wpt->latitude); - le_write_double(&gp.lon, wpt->longitude); - le_write_double(&gp.alt, alt_feet ); - le_write_double(&gp.speed, speed ); - le_write_double(&gp.heading, heading ); - le_write32(&gp.tm, wpt->creation_time); - - gbfwrite(&gp, sizeof(gp), 1, gplfile_out); + double alt_feet = METERS_TO_FEET(wpt->altitude); + int status = 3; + gpl_point_t gp; + double speed = 3600*METERS_TO_MILES(wpt->speed); + double heading = wpt->course; + + switch (wpt->fix) { + case fix_none: + status = 1; + break; + case fix_2d: + status = 2; + break; + case fix_3d: + status = 3; + break; + case fix_dgps: + status = 5; + break; + default: + status = 3; // a strategic lie for fix_unknown. + } + + memset(&gp, 0, sizeof(gp)); + le_write32(&gp.status, status); + le_write_double(&gp.lat, wpt->latitude); + le_write_double(&gp.lon, wpt->longitude); + le_write_double(&gp.alt, alt_feet); + le_write_double(&gp.speed, speed); + le_write_double(&gp.heading, heading); + le_write32(&gp.tm, wpt->creation_time); + + gbfwrite(&gp, sizeof(gp), 1, gplfile_out); } static void gpl_write(void) { - track_disp_all(NULL, NULL, gpl_trackpt); + track_disp_all(NULL, NULL, gpl_trackpt); } ff_vecs_t gpl_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - gpl_rd_init, - gpl_wr_init, - gpl_rd_deinit, - gpl_wr_deinit, - gpl_read, - gpl_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + gpl_rd_init, + gpl_wr_init, + gpl_rd_deinit, + gpl_wr_deinit, + gpl_read, + gpl_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* there is no need to convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/destinator.c b/gpsbabel/destinator.c index 108955001..1f0e5b97a 100644 --- a/gpsbabel/destinator.c +++ b/gpsbabel/destinator.c @@ -2,7 +2,7 @@ Support for Destinator POI's, Itineraries and Tracklogs. ( as described at "http://mozoft.com/d3log.html" ) - + Copyright (C) 2008 Olaf Klein, o.b.klein@gpsbabel.org @@ -36,7 +36,7 @@ static arglist_t destinator_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static gbfile *fin, *fout; @@ -50,316 +50,337 @@ static gpsdata_type data_type; static garmin_fs_t * gmsd_init(waypoint *wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; } static char * read_wcstr(const int discard) { - gbint16 *buff = NULL, c; - int size = 0, pos = 0; - - while (gbfread(&c, sizeof(c), 1, fin) && (c != 0)) { - if (size == 0) { - size = 16; - buff = xmalloc(size * sizeof(*buff)); - } - else if (pos == size) { - size += 16; - buff = xrealloc(buff, size * sizeof(*buff)); - } - buff[pos] = c; - pos += 1; - } - - if (pos != 0) { - char *res; - if (discard) res = NULL; - else { - res = cet_str_uni_to_utf8(buff, pos); - res = lrtrim(res); - if (*res == '\0') { - xfree(res); - res = NULL; - } - } - xfree(buff); - return res; - } - else - return NULL; + gbint16 *buff = NULL, c; + int size = 0, pos = 0; + + while (gbfread(&c, sizeof(c), 1, fin) && (c != 0)) { + if (size == 0) { + size = 16; + buff = xmalloc(size * sizeof(*buff)); + } else if (pos == size) { + size += 16; + buff = xrealloc(buff, size * sizeof(*buff)); + } + buff[pos] = c; + pos += 1; + } + + if (pos != 0) { + char *res; + if (discard) { + res = NULL; + } else { + res = cet_str_uni_to_utf8(buff, pos); + res = lrtrim(res); + if (*res == '\0') { + xfree(res); + res = NULL; + } + } + xfree(buff); + return res; + } else { + return NULL; + } } static void write_wcstr(const char *str) { - int len; - short *unicode; - - unicode = cet_str_utf8_to_uni(str, &len); - gbfwrite((void *)unicode, 2, len + 1, fout); - xfree(unicode); + int len; + short *unicode; + + unicode = cet_str_utf8_to_uni(str, &len); + gbfwrite((void *)unicode, 2, len + 1, fout); + xfree(unicode); } static int read_until_wcstr(const char *str) { - char *buff; - int len, sz; - int eos = 0, res = 0; - - len = strlen(str); - sz = (len + 1) * 2; - buff = xcalloc(sz, 1); - - while (! gbfeof(fin)) { - - char c = gbfgetc(fin); - memmove(buff, buff + 1, sz - 1); - buff[sz - 1] = c; - - if (c == 0) { - eos++; - if (eos >= 2) { /* two or more zero bytes => end of string */ - char *test = cet_str_uni_to_utf8((short *)buff, len); - if (test) { - res = (strcmp(str, test) == 0); - xfree(test); - if (res) break; - } - } - } - else eos = 0; - } - xfree(buff); - return res; + char *buff; + int len, sz; + int eos = 0, res = 0; + + len = strlen(str); + sz = (len + 1) * 2; + buff = xcalloc(sz, 1); + + while (! gbfeof(fin)) { + + char c = gbfgetc(fin); + memmove(buff, buff + 1, sz - 1); + buff[sz - 1] = c; + + if (c == 0) { + eos++; + if (eos >= 2) { /* two or more zero bytes => end of string */ + char *test = cet_str_uni_to_utf8((short *)buff, len); + if (test) { + res = (strcmp(str, test) == 0); + xfree(test); + if (res) { + break; + } + } + } + } else { + eos = 0; + } + } + xfree(buff); + return res; } static void destinator_read_poi(void) { - waypoint *wpt; - int count = 0; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - char *str, *hnum; - double ll; - garmin_fs_t *gmsd; - - if (count == 0) { - str = read_wcstr(0); - if ((str == NULL) || (strcmp(str, DST_DYN_POI) != 0)) - fatal(MYNAME "_poi: Invalid record header!\n"); - xfree(str); - } - else if (! read_until_wcstr(DST_DYN_POI)) break; - - count++; - - wpt = waypt_new(); - - wpt->shortname = read_wcstr(0); - wpt->notes = read_wcstr(0); /* comment */ - - hnum = read_wcstr(0); /* house number */ - - str = read_wcstr(0); /* street */ - if (!str) { - str = hnum; - hnum = NULL; - } - if (str) { - gmsd = gmsd_init(wpt); - if (hnum) { - str = xstrappend(str, " "); - str = xstrappend(str, hnum); - } - GMSD_SET(addr, str); - } - - if ((str = read_wcstr(0))) { /* city */ - gmsd = gmsd_init(wpt); - GMSD_SET(city, str); - } - - if (hnum) xfree(hnum); - - (void) read_wcstr(1); /* unknown */ - - if ((str = read_wcstr(0))) { /* postcode */ - gmsd = gmsd_init(wpt); - GMSD_SET(postal_code, str); - } - - (void) read_wcstr(1); /* unknown */ - - (void) gbfgetdbl(fin); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - ll = gbfgetdbl(fin); - if (ll != wpt->longitude) - fatal(MYNAME "_poi: Invalid file!\n"); - ll = gbfgetdbl(fin); - if (ll != wpt->latitude) - fatal(MYNAME "_poi: Invalid file!\n"); - - waypt_add(wpt); - } + waypoint *wpt; + int count = 0; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + char *str, *hnum; + double ll; + garmin_fs_t *gmsd; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_DYN_POI) != 0)) { + fatal(MYNAME "_poi: Invalid record header!\n"); + } + xfree(str); + } else if (! read_until_wcstr(DST_DYN_POI)) { + break; + } + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); /* comment */ + + hnum = read_wcstr(0); /* house number */ + + str = read_wcstr(0); /* street */ + if (!str) { + str = hnum; + hnum = NULL; + } + if (str) { + gmsd = gmsd_init(wpt); + if (hnum) { + str = xstrappend(str, " "); + str = xstrappend(str, hnum); + } + GMSD_SET(addr, str); + } + + if ((str = read_wcstr(0))) { /* city */ + gmsd = gmsd_init(wpt); + GMSD_SET(city, str); + } + + if (hnum) { + xfree(hnum); + } + + (void) read_wcstr(1); /* unknown */ + + if ((str = read_wcstr(0))) { /* postcode */ + gmsd = gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + + (void) read_wcstr(1); /* unknown */ + + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + ll = gbfgetdbl(fin); + if (ll != wpt->longitude) { + fatal(MYNAME "_poi: Invalid file!\n"); + } + ll = gbfgetdbl(fin); + if (ll != wpt->latitude) { + fatal(MYNAME "_poi: Invalid file!\n"); + } + + waypt_add(wpt); + } } static void destinator_read_rte(void) { - int count = 0; - route_head *rte = NULL; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - char *str; - waypoint *wpt; - - if (count == 0) { - str = read_wcstr(0); - if ((str == NULL) || (strcmp(str, DST_ITINERARY) != 0)) - fatal(MYNAME "_itn: Invalid record header!\n"); - xfree(str); - } - else if (! read_until_wcstr(DST_ITINERARY)) break; - - count++; - - wpt = waypt_new(); - - wpt->shortname = read_wcstr(0); - wpt->notes = read_wcstr(0); - - (void) gbfgetint32(fin); - (void) gbfgetdbl(fin); - (void) gbfgetdbl(fin); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - if (gbfgetdbl(fin) != wpt->longitude) - fatal(MYNAME "_itn: Invalid file!\n"); - if (gbfgetdbl(fin) != wpt->latitude) - fatal(MYNAME "_itn: Invalid file!\n"); - - if (! rte) { - rte = route_head_alloc(); - route_add_head(rte); - } - route_add_wpt(rte, wpt); - - (void) gbfgetdbl(fin); - (void) gbfgetdbl(fin); - } + int count = 0; + route_head *rte = NULL; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + char *str; + waypoint *wpt; + + if (count == 0) { + str = read_wcstr(0); + if ((str == NULL) || (strcmp(str, DST_ITINERARY) != 0)) { + fatal(MYNAME "_itn: Invalid record header!\n"); + } + xfree(str); + } else if (! read_until_wcstr(DST_ITINERARY)) { + break; + } + + count++; + + wpt = waypt_new(); + + wpt->shortname = read_wcstr(0); + wpt->notes = read_wcstr(0); + + (void) gbfgetint32(fin); + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + if (gbfgetdbl(fin) != wpt->longitude) { + fatal(MYNAME "_itn: Invalid file!\n"); + } + if (gbfgetdbl(fin) != wpt->latitude) { + fatal(MYNAME "_itn: Invalid file!\n"); + } + + if (! rte) { + rte = route_head_alloc(); + route_add_head(rte); + } + route_add_wpt(rte, wpt); + + (void) gbfgetdbl(fin); + (void) gbfgetdbl(fin); + } } static void destinator_read_trk(void) { - char TXT[4] = "TXT"; - int recno = -1; - route_head *trk = NULL; - - gbfrewind(fin); - - while (! (gbfeof(fin))) { - waypoint *wpt; - struct tm tm; - char buff[20]; - int date; - double time; - - recno++; - - if (gbfeof(fin)) break; - - wpt = waypt_new(); - - wpt->longitude = gbfgetdbl(fin); - wpt->latitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - (void) gbfgetdbl(fin); /* unknown */ - (void) gbfgetdbl(fin); /* unknown */ - (void) gbfgetdbl(fin); /* unknown */ - - wpt->fix = gbfgetint32(fin); - wpt->sat = gbfgetint32(fin); - - gbfseek(fin, 12 * sizeof(gbint32), SEEK_CUR); /* SAT info */ - - date = gbfgetint32(fin); - time = gbfgetflt(fin); - - gbfseek(fin, 2 * 12, SEEK_CUR); /* SAT info */ - - gbfread(TXT, 1, 3, fin); - if (strcmp(TXT, "TXT") != 0) - fatal(MYNAME "_trk: No (or unknown) file!\n"); - - gbfseek(fin, 13, SEEK_CUR); /* unknown */ - - memset(&tm, 0, sizeof(tm)); - - snprintf(buff, sizeof(buff), "%06d%.f", date, time); - strptime(buff, "%d%m%y%H%M%S", &tm); - wpt->creation_time = mkgmtime(&tm); - wpt->microseconds = ((int)time % 1000) * 1000; - - if (wpt->fix > 0) wpt->fix++; - - if (! trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + char TXT[4] = "TXT"; + int recno = -1; + route_head *trk = NULL; + + gbfrewind(fin); + + while (!(gbfeof(fin))) { + waypoint *wpt; + struct tm tm; + char buff[20]; + int date; + double time; + + recno++; + + if (gbfeof(fin)) { + break; + } + + wpt = waypt_new(); + + wpt->longitude = gbfgetdbl(fin); + wpt->latitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + (void) gbfgetdbl(fin); /* unknown */ + + wpt->fix = gbfgetint32(fin); + wpt->sat = gbfgetint32(fin); + + gbfseek(fin, 12 * sizeof(gbint32), SEEK_CUR); /* SAT info */ + + date = gbfgetint32(fin); + time = gbfgetflt(fin); + + gbfseek(fin, 2 * 12, SEEK_CUR); /* SAT info */ + + gbfread(TXT, 1, 3, fin); + if (strcmp(TXT, "TXT") != 0) { + fatal(MYNAME "_trk: No (or unknown) file!\n"); + } + + gbfseek(fin, 13, SEEK_CUR); /* unknown */ + + memset(&tm, 0, sizeof(tm)); + + snprintf(buff, sizeof(buff), "%06d%.f", date, time); + strptime(buff, "%d%m%y%H%M%S", &tm); + wpt->creation_time = mkgmtime(&tm); + wpt->microseconds = ((int)time % 1000) * 1000; + + if (wpt->fix > 0) { + wpt->fix++; + } + + if (! trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void destinator_read(void) { - int i0, i1; - double d0, d1; - char buff[16]; - - if (! gbfread(buff, 1, sizeof(buff), fin)) - fatal(MYNAME ": Unexpected EOF (end of file)!\n"); - - i0 = le_read32(&buff[0]); - i1 = le_read32(&buff[4]); - - if ((i0 == 0x690043) && (i1 == 0x790074)) { - if (data_type != rtedata) - warning(MYNAME ": Using Destinator Itinerary Format!\n"); - destinator_read_rte(); - } - else if ((i0 == 0x790044) && (i1 == 0x61006e)) { - if (data_type != wptdata) - warning(MYNAME ": Using Destinator POI Format!\n"); - destinator_read_poi(); - } - else { - if (data_type != trkdata) - warning(MYNAME ": Using Destinator Tracklog Format!\n"); - - le_read64(&d0, &buff[0]); - le_read64(&d1, &buff[8]); - if ((fabs(d0) > 180) || (fabs(d1) > 90)) - fatal(MYNAME ": No Destinator (.dat) file!\n"); - destinator_read_trk(); - } + int i0, i1; + double d0, d1; + char buff[16]; + + if (! gbfread(buff, 1, sizeof(buff), fin)) { + fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + } + + i0 = le_read32(&buff[0]); + i1 = le_read32(&buff[4]); + + if ((i0 == 0x690043) && (i1 == 0x790074)) { + if (data_type != rtedata) { + warning(MYNAME ": Using Destinator Itinerary Format!\n"); + } + destinator_read_rte(); + } else if ((i0 == 0x790044) && (i1 == 0x61006e)) { + if (data_type != wptdata) { + warning(MYNAME ": Using Destinator POI Format!\n"); + } + destinator_read_poi(); + } else { + if (data_type != trkdata) { + warning(MYNAME ": Using Destinator Tracklog Format!\n"); + } + + le_read64(&d0, &buff[0]); + le_read64(&d1, &buff[8]); + if ((fabs(d0) > 180) || (fabs(d1) > 90)) { + fatal(MYNAME ": No Destinator (.dat) file!\n"); + } + destinator_read_trk(); + } } /*******************************************************************************/ @@ -369,89 +390,94 @@ destinator_read(void) static void destinator_wpt_disp(const waypoint *wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); + garmin_fs_t *gmsd = GMSD_FIND(wpt); - write_wcstr(DST_DYN_POI); - write_wcstr((wpt->shortname) ? wpt->shortname : "WPT"); - write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + write_wcstr(DST_DYN_POI); + write_wcstr((wpt->shortname) ? wpt->shortname : "WPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); - write_wcstr(NULL); /* house number */ - write_wcstr(GMSD_GET(addr, NULL)); /* street */ - write_wcstr(GMSD_GET(city, NULL)); /* city */ - write_wcstr(NULL); /* unknown */ - write_wcstr(GMSD_GET(postal_code, NULL)); /* postcode */ - write_wcstr(NULL); /* unknown */ + write_wcstr(NULL); /* house number */ + write_wcstr(GMSD_GET(addr, NULL)); /* street */ + write_wcstr(GMSD_GET(city, NULL)); /* city */ + write_wcstr(NULL); /* unknown */ + write_wcstr(GMSD_GET(postal_code, NULL)); /* postcode */ + write_wcstr(NULL); /* unknown */ - gbfputint32(0, fout); - gbfputint32(0, fout); + gbfputint32(0, fout); + gbfputint32(0, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); } static void destinator_trkpt_disp(const waypoint *wpt) { - int i; - - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->altitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); - gbfputint32(wpt->fix > fix_unknown ? wpt->fix - 1 : 0, fout); - gbfputint32(wpt->sat, fout); - for (i = 0; i < 12; i++) gbfputint32(0, fout); - - if (wpt->creation_time) { - struct tm tm; - double time; - int date; - - tm = *gmtime(&wpt->creation_time); - tm.tm_mon += 1; - tm.tm_year -= 100; - date = ((int)tm.tm_mday * 10000) + ((int)tm.tm_mon * 100) + tm.tm_year; - gbfputint32(date, fout); - - time = ((int)tm.tm_hour * 10000) + ((int)tm.tm_min * 100) + tm.tm_sec; - time = (time * 1000) + (wpt->microseconds / 1000); - gbfputflt(time, fout); - } - else { - gbfputint32(0, fout); /* Is this invalid ? */ - gbfputflt(0, fout); - } - - for (i = 0; i < 12; i++) gbfputint16(0, fout); - gbfputcstr("TXT", fout); - for (i = 0; i < 12; i++) gbfputc(0, fout); + int i; + + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->altitude, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputint32(wpt->fix > fix_unknown ? wpt->fix - 1 : 0, fout); + gbfputint32(wpt->sat, fout); + for (i = 0; i < 12; i++) { + gbfputint32(0, fout); + } + + if (wpt->creation_time) { + struct tm tm; + double time; + int date; + + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year -= 100; + date = ((int)tm.tm_mday * 10000) + ((int)tm.tm_mon * 100) + tm.tm_year; + gbfputint32(date, fout); + + time = ((int)tm.tm_hour * 10000) + ((int)tm.tm_min * 100) + tm.tm_sec; + time = (time * 1000) + (wpt->microseconds / 1000); + gbfputflt(time, fout); + } else { + gbfputint32(0, fout); /* Is this invalid ? */ + gbfputflt(0, fout); + } + + for (i = 0; i < 12; i++) { + gbfputint16(0, fout); + } + gbfputcstr("TXT", fout); + for (i = 0; i < 12; i++) { + gbfputc(0, fout); + } } static void destinator_rtept_disp(const waypoint *wpt) { - write_wcstr(DST_ITINERARY); - write_wcstr((wpt->shortname) ? wpt->shortname : "RTEPT"); - write_wcstr((wpt->notes) ? wpt->notes : wpt->description); + write_wcstr(DST_ITINERARY); + write_wcstr((wpt->shortname) ? wpt->shortname : "RTEPT"); + write_wcstr((wpt->notes) ? wpt->notes : wpt->description); - gbfputint32(0, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputint32(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->latitude, fout); - gbfputdbl(0, fout); - gbfputdbl(0, fout); + gbfputdbl(0, fout); + gbfputdbl(0, fout); } /******************************************************************************* @@ -461,120 +487,120 @@ destinator_rtept_disp(const waypoint *wpt) static void destinator_rd_init(const char *fname) { - fin = gbfopen_le(fname, "rb", MYNAME); + fin = gbfopen_le(fname, "rb", MYNAME); } -static void +static void destinator_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void destinator_read_poi_wrapper(void) { - data_type = wptdata; - destinator_read(); + data_type = wptdata; + destinator_read(); } static void destinator_read_rte_wrapper(void) { - data_type = rtedata; - destinator_read(); + data_type = rtedata; + destinator_read(); } static void destinator_read_trk_wrapper(void) { - data_type = trkdata; - destinator_read(); + data_type = trkdata; + destinator_read(); } static void destinator_wr_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void destinator_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void destinator_write_poi(void) { - waypt_disp_all(destinator_wpt_disp); + waypt_disp_all(destinator_wpt_disp); } static void destinator_write_rte(void) { - route_disp_all(NULL, NULL, destinator_rtept_disp); + route_disp_all(NULL, NULL, destinator_rtept_disp); } static void destinator_write_trk(void) { - track_disp_all(NULL, NULL, destinator_trkpt_disp); + track_disp_all(NULL, NULL, destinator_trkpt_disp); } /**************************************************************************/ ff_vecs_t destinator_poi_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_poi_wrapper, - destinator_write_poi, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_poi_wrapper, + destinator_write_poi, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; ff_vecs_t destinator_itn_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_rte_wrapper, - destinator_write_rte, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_rte_wrapper, + destinator_write_rte, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; ff_vecs_t destinator_trl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - destinator_rd_init, - destinator_wr_init, - destinator_rd_deinit, - destinator_wr_deinit, - destinator_read_trk_wrapper, - destinator_write_trk, - NULL, - destinator_args, - CET_CHARSET_UTF8, 1 /* fixed */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + destinator_rd_init, + destinator_wr_init, + destinator_rd_deinit, + destinator_wr_deinit, + destinator_read_trk_wrapper, + destinator_write_trk, + NULL, + destinator_args, + CET_CHARSET_UTF8, 1 /* fixed */ }; /**************************************************************************/ diff --git a/gpsbabel/dg-100.c b/gpsbabel/dg-100.c index 5cc616ce1..2ae816fcd 100644 --- a/gpsbabel/dg-100.c +++ b/gpsbabel/dg-100.c @@ -44,140 +44,140 @@ static void *serial_handle; #define FRAME_MAXLEN 4096 enum dg100_command_id { - dg100cmd_getconfig = 0xB7, - dg100cmd_setconfig = 0xB8, - dg100cmd_getfileheader = 0xBB, - dg100cmd_getfile = 0xB5, - dg100cmd_erase = 0xBA, - dg100cmd_getid = 0xBF, - dg100cmd_setid = 0xC0, - dg100cmd_gpsmouse = 0xBC + dg100cmd_getconfig = 0xB7, + dg100cmd_setconfig = 0xB8, + dg100cmd_getfileheader = 0xBB, + dg100cmd_getfile = 0xB5, + dg100cmd_erase = 0xBA, + dg100cmd_getid = 0xBF, + dg100cmd_setid = 0xC0, + dg100cmd_gpsmouse = 0xBC }; struct dg100_command { - int id; - int sendsize; - int recvsize; - int trailing_bytes; - const char *text; /* Textual description for debugging */ + int id; + int sendsize; + int recvsize; + int trailing_bytes; + const char *text; /* Textual description for debugging */ }; struct dg100_command dg100_commands[] = { - { dg100cmd_getconfig, 0, 44+2, 2, "getconfig" }, - { dg100cmd_setconfig, 41, 4+2, 2, "setconfig" }, - /* the getfileheader answer has variable length, -1 is a dummy value */ - { dg100cmd_getfileheader, 2, -1 , 2, "getfileheader" }, - { dg100cmd_getfile, 2, 1024+2, 2, "getfile" }, - { dg100cmd_erase, 2, 4+2, 2, "erase" }, - { dg100cmd_getid, 0, 8+2, 2, "getid" }, - { dg100cmd_setid, 8, 4+2, 2, "setid" }, - { dg100cmd_gpsmouse, 1, 0 , 0, "gpsmouse" } + { dg100cmd_getconfig, 0, 44+2, 2, "getconfig" }, + { dg100cmd_setconfig, 41, 4+2, 2, "setconfig" }, + /* the getfileheader answer has variable length, -1 is a dummy value */ + { dg100cmd_getfileheader, 2, -1 , 2, "getfileheader" }, + { dg100cmd_getfile, 2, 1024+2, 2, "getfile" }, + { dg100cmd_erase, 2, 4+2, 2, "erase" }, + { dg100cmd_getid, 0, 8+2, 2, "getid" }, + { dg100cmd_setid, 8, 4+2, 2, "setid" }, + { dg100cmd_gpsmouse, 1, 0 , 0, "gpsmouse" } }; const unsigned dg100_numcommands = sizeof(dg100_commands) / sizeof(dg100_commands[0]); struct dynarray16 { - unsigned count; /* number of elements used */ - unsigned limit; /* number of elements allocated */ - gbint16 *data; + unsigned count; /* number of elements used */ + unsigned limit; /* number of elements allocated */ + gbint16 *data; }; /* helper functions */ static struct dg100_command * -dg100_findcmd(int id) -{ - unsigned int i; +dg100_findcmd(int id) { + unsigned int i; - /* linear search should be OK as long as dg100_numcommands is small */ - for (i = 0; i < dg100_numcommands; i++) { - if (dg100_commands[i].id == id) - return(&dg100_commands[i]); - } + /* linear search should be OK as long as dg100_numcommands is small */ + for (i = 0; i < dg100_numcommands; i++) { + if (dg100_commands[i].id == id) { + return(&dg100_commands[i]); + } + } - return NULL; + return NULL; } static void dynarray16_init(struct dynarray16 *a, unsigned limit) { - a->count = 0; - a->limit = limit; - a->data = xmalloc(sizeof(a->data[0]) * a->limit); + a->count = 0; + a->limit = limit; + a->data = xmalloc(sizeof(a->data[0]) * a->limit); } static gbint16 * dynarray16_alloc(struct dynarray16 *a, unsigned n) { - unsigned oldcount, need; - const unsigned elements_per_chunk = 4096 / sizeof(a->data[0]); - - oldcount = a->count; - a->count += n; - - if (a->count > a->limit) { - need = a->count - a->limit; - need = (need > elements_per_chunk) ? need : elements_per_chunk; - a->limit += need; - a->data = xrealloc(a->data, sizeof(a->data[0]) * a->limit); - } - return(a->data + oldcount); + unsigned oldcount, need; + const unsigned elements_per_chunk = 4096 / sizeof(a->data[0]); + + oldcount = a->count; + a->count += n; + + if (a->count > a->limit) { + need = a->count - a->limit; + need = (need > elements_per_chunk) ? need : elements_per_chunk; + a->limit += need; + a->data = xrealloc(a->data, sizeof(a->data[0]) * a->limit); + } + return(a->data + oldcount); } static time_t bintime2utc(int date, int time) { - struct tm gpstime; - - gpstime.tm_sec = time % 100; - time /= 100; - gpstime.tm_min = time % 100; - time /= 100; - gpstime.tm_hour = time; - - /* - * GPS year: 2000+; struct tm year: 1900+ - * GPS month: 1-12, struct tm month: 0-11 - */ - gpstime.tm_year = date % 100 + 100; - date /= 100; - gpstime.tm_mon = date % 100 - 1; - date /= 100; - gpstime.tm_mday = date; - - return(mkgmtime(&gpstime)); + struct tm gpstime; + + gpstime.tm_sec = time % 100; + time /= 100; + gpstime.tm_min = time % 100; + time /= 100; + gpstime.tm_hour = time; + + /* + * GPS year: 2000+; struct tm year: 1900+ + * GPS month: 1-12, struct tm month: 0-11 + */ + gpstime.tm_year = date % 100 + 100; + date /= 100; + gpstime.tm_mon = date % 100 - 1; + date /= 100; + gpstime.tm_mday = date; + + return(mkgmtime(&gpstime)); } -static void +static void dg100_debug(const char *hdr, int include_nl, size_t sz, unsigned char *buf) { - unsigned int i; + unsigned int i; - /* Only give byte dumps for higher debug levels */ - if (global_opts.debug_level < 5) { - return; - } + /* Only give byte dumps for higher debug levels */ + if (global_opts.debug_level < 5) { + return; + } - fprintf(stderr, "%s", hdr); + fprintf(stderr, "%s", hdr); - for (i = 0; i < sz; i++) { - fprintf(stderr, "%02x ", buf[i]); - } + for (i = 0; i < sz; i++) { + fprintf(stderr, "%02x ", buf[i]); + } - if (include_nl) { - fprintf(stderr, "\n"); - } + if (include_nl) { + fprintf(stderr, "\n"); + } } static void dg100_log(const char *fmt, ...) { - va_list ap; - va_start (ap, fmt); - if (global_opts.debug_level < 1) { - return; - } - - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + if (global_opts.debug_level < 1) { + return; + } + + vfprintf(stderr, fmt, ap); + va_end(ap); } @@ -185,158 +185,158 @@ dg100_log(const char *fmt, ...) static float bin2deg(int val) { - /* Assume that val prints in decimal digits as [-]dddmmffff - * ddd: degrees - * mm: the integer part of minutes - * ffff: the fractional part of minutes (decimal fraction 0.ffff) - */ - - float deg; - int deg_int, min_scaled, isneg; - unsigned absval; - - /* avoid division of negative integers, - * which has platform-dependent results */ - absval = abs(val); - isneg = (val < 0); - - deg_int = absval / 1000000; /* extract ddd */ - min_scaled = absval % 1000000; /* extract mmffff (minutes * 10^4) */ - deg = deg_int + (double) min_scaled / (10000 * 60); - - /* restore the sign */ - deg = isneg ? -deg : deg; - return(deg); + /* Assume that val prints in decimal digits as [-]dddmmffff + * ddd: degrees + * mm: the integer part of minutes + * ffff: the fractional part of minutes (decimal fraction 0.ffff) + */ + + float deg; + int deg_int, min_scaled, isneg; + unsigned absval; + + /* avoid division of negative integers, + * which has platform-dependent results */ + absval = abs(val); + isneg = (val < 0); + + deg_int = absval / 1000000; /* extract ddd */ + min_scaled = absval % 1000000; /* extract mmffff (minutes * 10^4) */ + deg = deg_int + (double) min_scaled / (10000 * 60); + + /* restore the sign */ + deg = isneg ? -deg : deg; + return(deg); } static void process_gpsfile(gbuint8 data[], route_head *track) { - const int recordsizes[3] = {8, 20, 32}; - int i, style, recsize; - int lat, lon, bintime, bindate; - waypoint *wpt; - - /* the first record of each file is always full-sized; its style field - * determines the format of all subsequent records in the file */ - style = be_read32(data + 28); - if (style > 2) { - fprintf(stderr, "unknown GPS record style %d", style); - return; - } - recsize = recordsizes[style]; - - for (i = 0; i <= 2048 - recsize; i += (i == 0) ? 32 : recsize) { - - lat = be_read32(data + i + 0); - lon = be_read32(data + i + 4); - - /* skip invalid trackpoints (blank records) */ - if (lat == -1 && lon == -1) { - continue; - } - - wpt = waypt_new(); - wpt->latitude = bin2deg(lat); - wpt->longitude = bin2deg(lon); - - if (style >= 1) { - bintime = be_read32(data + i + 8); - bindate = be_read32(data + i + 12); - wpt->creation_time = bintime2utc(bindate, bintime); - /* The device presents the speed as a fixed-point number - * with a scaling factor of 100, in km/h. - * The waypoint struct wants the speed as a - * floating-point number, in m/s. */ - wpt->speed = KPH_TO_MPS(be_read32(data + i + 16) / 100.0); - wpt->wpt_flags.speed = 1; - } - - if (style >= 2) { - wpt->altitude = be_read32(data + i + 20) / 10000.0; - } - - track_add_wpt(track, wpt); - } + const int recordsizes[3] = {8, 20, 32}; + int i, style, recsize; + int lat, lon, bintime, bindate; + waypoint *wpt; + + /* the first record of each file is always full-sized; its style field + * determines the format of all subsequent records in the file */ + style = be_read32(data + 28); + if (style > 2) { + fprintf(stderr, "unknown GPS record style %d", style); + return; + } + recsize = recordsizes[style]; + + for (i = 0; i <= 2048 - recsize; i += (i == 0) ? 32 : recsize) { + + lat = be_read32(data + i + 0); + lon = be_read32(data + i + 4); + + /* skip invalid trackpoints (blank records) */ + if (lat == -1 && lon == -1) { + continue; + } + + wpt = waypt_new(); + wpt->latitude = bin2deg(lat); + wpt->longitude = bin2deg(lon); + + if (style >= 1) { + bintime = be_read32(data + i + 8); + bindate = be_read32(data + i + 12); + wpt->creation_time = bintime2utc(bindate, bintime); + /* The device presents the speed as a fixed-point number + * with a scaling factor of 100, in km/h. + * The waypoint struct wants the speed as a + * floating-point number, in m/s. */ + wpt->speed = KPH_TO_MPS(be_read32(data + i + 16) / 100.0); + wpt->wpt_flags.speed = 1; + } + + if (style >= 2) { + wpt->altitude = be_read32(data + i + 20) / 10000.0; + } + + track_add_wpt(track, wpt); + } } static gbuint16 dg100_checksum(gbuint8 buf[], int count) { - gbuint16 sum = 0; - int i; + gbuint16 sum = 0; + int i; - for (i = 0; i < count; i++) { - sum += buf[i]; - } - sum &= (1<<15) - 1; + for (i = 0; i < count; i++) { + sum += buf[i]; + } + sum &= (1<<15) - 1; - return(sum); + return(sum); } /* communication functions */ static size_t dg100_send(gbuint8 cmd, const void *payload, size_t count) { - gbuint8 frame[FRAME_MAXLEN]; - gbuint16 checksum, payload_len; - size_t framelen, param_len; - int n; - - param_len = count; - payload_len = 1 + count; - /* Frame length calculation: - * frame start sequence(2), payload length field(2), command id(1), - * param(variable length), - * checksum(2), frame end sequence(2) */ - framelen = 2 + 2 + 1 + count + 2 + 2; - assert(framelen <= FRAME_MAXLEN); - - /* create frame head + command */ - be_write16(frame + 0, 0xA0A2); - be_write16(frame + 2, payload_len); - frame[4] = cmd; - - /* copy payload */ - memcpy(frame + 5, payload, count); - - /* create frame tail */ - checksum = dg100_checksum(frame + 4, framelen - 8); - be_write16(frame + framelen - 4, checksum); - be_write16(frame + framelen - 2, 0xB0B3); - - n = gbser_write(serial_handle, frame, framelen); - - if (global_opts.debug_level) { - struct dg100_command *cmdp = dg100_findcmd(cmd); - - dg100_debug(n == 0 ? "Sent: " : "Error Sending:", - 1, framelen, frame); - dg100_log("TX: Frame Start %02x %02x Payload_Len %04x Cmd: %s\n", - frame[0], frame[1], payload_len, cmdp->text); - } - - if (n == gbser_ERROR) { - fatal("dg_100_send: write failed\n"); - } - return (n); + gbuint8 frame[FRAME_MAXLEN]; + gbuint16 checksum, payload_len; + size_t framelen, param_len; + int n; + + param_len = count; + payload_len = 1 + count; + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * checksum(2), frame end sequence(2) */ + framelen = 2 + 2 + 1 + count + 2 + 2; + assert(framelen <= FRAME_MAXLEN); + + /* create frame head + command */ + be_write16(frame + 0, 0xA0A2); + be_write16(frame + 2, payload_len); + frame[4] = cmd; + + /* copy payload */ + memcpy(frame + 5, payload, count); + + /* create frame tail */ + checksum = dg100_checksum(frame + 4, framelen - 8); + be_write16(frame + framelen - 4, checksum); + be_write16(frame + framelen - 2, 0xB0B3); + + n = gbser_write(serial_handle, frame, framelen); + + if (global_opts.debug_level) { + struct dg100_command *cmdp = dg100_findcmd(cmd); + + dg100_debug(n == 0 ? "Sent: " : "Error Sending:", + 1, framelen, frame); + dg100_log("TX: Frame Start %02x %02x Payload_Len %04x Cmd: %s\n", + frame[0], frame[1], payload_len, cmdp->text); + } + + if (n == gbser_ERROR) { + fatal("dg_100_send: write failed\n"); + } + return (n); } static int dg100_recv_byte() { - int result; - - /* allow for a delay of 40s; - * erasing the whole DG-100 memory takes about 21s */ - result = gbser_readc_wait(serial_handle, 40000); - switch(result){ - case gbser_ERROR: - fatal("dg100_recv_byte(): error reading one byte\n"); - case gbser_NOTHING: - fatal("dg100_recv_byte(): read timeout\n"); - } - return result; + int result; + + /* allow for a delay of 40s; + * erasing the whole DG-100 memory takes about 21s */ + result = gbser_readc_wait(serial_handle, 40000); + switch (result) { + case gbser_ERROR: + fatal("dg100_recv_byte(): error reading one byte\n"); + case gbser_NOTHING: + fatal("dg100_recv_byte(): read timeout\n"); + } + return result; } /* payload returns a pointer into a static buffer (which also contains the @@ -345,156 +345,156 @@ dg100_recv_byte() static int dg100_recv_frame(struct dg100_command **cmdinfo_result, gbuint8 **payload) { - static gbuint8 buf[FRAME_MAXLEN]; - gbuint16 frame_start_seq, payload_len_field; - gbuint16 payload_end_seq, payload_checksum, frame_end_seq; - gbuint16 frame_head, numheaders, sum; - gbuint8 c, cmd; - int i, param_len, frame_len; - struct dg100_command *cmdinfo; - - /* consume input until frame head sequence 0xA0A2 was received */ - frame_head = 0; - dg100_debug("Receiving ", 0, 0, NULL); - do { - c = dg100_recv_byte(); - dg100_debug("", 0, 1, &c); - frame_head <<= 8; - frame_head |= c; - - } while (frame_head != 0xA0A2); - - be_write16(buf + 0, frame_head); - - /* To read the remaining data, we need to know how long the frame is. - * - * The obvious source of this information would be the payload length - * field, but the spec says that this field should be ignored in answers. - * Indeed, its value differs from the actual payload length. - * - * We could scan for the frame end sequences, - * but there is no guarantee that they do not appear within valid data. - * - * This means we can only calculate the length using information from - * the beginning of the frame, other than the payload length. - * - * The solution implemented here is to derive the frame length from the - * Command ID field, which is more of an answer ID. This is possible - * since for each answer ID, the frame length is either constant or it - * can be derived from the first two bytes of payload data. - */ - - /* read Payload Length, Command ID, and two further bytes */ - i = gbser_read_wait(serial_handle, &buf[2], 5, 1000); - if (i < 5) { - fatal("Expected to read 5 bytes, but got %d\n", i); - } - dg100_debug("", 0, 5, &buf[2]); - - payload_len_field = be_read16(buf + 2); - cmd = buf[4]; - - /* - * getconfig/setconfig have the same answer ID - - * this seems to be a firmware bug we must work around. - * Distinguish them by the (otherwise ignored) Payload Len field, - * which was observed as 53 for getconfig and 5 for setconfig. - */ - if (cmd == dg100cmd_getconfig && payload_len_field <= 20) { - cmd = dg100cmd_setconfig; - } - - cmdinfo = dg100_findcmd(cmd); - if (!cmdinfo) { - /* TODO: consume data until frame end signature, - * then report failure to the caller? */ - fatal("unknown answer ID %02x\n", cmd); - } - - param_len = cmdinfo->recvsize; - - /* - * the getfileheader answer has a varying param_len, - * we need to calculate it - */ - if (cmd == dg100cmd_getfileheader) { - numheaders = be_read16(buf + 5); - param_len = 2 + 2 + 12 * numheaders + 2; - } - - /* Frame length calculation: - * frame start sequence(2), payload length field(2), command id(1), - * param(variable length), - * payload end seqence(2), checksum(2), frame end sequence(2) */ - frame_len = 2 + 2 + 1 + param_len + 2 + 2 + 2; - - if (frame_len > FRAME_MAXLEN) { - fatal("frame too large (frame_len=%d, FRAME_MAXLEN=%d)\n", - frame_len, FRAME_MAXLEN); - } - - i = gbser_read_wait(serial_handle, &buf[7], frame_len - 7, 1000); - if (i < frame_len - 7) { - fatal("Expected to read %d bytes, but got %d\n", - frame_len - 7, i); - } - dg100_debug("", 0, frame_len - 7, &buf[7]); - - frame_start_seq = be_read16(buf + 0); - payload_len_field = be_read16(buf + 2); - payload_end_seq = be_read16(buf + frame_len - 6); - payload_checksum = be_read16(buf + frame_len - 4); - frame_end_seq = be_read16(buf + frame_len - 2); - - dg100_log("RX: Start %04x Len %04x Cmd: %s\n", - frame_start_seq, payload_len_field, cmdinfo->text); - - /* calculate checksum */ - sum = dg100_checksum(buf + 4, frame_len - 8); - if (sum != payload_checksum) { - fatal("checksum mismatch: data sum is 0x%04x, checksum received is 0x%04x\n", - sum, payload_checksum); - } - - /* - * TODO: check signatures; - * on failure, flush input or scan for end sequence - */ - - *cmdinfo_result = cmdinfo; - *payload = buf + 5; - dg100_debug("\n", 0, 0, &buf[i]); - return(param_len); + static gbuint8 buf[FRAME_MAXLEN]; + gbuint16 frame_start_seq, payload_len_field; + gbuint16 payload_end_seq, payload_checksum, frame_end_seq; + gbuint16 frame_head, numheaders, sum; + gbuint8 c, cmd; + int i, param_len, frame_len; + struct dg100_command *cmdinfo; + + /* consume input until frame head sequence 0xA0A2 was received */ + frame_head = 0; + dg100_debug("Receiving ", 0, 0, NULL); + do { + c = dg100_recv_byte(); + dg100_debug("", 0, 1, &c); + frame_head <<= 8; + frame_head |= c; + + } while (frame_head != 0xA0A2); + + be_write16(buf + 0, frame_head); + + /* To read the remaining data, we need to know how long the frame is. + * + * The obvious source of this information would be the payload length + * field, but the spec says that this field should be ignored in answers. + * Indeed, its value differs from the actual payload length. + * + * We could scan for the frame end sequences, + * but there is no guarantee that they do not appear within valid data. + * + * This means we can only calculate the length using information from + * the beginning of the frame, other than the payload length. + * + * The solution implemented here is to derive the frame length from the + * Command ID field, which is more of an answer ID. This is possible + * since for each answer ID, the frame length is either constant or it + * can be derived from the first two bytes of payload data. + */ + + /* read Payload Length, Command ID, and two further bytes */ + i = gbser_read_wait(serial_handle, &buf[2], 5, 1000); + if (i < 5) { + fatal("Expected to read 5 bytes, but got %d\n", i); + } + dg100_debug("", 0, 5, &buf[2]); + + payload_len_field = be_read16(buf + 2); + cmd = buf[4]; + + /* + * getconfig/setconfig have the same answer ID - + * this seems to be a firmware bug we must work around. + * Distinguish them by the (otherwise ignored) Payload Len field, + * which was observed as 53 for getconfig and 5 for setconfig. + */ + if (cmd == dg100cmd_getconfig && payload_len_field <= 20) { + cmd = dg100cmd_setconfig; + } + + cmdinfo = dg100_findcmd(cmd); + if (!cmdinfo) { + /* TODO: consume data until frame end signature, + * then report failure to the caller? */ + fatal("unknown answer ID %02x\n", cmd); + } + + param_len = cmdinfo->recvsize; + + /* + * the getfileheader answer has a varying param_len, + * we need to calculate it + */ + if (cmd == dg100cmd_getfileheader) { + numheaders = be_read16(buf + 5); + param_len = 2 + 2 + 12 * numheaders + 2; + } + + /* Frame length calculation: + * frame start sequence(2), payload length field(2), command id(1), + * param(variable length), + * payload end seqence(2), checksum(2), frame end sequence(2) */ + frame_len = 2 + 2 + 1 + param_len + 2 + 2 + 2; + + if (frame_len > FRAME_MAXLEN) { + fatal("frame too large (frame_len=%d, FRAME_MAXLEN=%d)\n", + frame_len, FRAME_MAXLEN); + } + + i = gbser_read_wait(serial_handle, &buf[7], frame_len - 7, 1000); + if (i < frame_len - 7) { + fatal("Expected to read %d bytes, but got %d\n", + frame_len - 7, i); + } + dg100_debug("", 0, frame_len - 7, &buf[7]); + + frame_start_seq = be_read16(buf + 0); + payload_len_field = be_read16(buf + 2); + payload_end_seq = be_read16(buf + frame_len - 6); + payload_checksum = be_read16(buf + frame_len - 4); + frame_end_seq = be_read16(buf + frame_len - 2); + + dg100_log("RX: Start %04x Len %04x Cmd: %s\n", + frame_start_seq, payload_len_field, cmdinfo->text); + + /* calculate checksum */ + sum = dg100_checksum(buf + 4, frame_len - 8); + if (sum != payload_checksum) { + fatal("checksum mismatch: data sum is 0x%04x, checksum received is 0x%04x\n", + sum, payload_checksum); + } + + /* + * TODO: check signatures; + * on failure, flush input or scan for end sequence + */ + + *cmdinfo_result = cmdinfo; + *payload = buf + 5; + dg100_debug("\n", 0, 0, &buf[i]); + return(param_len); } /* return value: number of bytes copied into buf, -1 on error */ static int dg100_recv(gbuint8 expected_id, void *buf, unsigned int len) { - int n; - struct dg100_command *cmdinfo; - gbuint8 *data; - unsigned int copysize, trailing_bytes; - - n = dg100_recv_frame(&cmdinfo, &data); - - /* check whether the received frame matches the expected answer type */ - if (cmdinfo->id != expected_id) { - fprintf(stderr, "ERROR: answer type %02x, expecting %02x", cmdinfo->id, expected_id); - return -1; - } - - trailing_bytes = cmdinfo->trailing_bytes; - copysize = n - trailing_bytes; - - /* check for buffer overflow */ - if (len < copysize) { - fprintf(stderr, "ERROR: buffer too small, size=%d, need=%d", len, copysize); - return -1; - } - - memcpy(buf, data, copysize); - return(copysize); + int n; + struct dg100_command *cmdinfo; + gbuint8 *data; + unsigned int copysize, trailing_bytes; + + n = dg100_recv_frame(&cmdinfo, &data); + + /* check whether the received frame matches the expected answer type */ + if (cmdinfo->id != expected_id) { + fprintf(stderr, "ERROR: answer type %02x, expecting %02x", cmdinfo->id, expected_id); + return -1; + } + + trailing_bytes = cmdinfo->trailing_bytes; + copysize = n - trailing_bytes; + + /* check for buffer overflow */ + if (len < copysize) { + fprintf(stderr, "ERROR: buffer too small, size=%d, need=%d", len, copysize); + return -1; + } + + memcpy(buf, data, copysize); + return(copysize); } /* the number of bytes to be sent is determined by cmd, @@ -502,118 +502,119 @@ dg100_recv(gbuint8 expected_id, void *buf, unsigned int len) static int dg100_request(gbuint8 cmd, const void *sendbuf, void *recvbuf, size_t count) { - struct dg100_command *cmdinfo; - int n, i, frames, fill; - gbuint8 *buf; - - cmdinfo = dg100_findcmd(cmd); - assert (cmdinfo != NULL); - dg100_send(cmd, sendbuf, cmdinfo->sendsize); - - /* the number of frames the answer will comprise */ - frames = (cmd == dg100cmd_getfile) ? 2 : 1; - /* alias pointer for easy typecasting */ - buf = recvbuf; - fill = 0; - for (i = 0; i < frames; i++) { - n = dg100_recv(cmd, buf + fill, count - fill); - if (n < 0) - return(-1); - fill += n; - } - return(fill); + struct dg100_command *cmdinfo; + int n, i, frames, fill; + gbuint8 *buf; + + cmdinfo = dg100_findcmd(cmd); + assert(cmdinfo != NULL); + dg100_send(cmd, sendbuf, cmdinfo->sendsize); + + /* the number of frames the answer will comprise */ + frames = (cmd == dg100cmd_getfile) ? 2 : 1; + /* alias pointer for easy typecasting */ + buf = recvbuf; + fill = 0; + for (i = 0; i < frames; i++) { + n = dg100_recv(cmd, buf + fill, count - fill); + if (n < 0) { + return(-1); + } + fill += n; + } + return(fill); } /* higher level communication functions */ static void dg100_getfileheaders(struct dynarray16 *headers) { - gbuint8 request[2]; - gbuint8 answer[FRAME_MAXLEN]; - int seqnum; - gbint16 numheaders, nextheader, *h; - int i, offset; - - nextheader = 0; - do { - /* request the next batch of headers */ - be_write16(request, nextheader); - dg100_request(dg100cmd_getfileheader, request, answer, sizeof(answer)); - - /* process the answer */ - numheaders = be_read16(answer); - nextheader = be_read16(answer + 2); - dg100_log("found %d headers, nextheader=%d\n", - numheaders, nextheader); - if (numheaders <= 0) { - dg100_log("no further headers, aborting the loop\n"); - break; - } - - h = dynarray16_alloc(headers, numheaders); - for (i = 0; i < numheaders; i++) { - offset = 4 + i * 12; - seqnum = be_read32(answer + offset + 8); - h[i] = seqnum; - if (global_opts.debug_level) { - int time = be_read32(answer + offset); - int date = be_read32(answer + offset + 4); - time_t ti = bintime2utc(date, time); - dg100_log("Header #%d: Seq: %d Time: %s", - i, seqnum, ctime(&ti)); - } - } - } while (nextheader != 0); + gbuint8 request[2]; + gbuint8 answer[FRAME_MAXLEN]; + int seqnum; + gbint16 numheaders, nextheader, *h; + int i, offset; + + nextheader = 0; + do { + /* request the next batch of headers */ + be_write16(request, nextheader); + dg100_request(dg100cmd_getfileheader, request, answer, sizeof(answer)); + + /* process the answer */ + numheaders = be_read16(answer); + nextheader = be_read16(answer + 2); + dg100_log("found %d headers, nextheader=%d\n", + numheaders, nextheader); + if (numheaders <= 0) { + dg100_log("no further headers, aborting the loop\n"); + break; + } + + h = dynarray16_alloc(headers, numheaders); + for (i = 0; i < numheaders; i++) { + offset = 4 + i * 12; + seqnum = be_read32(answer + offset + 8); + h[i] = seqnum; + if (global_opts.debug_level) { + int time = be_read32(answer + offset); + int date = be_read32(answer + offset + 4); + time_t ti = bintime2utc(date, time); + dg100_log("Header #%d: Seq: %d Time: %s", + i, seqnum, ctime(&ti)); + } + } + } while (nextheader != 0); } static void dg100_getfile(gbint16 num, route_head *track) { - gbuint8 request[2]; - gbuint8 answer[2048]; + gbuint8 request[2]; + gbuint8 answer[2048]; - be_write16(request, num); - dg100_request(dg100cmd_getfile, request, answer, sizeof(answer)); - process_gpsfile(answer, track); + be_write16(request, num); + dg100_request(dg100cmd_getfile, request, answer, sizeof(answer)); + process_gpsfile(answer, track); } static void dg100_getfiles() { - unsigned int i; - int filenum; - struct dynarray16 headers; - route_head *track; - - track = route_head_alloc(); - track->rte_name = xstrdup("DG-100 tracklog"); - track->rte_desc = xstrdup("DG-100 GPS tracklog data"); - track_add_head(track); - - /* maximum number of headers observed so far: 672 - * if necessary, the dynarray will grow even further */ - dynarray16_init(&headers, 1024); - - dg100_getfileheaders(&headers); - - for (i = 0; i < headers.count; i++) { - filenum = headers.data[i]; - dg100_getfile(filenum, track); - } + unsigned int i; + int filenum; + struct dynarray16 headers; + route_head *track; + + track = route_head_alloc(); + track->rte_name = xstrdup("DG-100 tracklog"); + track->rte_desc = xstrdup("DG-100 GPS tracklog data"); + track_add_head(track); + + /* maximum number of headers observed so far: 672 + * if necessary, the dynarray will grow even further */ + dynarray16_init(&headers, 1024); + + dg100_getfileheaders(&headers); + + for (i = 0; i < headers.count; i++) { + filenum = headers.data[i]; + dg100_getfile(filenum, track); + } } static int dg100_erase() { - gbuint8 request[2] = { 0xFF, 0xFF }; - gbuint8 answer[4]; - - dg100_request(dg100cmd_erase, request, answer, sizeof(answer)); - if (be_read32(answer) != 1) { - fprintf(stderr, "dg100_erase() FAILED\n"); - return(-1); - } - return(0); + gbuint8 request[2] = { 0xFF, 0xFF }; + gbuint8 answer[4]; + + dg100_request(dg100cmd_erase, request, answer, sizeof(answer)); + if (be_read32(answer) != 1) { + fprintf(stderr, "dg100_erase() FAILED\n"); + return(-1); + } + return(0); } /* GPSBabel integration */ @@ -623,11 +624,15 @@ static char *erase_only; static arglist_t dg100_args[] = { - { "erase", &erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "erase_only", &erase_only, "Only erase device data, do not download anything", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_only", &erase_only, "Only erase device data, do not download anything", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /******************************************************************************* @@ -637,35 +642,35 @@ arglist_t dg100_args[] = { static void dg100_rd_init(const char *fname) { - if (serial_handle = gbser_init(fname), NULL == serial_handle) { - fatal(MYNAME ": Can't open port '%s'\n", fname); - } - if (gbser_set_speed(serial_handle, 115200) != gbser_OK) { - fatal(MYNAME ": Can't configure port '%s'\n", fname); - } - // Toss anything that came in before our speed was set, particularly - // for the bluetooth BT-335 product. - gbser_flush(serial_handle); + if (serial_handle = gbser_init(fname), NULL == serial_handle) { + fatal(MYNAME ": Can't open port '%s'\n", fname); + } + if (gbser_set_speed(serial_handle, 115200) != gbser_OK) { + fatal(MYNAME ": Can't configure port '%s'\n", fname); + } + // Toss anything that came in before our speed was set, particularly + // for the bluetooth BT-335 product. + gbser_flush(serial_handle); } -static void +static void dg100_rd_deinit(void) { - gbser_deinit(serial_handle); - serial_handle = NULL; + gbser_deinit(serial_handle); + serial_handle = NULL; } static void dg100_read(void) { - if (*erase_only == '1') { - dg100_erase(); - return; - } - dg100_getfiles(); - if (*erase == '1') { - dg100_erase(); - } + if (*erase_only == '1') { + dg100_erase(); + return; + } + dg100_getfiles(); + if (*erase == '1') { + dg100_erase(); + } } /**************************************************************************/ @@ -673,21 +678,21 @@ dg100_read(void) // capabilities below means: we can only read tracks ff_vecs_t dg100_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - dg100_rd_init, - NULL, - dg100_rd_deinit, - NULL, - dg100_read, - NULL, - NULL, - dg100_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + dg100_rd_init, + NULL, + dg100_rd_deinit, + NULL, + dg100_read, + NULL, + NULL, + dg100_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/discard.c b/gpsbabel/discard.c index 9e380a2b7..05c93fe51 100644 --- a/gpsbabel/discard.c +++ b/gpsbabel/discard.c @@ -41,23 +41,39 @@ static route_head *head; static arglist_t fix_args[] = { - {"hdop", &hdopopt, "Suppress waypoints with higher hdop", - "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"vdop", &vdopopt, "Suppress waypoints with higher vdop", - "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"hdopandvdop", &andopt, "Link hdop and vdop supression with AND", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"sat", &satopt, "Minimium sats to keep waypoints", - "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - {"fixnone", &fixnoneopt, "Suppress waypoints without fix", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"fixunknown", &fixunknownopt, "Suppress waypoints with unknown fix", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"elemin", &eleminopt, "Suppress waypoints below given elevation in meters", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - {"elemax", &elemaxopt, "Suppress waypoints above given elevation in meters", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "hdop", &hdopopt, "Suppress waypoints with higher hdop", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "vdop", &vdopopt, "Suppress waypoints with higher vdop", + "-1.0", ARGTYPE_END_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "hdopandvdop", &andopt, "Link hdop and vdop supression with AND", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "sat", &satopt, "Minimium sats to keep waypoints", + "-1.0", ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + { + "fixnone", &fixnoneopt, "Suppress waypoints without fix", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "fixunknown", &fixunknownopt, "Suppress waypoints with unknown fix", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "elemin", &eleminopt, "Suppress waypoints below given elevation in meters", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + { + "elemax", &elemaxopt, "Suppress waypoints above given elevation in meters", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* @@ -66,108 +82,121 @@ arglist_t fix_args[] = { static void fix_process_wpt(const waypoint *wpt) { - int del = 0; - int delh = 0; - int delv = 0; - - waypoint *waypointp = (waypoint *) wpt; - - if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) - delh = 1; - if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) - delv = 1; - - if (andopt) - del = delh && delv; - else - del = delh || delv; - - if ((satpf >= 0) && (waypointp->sat < satpf)) - del = 1; - - if ((fixnoneopt) && (waypointp->fix == fix_none)) - del = 1; - - if ((fixunknownopt) && (waypointp->fix == fix_unknown)) - del = 1; - - if ((eleminopt) && (waypointp->altitude < eleminpf)) - del = 1; - - if ((elemaxopt) && (waypointp->altitude > elemaxpf)) - del = 1; - - if (del) { - switch(what) { - case wptdata: - waypt_del(waypointp); - break; - case trkdata: - track_del_wpt(head, waypointp); - break; - case rtedata: - route_del_wpt(head, waypointp); - break; - default: - return; - } - waypt_free(waypointp); - } + int del = 0; + int delh = 0; + int delv = 0; + + waypoint *waypointp = (waypoint *) wpt; + + if ((hdopf >= 0.0) && (waypointp->hdop > hdopf)) { + delh = 1; + } + if ((vdopf >= 0.0) && (waypointp->vdop > vdopf)) { + delv = 1; + } + + if (andopt) { + del = delh && delv; + } else { + del = delh || delv; + } + + if ((satpf >= 0) && (waypointp->sat < satpf)) { + del = 1; + } + + if ((fixnoneopt) && (waypointp->fix == fix_none)) { + del = 1; + } + + if ((fixunknownopt) && (waypointp->fix == fix_unknown)) { + del = 1; + } + + if ((eleminopt) && (waypointp->altitude < eleminpf)) { + del = 1; + } + + if ((elemaxopt) && (waypointp->altitude > elemaxpf)) { + del = 1; + } + + if (del) { + switch (what) { + case wptdata: + waypt_del(waypointp); + break; + case trkdata: + track_del_wpt(head, waypointp); + break; + case rtedata: + route_del_wpt(head, waypointp); + break; + default: + return; + } + waypt_free(waypointp); + } } static void fix_process_head(const route_head *trk) { - head = (route_head *)trk; + head = (route_head *)trk; } static void fix_process(void) { - // Filter waypoints. - what = wptdata; - waypt_disp_all(fix_process_wpt); - - // Filter tracks - what = trkdata; - track_disp_all(fix_process_head, NULL, fix_process_wpt); - - // And routes - what = rtedata; - route_disp_all(fix_process_head, NULL, fix_process_wpt); - + // Filter waypoints. + what = wptdata; + waypt_disp_all(fix_process_wpt); + + // Filter tracks + what = trkdata; + track_disp_all(fix_process_head, NULL, fix_process_wpt); + + // And routes + what = rtedata; + route_disp_all(fix_process_head, NULL, fix_process_wpt); + } static void -fix_init(const char *args) +fix_init(const char *args) { - if (hdopopt) - hdopf = atof(hdopopt); - else - hdopf = -1.0; - - if (vdopopt) - vdopf = atof(vdopopt); - else - vdopf = -1.0; - - if (satopt) - satpf = atoi(satopt); - else - satpf = -1; - - if (eleminopt) - eleminpf = atoi(eleminopt); - - if (elemaxopt) - elemaxpf = atoi(elemaxopt); + if (hdopopt) { + hdopf = atof(hdopopt); + } else { + hdopf = -1.0; + } + + if (vdopopt) { + vdopf = atof(vdopopt); + } else { + vdopf = -1.0; + } + + if (satopt) { + satpf = atoi(satopt); + } else { + satpf = -1; + } + + if (eleminopt) { + eleminpf = atoi(eleminopt); + } + + if (elemaxopt) { + elemaxpf = atoi(elemaxopt); + } } filter_vecs_t discard_vecs = { - fix_init, - fix_process, - NULL, - NULL, - fix_args + fix_init, + fix_process, + NULL, + NULL, + fix_args }; #endif diff --git a/gpsbabel/dmtlog.c b/gpsbabel/dmtlog.c index 8f0088899..31fdf1502 100644 --- a/gpsbabel/dmtlog.c +++ b/gpsbabel/dmtlog.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "jeeps/gpsmath.h" #include "xmlgeneric.h" @@ -53,9 +53,11 @@ static int track_index, this_index; static arglist_t dmtlog_args[] = { - { "index", &opt_index, - "Index of track (if more than one in source)", "1", ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR + { + "index", &opt_index, + "Index of track (if more than one in source)", "1", ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; @@ -63,10 +65,10 @@ arglist_t dmtlog_args[] = { static xg_callback tlog3a_xgcb_version, tlog3a_xgcb_length, tlog3a_xgcb_data; static xg_tag_mapping tlog3a_xgcb_map[] = { - { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, - { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, - { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, - { NULL, 0, NULL} + { tlog3a_xgcb_version, cb_cdata, "/CXMLSafe/Version" }, + { tlog3a_xgcb_length, cb_cdata, "/CXMLSafe/Length" }, + { tlog3a_xgcb_data, cb_cdata, "/CXMLSafe/Data" }, + { NULL, 0, NULL} }; #endif @@ -79,25 +81,25 @@ static xg_callback tlog3b_xgcb_wptno, tlog3b_xgcb_wptal; static xg_callback tlog3b_xgcb_tptdt; static xg_tag_mapping tlog3b_xgcb_map[] = { - { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, - { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, - { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, - { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, - { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, - { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, - { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, - { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, - { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, - { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, - { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, - { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, - { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, - { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, - { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, - { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, - { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, - { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, - { NULL, 0, NULL} + { tlog3b_xgcb_tfna, cb_cdata, "/CTrackFile/Name" }, + { tlog3b_xgcb_tfdes, cb_cdata, "/CTrackFile/Description" }, + { tlog3b_xgcb_wptst, cb_start, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CWayPoint/Id" }, + { tlog3b_xgcb_wptdt, cb_cdata, "/CTrackFile/CWayPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CWayPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CWayPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CWayPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CWayPoint/Altitude" }, + { tlog3b_xgcb_wpten, cb_end, "/CTrackFile/CWayPoint" }, + { tlog3b_xgcb_tptst, cb_start, "/CTrackFile/CTrackPoint" }, + { tlog3b_xgcb_wptid, cb_cdata, "/CTrackFile/CTrackPoint/Id" }, + { tlog3b_xgcb_tptdt, cb_cdata, "/CTrackFile/CTrackPoint/Datum" }, + { tlog3b_xgcb_wptgr, cb_cdata, "/CTrackFile/CTrackPoint/Grid" }, + { tlog3b_xgcb_wptea, cb_cdata, "/CTrackFile/CTrackPoint/Easting" }, + { tlog3b_xgcb_wptno, cb_cdata, "/CTrackFile/CTrackPoint/Northing" }, + { tlog3b_xgcb_wptal, cb_cdata, "/CTrackFile/CTrackPoint/Altitude" }, + { tlog3b_xgcb_tpten, cb_end, "/CTrackFile/CTrackPoint" }, + { NULL, 0, NULL} }; /* helpers */ @@ -105,90 +107,97 @@ static xg_tag_mapping tlog3b_xgcb_map[] = { static void convert_datum(waypoint *wpt, int datum) { - if (datum != DATUM_WGS84) { - double lat = wpt->latitude; - double lon = wpt->longitude; - double alt = wpt->altitude; - GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, - &wpt->latitude, &wpt->longitude, &wpt->altitude, - datum); - } + if (datum != DATUM_WGS84) { + double lat = wpt->latitude; + double lon = wpt->longitude; + double alt = wpt->altitude; + GPS_Math_Known_Datum_To_WGS84_C(lat, lon, alt, + &wpt->latitude, &wpt->longitude, &wpt->altitude, + datum); + } } static void finalize_pt(waypoint *wpt) { - if (strcmp(xmlgrid, "BNG") == 0) { - GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, - &wpt->latitude, &wpt->longitude); - xmldatum = DATUM_OSGB36; - } - else { - wpt->latitude = xmlLatitude; - wpt->longitude = xmlLongitude; - } - /* NOTE: - * Alan White reports this program actually subtracts a number - * of meters ranging between 46 and 50 meters. It appears to be - * constant for each location, but different without an obvious - * correlation to ground altitude. We considered offsetting this - * in GPSBabel, but concluded it wasn't worth the bother. - * If we get complaints, probably all of our alt reading and writing - * should offset an average of 46m or so. - */ - wpt->altitude = xmlAltitude; - convert_datum(wpt, xmldatum); + if (strcmp(xmlgrid, "BNG") == 0) { + GPS_Math_NGENToAiry1830LatLon(xmlEasting, xmlNorthing, + &wpt->latitude, &wpt->longitude); + xmldatum = DATUM_OSGB36; + } else { + wpt->latitude = xmlLatitude; + wpt->longitude = xmlLongitude; + } + /* NOTE: + * Alan White reports this program actually subtracts a number + * of meters ranging between 46 and 50 meters. It appears to be + * constant for each location, but different without an obvious + * correlation to ground altitude. We considered offsetting this + * in GPSBabel, but concluded it wasn't worth the bother. + * If we get complaints, probably all of our alt reading and writing + * should offset an average of 46m or so. + */ + wpt->altitude = xmlAltitude; + convert_datum(wpt, xmldatum); } /* xml-reader callbacks */ #if !ZLIB_INHIBITED -static void +static void tlog3a_xgcb_version(const char *args, const char **unused) { - if (strcmp(args, "1") != 0) - fatal(MYNAME ": Unsupported file version '%s'!\n", args); + if (strcmp(args, "1") != 0) { + fatal(MYNAME ": Unsupported file version '%s'!\n", args); + } } -static void +static void tlog3a_xgcb_length(const char *args, const char **unused) { } -static void +static void tlog3a_xgcb_data(const char *args, const char **unused) { - int len; - char *bin; - char *cin, *cout; - char cl, ch; - - len = strlen(args); - bin = xmalloc((len >> 1) + 1); - - cin = (char *)args; - cout = bin; - - cl = 0x10; - while (*cin) { - char c = *cin++; - - if (c == '\0') break; - else if ((c >= 'A') && (c <= 'F')) c -= 'A' - 10; - else if ((c >= 'a') && (c <= 'f')) c -= 'a' - 10; - else if ((c >= '0') && (c <= '9')) c -= '0'; - else continue; - - if (cl == 0x10) cl = c; - else { - ch = (cl << 4) | c; - *cout++ = ch; - cl = 0x10; - } - } - xmlbin = bin; - xmlbinsize = (cout - bin); + int len; + char *bin; + char *cin, *cout; + char cl, ch; + + len = strlen(args); + bin = xmalloc((len >> 1) + 1); + + cin = (char *)args; + cout = bin; + + cl = 0x10; + while (*cin) { + char c = *cin++; + + if (c == '\0') { + break; + } else if ((c >= 'A') && (c <= 'F')) { + c -= 'A' - 10; + } else if ((c >= 'a') && (c <= 'f')) { + c -= 'a' - 10; + } else if ((c >= '0') && (c <= '9')) { + c -= '0'; + } else { + continue; + } + + if (cl == 0x10) { + cl = c; + } else { + ch = (cl << 4) | c; + *cout++ = ch; + cl = 0x10; + } + } + xmlbin = bin; + xmlbinsize = (cout - bin); } #endif @@ -196,332 +205,357 @@ tlog3a_xgcb_data(const char *args, const char **unused) static void tlog3b_xgcb_tfna(const char *args, const char **unused) { - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - xmltrk->rte_name = strdup(args); + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_name = strdup(args); } static void tlog3b_xgcb_tfdes(const char *args, const char **unused) { - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - xmltrk->rte_desc = strdup(args); + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + xmltrk->rte_desc = strdup(args); } static void tlog3b_xgcb_wptst(const char *args, const char **unused) { - xmlwpt = waypt_new(); - xmldatum = DATUM_WGS84; + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; } static void tlog3b_xgcb_tptst(const char *args, const char **unused) { - xmlwpt = waypt_new(); - xmldatum = DATUM_WGS84; + xmlwpt = waypt_new(); + xmldatum = DATUM_WGS84; } static void tlog3b_xgcb_tpten(const char *args, const char **unused) { - finalize_pt(xmlwpt); - - if (xmltrk == NULL) { - xmltrk = route_head_alloc(); - track_add_head(xmltrk); - } - track_add_wpt(xmltrk, xmlwpt); - xmlwpt = NULL; + finalize_pt(xmlwpt); + + if (xmltrk == NULL) { + xmltrk = route_head_alloc(); + track_add_head(xmltrk); + } + track_add_wpt(xmltrk, xmlwpt); + xmlwpt = NULL; } static void tlog3b_xgcb_wptid(const char *args, const char **unused) { - if (*args) - xmlwpt->shortname = xstrdup(args); + if (*args) { + xmlwpt->shortname = xstrdup(args); + } } static void tlog3b_xgcb_wptdt(const char *args, const char **unused) { - xmldatum = GPS_Lookup_Datum_Index(args); + xmldatum = GPS_Lookup_Datum_Index(args); } static void tlog3b_xgcb_wptgr(const char *args, const char **unused) { - if (xmlgrid != NULL) { - if (strcmp(xmlgrid, args) == 0) return; - xfree(xmlgrid); - } - xmlgrid = xstrdup(args); + if (xmlgrid != NULL) { + if (strcmp(xmlgrid, args) == 0) { + return; + } + xfree(xmlgrid); + } + xmlgrid = xstrdup(args); } static void tlog3b_xgcb_wptno(const char *args, const char **unused) { - xmlNorthing = atof(args); + xmlNorthing = atof(args); } static void tlog3b_xgcb_wptea(const char *args, const char **unused) { - xmlEasting = atof(args); + xmlEasting = atof(args); } static void tlog3b_xgcb_wptal(const char *args, const char **unused) { - xmlAltitude = atof(args); + xmlAltitude = atof(args); } static void tlog3b_xgcb_tptdt(const char *args, const char **unused) { - xmldatum = GPS_Lookup_Datum_Index(args); + xmldatum = GPS_Lookup_Datum_Index(args); } static void tlog3b_xgcb_wpten(const char *args, const char **unused) { - finalize_pt(xmlwpt); - waypt_add(xmlwpt); - xmlwpt = NULL; + finalize_pt(xmlwpt); + waypt_add(xmlwpt); + xmlwpt = NULL; } static char * read_str(gbfile *f) { - int i; - char *res; + int i; + char *res; - i = gbfgetc(f); - if (i == 0xff) i = gbfgetint16(f); - - res = xmalloc(i + 1); - res[i] = '\0'; - if (i) gbfread(res, 1, i, f); - - return res; + i = gbfgetc(f); + if (i == 0xff) { + i = gbfgetint16(f); + } + + res = xmalloc(i + 1); + res[i] = '\0'; + if (i) { + gbfread(res, 1, i, f); + } + + return res; } static void write_str(const char *str, gbfile *f) { - if (str && *str) { - int len = strlen(str); - if (len > 0xfe) { + if (str && *str) { + int len = strlen(str); + if (len > 0xfe) { #if 0 - if (len > 0x7fff) len = 0x7fff; - gbfputc((unsigned char) 0xff, f); - gbfputint16(len, f); + if (len > 0x7fff) { + len = 0x7fff; + } + gbfputc((unsigned char) 0xff, f); + gbfputint16(len, f); #else - len = 0xfe; - gbfputc(len, f); + len = 0xfe; + gbfputc(len, f); #endif - } - else gbfputc(len, f); - gbfwrite(str, len, 1, f); - } - else gbfputc(0, f); + } else { + gbfputc(len, f); + } + gbfwrite(str, len, 1, f); + } else { + gbfputc(0, f); + } } static int read_datum(gbfile *f) { - int res; - char *d, *g; - - d = read_str(f); - g = read_str(f); - - res = GPS_Lookup_Datum_Index(d); - - if (*g && (strcmp(d, g) != 0)) { - fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", - d, g); - } - xfree(d); - xfree(g); - - return res; + int res; + char *d, *g; + + d = read_str(f); + g = read_str(f); + + res = GPS_Lookup_Datum_Index(d); + + if (*g && (strcmp(d, g) != 0)) { + fatal(MYNAME ": Unsupported combination of datum '%s' and grid '%s'!\n", + d, g); + } + xfree(d); + xfree(g); + + return res; } static void read_CTrackFile(const int version) { - char buf[128]; - gbuint32 ver; - gbint32 tcount, wcount; - gbint16 u1; - gbint32 ux; - route_head *track; - int i; - int datum; - - u1 = gbfgetint16(fin); - - gbfread(buf, 1, 10, fin); - if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) - fatal(MYNAME ": Unknown or invalid track file.\n"); - - if (version == 8) - gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ - - ver = gbfgetint32(fin); - if (ver != version) - fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); - - ux = gbfgetint32(fin); // Unknown 2 - ux = gbfgetint32(fin); // Unknown 3 - ux = gbfgetint32(fin); // Unknown 4 - - track = route_head_alloc(); - track_add_head(track); - - /* S1 .. S9: comments, hints, jokes, aso */ - for (i = 0; i < 9; i++) { - char *s = read_str(fin); - xfree(s); - } - - tcount = gbfgetint32(fin); - if (tcount > 0) { - datum = read_datum(fin); - if (version == 8) { - int len; - - gbfread(buf, 1, 4, fin); - len = gbfgetint16(fin); - gbfseek(fin, len, SEEK_CUR); - } - } - - while (tcount > 0) - { - waypoint *wpt; - - tcount--; - - if (version == 8) - datum = read_datum(fin); - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - convert_datum(wpt, datum); - - track_add_wpt(track, wpt); - - if (version == 8) - gbfseek(fin, 34, SEEK_CUR); /* skip unknown 34 bytes */ - } - - if (version == 8) { - - i = gbfgetint16(fin); - i = gbfgetc(fin); - if (i == 0) return; - - gbfungetc(i, fin); - datum = read_datum(fin); - - (void) gbfgetint16(fin); - (void) gbfgetint32(fin); - - gbfread(buf, 1, 9, fin); - if (strncmp(buf, "CWayPoint", 9) != 0) { - warning(MYNAME ": Unsupported waypoint structure!\n"); - return; - } - - while (! gbfeof(fin)) { - waypoint *wpt; - - i = gbfgetc(fin); - if (i == 0) break; - - gbfungetc(i, fin); - datum = read_datum(fin); - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ - - wpt->notes = read_str(fin); - wpt->description = read_str(fin); - (void) gbfgetint16(fin); - - waypt_add(wpt); - } - return; - } - - wcount = gbfgetint32(fin); - if (wcount == 0) return; - - datum = read_datum(fin); - - while (wcount > 0) { - waypoint *wpt; - gbint32 namect, i; - - wcount--; - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - wpt->altitude = gbfgetdbl(fin); - - convert_datum(wpt, datum); - - namect = gbfgetint32(fin); - - // variants of shortname - - for (i = 0; i < namect; i++) { - char *name; - - name = read_str(fin); - if (name && *name) { - switch(i) { - case 0: wpt->description = xstrdup(name); break; - case 1: wpt->shortname = xstrdup(name); break; - } - } - xfree(name); - } - - waypt_add(wpt); - } + char buf[128]; + gbuint32 ver; + gbint32 tcount, wcount; + gbint16 u1; + gbint32 ux; + route_head *track; + int i; + int datum; + + u1 = gbfgetint16(fin); + + gbfread(buf, 1, 10, fin); + if ((u1 != 0x0a) || (strncmp("CTrackFile", buf, 10) != 0)) { + fatal(MYNAME ": Unknown or invalid track file.\n"); + } + + if (version == 8) { + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + } + + ver = gbfgetint32(fin); + if (ver != version) { + fatal(MYNAME ": Unknown or invalid track file (%d).\n", ver); + } + + ux = gbfgetint32(fin); // Unknown 2 + ux = gbfgetint32(fin); // Unknown 3 + ux = gbfgetint32(fin); // Unknown 4 + + track = route_head_alloc(); + track_add_head(track); + + /* S1 .. S9: comments, hints, jokes, aso */ + for (i = 0; i < 9; i++) { + char *s = read_str(fin); + xfree(s); + } + + tcount = gbfgetint32(fin); + if (tcount > 0) { + datum = read_datum(fin); + if (version == 8) { + int len; + + gbfread(buf, 1, 4, fin); + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); + } + } + + while (tcount > 0) { + waypoint *wpt; + + tcount--; + + if (version == 8) { + datum = read_datum(fin); + } + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + track_add_wpt(track, wpt); + + if (version == 8) { + gbfseek(fin, 34, SEEK_CUR); /* skip unknown 34 bytes */ + } + } + + if (version == 8) { + + i = gbfgetint16(fin); + i = gbfgetc(fin); + if (i == 0) { + return; + } + + gbfungetc(i, fin); + datum = read_datum(fin); + + (void) gbfgetint16(fin); + (void) gbfgetint32(fin); + + gbfread(buf, 1, 9, fin); + if (strncmp(buf, "CWayPoint", 9) != 0) { + warning(MYNAME ": Unsupported waypoint structure!\n"); + return; + } + + while (! gbfeof(fin)) { + waypoint *wpt; + + i = gbfgetc(fin); + if (i == 0) { + break; + } + + gbfungetc(i, fin); + datum = read_datum(fin); + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + gbfseek(fin, 36, SEEK_CUR); /* skip unknown 36 bytes */ + + wpt->notes = read_str(fin); + wpt->description = read_str(fin); + (void) gbfgetint16(fin); + + waypt_add(wpt); + } + return; + } + + wcount = gbfgetint32(fin); + if (wcount == 0) { + return; + } + + datum = read_datum(fin); + + while (wcount > 0) { + waypoint *wpt; + gbint32 namect, i; + + wcount--; + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + wpt->altitude = gbfgetdbl(fin); + + convert_datum(wpt, datum); + + namect = gbfgetint32(fin); + + // variants of shortname + + for (i = 0; i < namect; i++) { + char *name; + + name = read_str(fin); + if (name && *name) { + switch (i) { + case 0: + wpt->description = xstrdup(name); + break; + case 1: + wpt->shortname = xstrdup(name); + break; + } + } + xfree(name); + } + + waypt_add(wpt); + } } @@ -530,75 +564,75 @@ read_CTrackFile(const int version) static int inflate_buff(const char *buff, const size_t size, char **out_buff) { - int res = Z_OK; - z_stream strm; - char out[DEFLATE_BUFF_SIZE]; - char *cout = NULL; - gbuint32 bytes = 0; - gbuint32 have; - - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = 0; - strm.next_in = Z_NULL; - - res = inflateInit(&strm); - if (res != Z_OK) { - return res; - } - - strm.avail_in = size; - strm.next_in = (void *)buff; - - do { - strm.avail_out = DEFLATE_BUFF_SIZE; - strm.next_out = (void *)out; - res = inflate(&strm, Z_NO_FLUSH); - - switch (res) { - case Z_NEED_DICT: - res = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return res; - } - have = DEFLATE_BUFF_SIZE - strm.avail_out; - if (have > 0) { - cout = xrealloc(cout, bytes + have); - memcpy(cout+bytes, out, have); - bytes+=have; - } - } while (strm.avail_out == 0); - - *out_buff = cout; - return res; + int res = Z_OK; + z_stream strm; + char out[DEFLATE_BUFF_SIZE]; + char *cout = NULL; + gbuint32 bytes = 0; + gbuint32 have; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + + res = inflateInit(&strm); + if (res != Z_OK) { + return res; + } + + strm.avail_in = size; + strm.next_in = (void *)buff; + + do { + strm.avail_out = DEFLATE_BUFF_SIZE; + strm.next_out = (void *)out; + res = inflate(&strm, Z_NO_FLUSH); + + switch (res) { + case Z_NEED_DICT: + res = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return res; + } + have = DEFLATE_BUFF_SIZE - strm.avail_out; + if (have > 0) { + cout = xrealloc(cout, bytes + have); + memcpy(cout+bytes, out, have); + bytes+=have; + } + } while (strm.avail_out == 0); + + *out_buff = cout; + return res; } static void read_CXMLSafe(void) { - char *xmlstr = NULL; - - xmlbin = NULL; - xmlbinsize = 0; - - xml_init(fin->name, tlog3a_xgcb_map, NULL); - xml_read(); - xml_deinit(); - - if (xmlbin != NULL) { - inflate_buff(xmlbin, xmlbinsize, &xmlstr); - xfree(xmlbin); - - xml_init(NULL, tlog3b_xgcb_map, NULL); - xml_readstring(xmlstr); - xml_deinit(); - - xfree(xmlstr); - } + char *xmlstr = NULL; + + xmlbin = NULL; + xmlbinsize = 0; + + xml_init(fin->name, tlog3a_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + if (xmlbin != NULL) { + inflate_buff(xmlbin, xmlbinsize, &xmlstr); + xfree(xmlbin); + + xml_init(NULL, tlog3b_xgcb_map, NULL); + xml_readstring(xmlstr); + xml_deinit(); + + xfree(xmlstr); + } } #endif @@ -606,11 +640,11 @@ read_CXMLSafe(void) static void read_XML(void) { - xml_init(fin->name, tlog3b_xgcb_map, NULL); - xml_read(); - xml_deinit(); - - return; + xml_init(fin->name, tlog3b_xgcb_map, NULL); + xml_read(); + xml_deinit(); + + return; } /******************************************************************************* @@ -620,98 +654,104 @@ read_XML(void) static void dmtlog_rd_init(const char *fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - - xmlbin = NULL; - xmltrk = NULL; - xmlwpt = NULL; - xmlgrid = NULL; + fin = gbfopen_le(fname, "rb", MYNAME); + + xmlbin = NULL; + xmltrk = NULL; + xmlwpt = NULL; + xmlgrid = NULL; } -static void +static void dmtlog_rd_deinit(void) { - gbfclose(fin); - if (xmlgrid != NULL) xfree(xmlgrid); + gbfclose(fin); + if (xmlgrid != NULL) { + xfree(xmlgrid); + } } static void dmtlog_read(void) { - switch(gbfgetuint32(fin)) { - - case 0x4FFFF: - read_CTrackFile(4); - break; - - case 0x8FFFF: - read_CTrackFile(8); - break; - - case 0x4d58433c: + switch (gbfgetuint32(fin)) { + + case 0x4FFFF: + read_CTrackFile(4); + break; + + case 0x8FFFF: + read_CTrackFile(8); + break; + + case 0x4d58433c: #if !ZLIB_INHIBITED - read_CXMLSafe(); + read_CXMLSafe(); #else - fatal(MYNAME ": Zlib was not included in this build.\n"); -#endif - break; - case 0x7254433c: - read_XML(); - break; + fatal(MYNAME ": Zlib was not included in this build.\n"); +#endif + break; + case 0x7254433c: + read_XML(); + break; - default: - fatal(MYNAME ": Unknown or unsupported file type.\n"); - } + default: + fatal(MYNAME ": Unknown or unsupported file type.\n"); + } } static void dmtlog_wr_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void dmtlog_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void write_header(const route_head *trk) { - int count, i; - char *cout; - const char ZERO = '\0'; - - header_written = 1; - - count = 0; - if (trk != NULL) { - queue *curr, *prev; - QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; - } - write_str(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); - - xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); - write_str(cout, fout); - xfree(cout); - - for (i = 3; i <= 8; i++) gbfputc(ZERO, fout); - write_str("GPSBabel", fout); - gbfputint32(count, fout); - if (count > 0) { - write_str("WGS84", fout); - write_str("WGS84", fout); - } + int count, i; + char *cout; + const char ZERO = '\0'; + + header_written = 1; + + count = 0; + if (trk != NULL) { + queue *curr, *prev; + QUEUE_FOR_EACH(&trk->waypoint_list, curr, prev) count++; + } + write_str(trk && trk->rte_name && *trk->rte_name ? trk->rte_name : "Name", fout); + + xasprintf(&cout, "%d trackpoints and %d waypoints", count, waypt_count()); + write_str(cout, fout); + xfree(cout); + + for (i = 3; i <= 8; i++) { + gbfputc(ZERO, fout); + } + write_str("GPSBabel", fout); + gbfputint32(count, fout); + if (count > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + } } static void track_hdr_cb(const route_head *trk) { - - this_index++; - if (this_index != track_index) return; - write_header(trk); + + this_index++; + if (this_index != track_index) { + return; + } + write_header(trk); } static void @@ -722,74 +762,81 @@ track_tlr_cb(const route_head *trk) static void track_wpt_cb(const waypoint *wpt) { - if (this_index != track_index) return; - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); + if (this_index != track_index) { + return; + } + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); } static void wpt_cb(const waypoint *wpt) { - int names; - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); - - names = 1; - if (wpt->description && *wpt->description) names = 2; - gbfputint32(names, fout); - if (names > 1) write_str(wpt->description, fout); - write_str(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); + int names; + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputdbl(wpt->altitude != unknown_alt ? wpt->altitude : 0, fout); + + names = 1; + if (wpt->description && *wpt->description) { + names = 2; + } + gbfputint32(names, fout); + if (names > 1) { + write_str(wpt->description, fout); + } + write_str(wpt->shortname && *wpt->shortname ? wpt->shortname : "Name", fout); } static void dmtlog_write(void) { - track_index = atoi(opt_index); - /* ... validate index */ - - gbfputint32(0x4FFFF, fout); - gbfputuint16(0x0A, fout); - gbfputs("CTrackFile", fout); - gbfputint32(4, fout); - gbfputint32(1, fout); - gbfputint32(0x100001, fout); - gbfputuint32((const gbuint32)gpsbabel_time, fout); - - header_written = 0; - this_index = 0; - track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); - if (!header_written) - write_header(NULL); - gbfputint32(waypt_count(), fout); - if (waypt_count() > 0) { - write_str("WGS84", fout); - write_str("WGS84", fout); - waypt_disp_all(wpt_cb); - } + track_index = atoi(opt_index); + /* ... validate index */ + + gbfputint32(0x4FFFF, fout); + gbfputuint16(0x0A, fout); + gbfputs("CTrackFile", fout); + gbfputint32(4, fout); + gbfputint32(1, fout); + gbfputint32(0x100001, fout); + gbfputuint32((const gbuint32)gpsbabel_time, fout); + + header_written = 0; + this_index = 0; + track_disp_all(track_hdr_cb, track_tlr_cb, track_wpt_cb); + if (!header_written) { + write_header(NULL); + } + gbfputint32(waypt_count(), fout); + if (waypt_count() > 0) { + write_str("WGS84", fout); + write_str("WGS84", fout); + waypt_disp_all(wpt_cb); + } } /**************************************************************************/ ff_vecs_t dmtlog_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - dmtlog_rd_init, - dmtlog_wr_init, - dmtlog_rd_deinit, - dmtlog_wr_deinit, - dmtlog_read, - dmtlog_write, - NULL, - dmtlog_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + dmtlog_rd_init, + dmtlog_wr_init, + dmtlog_rd_deinit, + dmtlog_wr_deinit, + dmtlog_read, + dmtlog_write, + NULL, + dmtlog_args, + CET_CHARSET_ASCII, 0 }; diff --git a/gpsbabel/duplicate.c b/gpsbabel/duplicate.c index 1043faf5d..117717303 100644 --- a/gpsbabel/duplicate.c +++ b/gpsbabel/duplicate.c @@ -30,78 +30,89 @@ static char *correct_coords = NULL; static arglist_t dup_args[] = { - {"shortname", &snopt, "Suppress duplicate waypoints based on name", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"location", &lcopt, "Suppress duplicate waypoint based on coords", - NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"all", &purge_duplicates, "Suppress all instances of duplicates", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"correct", &correct_coords, "Use coords from duplicate points", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "shortname", &snopt, "Suppress duplicate waypoints based on name", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "location", &lcopt, "Suppress duplicate waypoint based on coords", + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "all", &purge_duplicates, "Suppress all instances of duplicates", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "correct", &correct_coords, "Use coords from duplicate points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct btree_node { - struct btree_node *left, *right; - unsigned long data; - waypoint *wpt; + struct btree_node *left, *right; + unsigned long data; + waypoint *wpt; } btree_node; static btree_node * -addnode (btree_node * tree, btree_node * newnode, btree_node **oldnode) +addnode(btree_node * tree, btree_node * newnode, btree_node **oldnode) { - btree_node * tmp, * last = NULL; - - if ( *oldnode ) {*oldnode = NULL;} - - if (!tree) - return (newnode); - - tmp = tree; - - while (tmp) { - last = tmp; - if (newnode->data < tmp->data) { - tmp = tmp->right; - } else if (newnode->data > tmp->data) { - tmp = tmp->left; - } else { - if ( oldnode ) { - *oldnode = tmp; - } - return (NULL); - } - } - - if (newnode->data < last->data) { - last->right = newnode; - } else { - last->left = newnode; - } - - return (tree); + btree_node * tmp, * last = NULL; + + if (*oldnode) { + *oldnode = NULL; + } + + if (!tree) { + return (newnode); + } + + tmp = tree; + + while (tmp) { + last = tmp; + if (newnode->data < tmp->data) { + tmp = tmp->right; + } else if (newnode->data > tmp->data) { + tmp = tmp->left; + } else { + if (oldnode) { + *oldnode = tmp; + } + return (NULL); + } + } + + if (newnode->data < last->data) { + last->right = newnode; + } else { + last->left = newnode; + } + + return (tree); } void -free_tree (btree_node *tree) +free_tree(btree_node *tree) { - if ( tree->left ) { - free_tree(tree->left); - } - if ( tree->right ) { - free_tree(tree->right); - } - xfree(tree); + if (tree->left) { + free_tree(tree->left); + } + if (tree->right) { + free_tree(tree->right); + } + xfree(tree); } typedef struct { - waypoint *wpt; - int index; + waypoint *wpt; + int index; } wpt_ptr; /* - + It looks odd that we have different comparisons for date and index. If exported if a < b return 1 if index if a < b return -1 @@ -138,24 +149,24 @@ static int compare(const void *a, const void *b) { - const wpt_ptr *wa = (wpt_ptr *)a; - const wpt_ptr *wb = (wpt_ptr *)b; + const wpt_ptr *wa = (wpt_ptr *)a; + const wpt_ptr *wb = (wpt_ptr *)b; - if ( wa->wpt->gc_data->exported < wb->wpt->gc_data->exported ) { - return 1; - } else if ( wa->wpt->gc_data->exported > wb->wpt->gc_data->exported ) { - return -1; - } + if (wa->wpt->gc_data->exported < wb->wpt->gc_data->exported) { + return 1; + } else if (wa->wpt->gc_data->exported > wb->wpt->gc_data->exported) { + return -1; + } - /* If the exported dates are the same, sort by index. */ - if ( wa->index < wb->index ) { - return -1; - } else if (wa->index > wb->index ) { - return 1; - } + /* If the exported dates are the same, sort by index. */ + if (wa->index < wb->index) { + return -1; + } else if (wa->index > wb->index) { + return 1; + } - /* If index and date are the same, it's the same element. */ - return 0; + /* If index and date are the same, it's the same element. */ + return 0; } @@ -163,98 +174,102 @@ compare(const void *a, const void *b) static void duplicate_process(void) { - waypoint * waypointp; - btree_node * newnode, * btmp, * sup_tree = NULL; - btree_node * oldnode = NULL; - unsigned long crc = 0; - struct { char shortname[32]; char lat[13]; char lon[13]; } dupe; - waypoint * delwpt = NULL; - - int i, ct = waypt_count(); - wpt_ptr *htable, *bh; - queue *elem, *tmp; - - htable = (wpt_ptr *) xmalloc(ct * sizeof(*htable)); - bh = htable; - - i = 0; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - bh->wpt = (waypoint *) elem; - bh->index = i; - i ++; - bh ++; - } - qsort(htable, ct, sizeof(*htable), compare); - - for (i=0;ishortname, sizeof(dupe.shortname) - 1); - } - - if (lcopt) { - /* let sprintf take care of rounding */ - sprintf(dupe.lat, "%11.4f", waypointp->latitude); - sprintf(dupe.lon, "%11.4f", waypointp->longitude); - /* The degrees2ddmm stuff is a feeble attempt to - * get everything rounded the same way in a precision - * that's "close enough" for determining duplicates. - */ - sprintf(dupe.lat, "%11.3f", degrees2ddmm(waypointp->latitude)); - sprintf(dupe.lon, "%11.3f", degrees2ddmm(waypointp->longitude)); - - } - - crc = get_crc32(&dupe, sizeof(dupe)); - - newnode = (btree_node *)xcalloc(sizeof(btree_node), 1); - newnode->data = crc; - newnode->wpt = waypointp; - - btmp = addnode(sup_tree, newnode, &oldnode ); - - if (btmp == NULL) { - if ( delwpt ) { - waypt_free(delwpt); - } - if ( correct_coords && oldnode && oldnode->wpt ) { - oldnode->wpt->latitude = waypointp->latitude; - oldnode->wpt->longitude = waypointp->longitude; - } - delwpt = waypointp; - waypt_del(waypointp); /* collision */ - xfree(newnode); - if ( purge_duplicates && oldnode ) { - if ( oldnode->wpt ) { - waypt_del( oldnode->wpt ); - waypt_free( oldnode->wpt ); - oldnode->wpt = NULL; - } - } - - } else { - sup_tree = btmp; - } - } - - if ( delwpt ) { - waypt_free(delwpt); - } - - xfree(htable); - if ( sup_tree ) { - free_tree(sup_tree); - } + waypoint * waypointp; + btree_node * newnode, * btmp, * sup_tree = NULL; + btree_node * oldnode = NULL; + unsigned long crc = 0; + struct { + char shortname[32]; + char lat[13]; + char lon[13]; + } dupe; + waypoint * delwpt = NULL; + + int i, ct = waypt_count(); + wpt_ptr *htable, *bh; + queue *elem, *tmp; + + htable = (wpt_ptr *) xmalloc(ct * sizeof(*htable)); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint *) elem; + bh->index = i; + i ++; + bh ++; + } + qsort(htable, ct, sizeof(*htable), compare); + + for (i=0; ishortname, sizeof(dupe.shortname) - 1); + } + + if (lcopt) { + /* let sprintf take care of rounding */ + sprintf(dupe.lat, "%11.4f", waypointp->latitude); + sprintf(dupe.lon, "%11.4f", waypointp->longitude); + /* The degrees2ddmm stuff is a feeble attempt to + * get everything rounded the same way in a precision + * that's "close enough" for determining duplicates. + */ + sprintf(dupe.lat, "%11.3f", degrees2ddmm(waypointp->latitude)); + sprintf(dupe.lon, "%11.3f", degrees2ddmm(waypointp->longitude)); + + } + + crc = get_crc32(&dupe, sizeof(dupe)); + + newnode = (btree_node *)xcalloc(sizeof(btree_node), 1); + newnode->data = crc; + newnode->wpt = waypointp; + + btmp = addnode(sup_tree, newnode, &oldnode); + + if (btmp == NULL) { + if (delwpt) { + waypt_free(delwpt); + } + if (correct_coords && oldnode && oldnode->wpt) { + oldnode->wpt->latitude = waypointp->latitude; + oldnode->wpt->longitude = waypointp->longitude; + } + delwpt = waypointp; + waypt_del(waypointp); /* collision */ + xfree(newnode); + if (purge_duplicates && oldnode) { + if (oldnode->wpt) { + waypt_del(oldnode->wpt); + waypt_free(oldnode->wpt); + oldnode->wpt = NULL; + } + } + + } else { + sup_tree = btmp; + } + } + + if (delwpt) { + waypt_free(delwpt); + } + + xfree(htable); + if (sup_tree) { + free_tree(sup_tree); + } } filter_vecs_t duplicate_vecs = { - NULL, - duplicate_process, - NULL, - NULL, - dup_args + NULL, + duplicate_process, + NULL, + NULL, + dup_args }; #endif diff --git a/gpsbabel/easygps.c b/gpsbabel/easygps.c index 2bc95850b..e9b71d2fb 100644 --- a/gpsbabel/easygps.c +++ b/gpsbabel/easygps.c @@ -31,185 +31,185 @@ static short_handle mkshort_handle; static arglist_t easygps_args[] = { -/* {"deficon", &deficon, "Default icon name", "Waypoint", - ARGTYPE_STRING}, */ - ARG_TERMINATOR + /* {"deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING}, */ + ARG_TERMINATOR }; static void rd_init(const char *fname) { - int sz; - char ibuf[100] = {'0'} ; - const char *ezsig = "TerraByte Location File"; - - file_in = gbfopen_le(fname, "rb", MYNAME); - - sz = gbfread(ibuf, 1, 52, file_in); - - if ((sz < 52) || - strncmp(ibuf, ezsig, sizeof(ezsig)-1) || - (ibuf[51] != 'W')) { - fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); - } + int sz; + char ibuf[100] = {'0'} ; + const char *ezsig = "TerraByte Location File"; + + file_in = gbfopen_le(fname, "rb", MYNAME); + + sz = gbfread(ibuf, 1, 52, file_in); + + if ((sz < 52) || + strncmp(ibuf, ezsig, sizeof(ezsig)-1) || + (ibuf[51] != 'W')) { + fatal(MYNAME ": %s is not an EasyGPS file.\n", fname); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - char p; - char ibuf[10]; - do { - unsigned char tag; - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { - switch (tag) { - case 1: - wpt_tmp->shortname = gbfgetpstr(file_in); - break; - case 2: - case 3: - wpt_tmp->description = gbfgetpstr(file_in);; - break; - case 5: - wpt_tmp->notes = gbfgetpstr(file_in);; - break; - case 6: - wpt_tmp->url_link_text = gbfgetpstr(file_in);; - break; - case 7: - wpt_tmp->icon_descr = gbfgetpstr(file_in);; - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 8: /* NULL Terminated (vs. pascal) descr */ - wpt_tmp->notes = gbfgetcstr(file_in); - break; - case 9: /* NULL Terminated (vs. pascal) link */ - wpt_tmp->url = gbfgetcstr(file_in); - break; - case 0x10: - wpt_tmp->url_link_text = gbfgetcstr(file_in); - break; - case 0x63: - wpt_tmp->latitude = gbfgetdbl(file_in); - break; - case 0x64: - wpt_tmp->longitude = gbfgetdbl(file_in); - break; - case 0x65: - case 0x66: - gbfread(ibuf, 8, 1, file_in); - break; - case 0x84: - case 0x85: - gbfread(ibuf, 4, 1, file_in); - break; - case 0x86: /* May be proximity. I think it's time. */ - gbfread(ibuf, 4, 1, file_in); - break; - default: - printf("Unknown tag %x\n", tag); - ; - } - } - waypt_add(wpt_tmp); - p = gbfgetc(file_in); - } while (!gbfeof(file_in) && (p == 'W')); + char p; + char ibuf[10]; + do { + unsigned char tag; + waypoint *wpt_tmp; + + wpt_tmp = waypt_new(); + + for (tag = gbfgetc(file_in); tag != 0xff; tag = gbfgetc(file_in)) { + switch (tag) { + case 1: + wpt_tmp->shortname = gbfgetpstr(file_in); + break; + case 2: + case 3: + wpt_tmp->description = gbfgetpstr(file_in);; + break; + case 5: + wpt_tmp->notes = gbfgetpstr(file_in);; + break; + case 6: + wpt_tmp->url_link_text = gbfgetpstr(file_in);; + break; + case 7: + wpt_tmp->icon_descr = gbfgetpstr(file_in);; + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 8: /* NULL Terminated (vs. pascal) descr */ + wpt_tmp->notes = gbfgetcstr(file_in); + break; + case 9: /* NULL Terminated (vs. pascal) link */ + wpt_tmp->url = gbfgetcstr(file_in); + break; + case 0x10: + wpt_tmp->url_link_text = gbfgetcstr(file_in); + break; + case 0x63: + wpt_tmp->latitude = gbfgetdbl(file_in); + break; + case 0x64: + wpt_tmp->longitude = gbfgetdbl(file_in); + break; + case 0x65: + case 0x66: + gbfread(ibuf, 8, 1, file_in); + break; + case 0x84: + case 0x85: + gbfread(ibuf, 4, 1, file_in); + break; + case 0x86: /* May be proximity. I think it's time. */ + gbfread(ibuf, 4, 1, file_in); + break; + default: + printf("Unknown tag %x\n", tag); + ; + } + } + waypt_add(wpt_tmp); + p = gbfgetc(file_in); + } while (!gbfeof(file_in) && (p == 'W')); } static void ez_disp(const waypoint *wpt) { - gbfputc('W', file_out); - - if (wpt->shortname) { - gbfputc(1, file_out); - gbfputpstr(wpt->shortname, file_out); - } - if (wpt->description) { - gbfputc(3, file_out); - gbfputpstr(wpt->description, file_out); - } - if (wpt->icon_descr) { - gbfputc(7, file_out); - gbfputpstr(wpt->icon_descr, file_out); - } - gbfputc(0x63, file_out); - gbfputdbl(wpt->latitude, file_out); - - gbfputc(0x64, file_out); - gbfputdbl(wpt->longitude, file_out); - - if (wpt->notes) { - gbfputc(5, file_out); - gbfputpstr(wpt->notes, file_out); - } - if (wpt->url_link_text) { - gbfputc(6, file_out); - gbfputpstr(wpt->url_link_text, file_out); - } - if (1 && wpt->url) { - gbfputc(9, file_out); - gbfputcstr(wpt->url, file_out); - } - gbfputc(0xff, file_out); + gbfputc('W', file_out); + + if (wpt->shortname) { + gbfputc(1, file_out); + gbfputpstr(wpt->shortname, file_out); + } + if (wpt->description) { + gbfputc(3, file_out); + gbfputpstr(wpt->description, file_out); + } + if (wpt->icon_descr) { + gbfputc(7, file_out); + gbfputpstr(wpt->icon_descr, file_out); + } + gbfputc(0x63, file_out); + gbfputdbl(wpt->latitude, file_out); + + gbfputc(0x64, file_out); + gbfputdbl(wpt->longitude, file_out); + + if (wpt->notes) { + gbfputc(5, file_out); + gbfputpstr(wpt->notes, file_out); + } + if (wpt->url_link_text) { + gbfputc(6, file_out); + gbfputpstr(wpt->url_link_text, file_out); + } + if (1 && wpt->url) { + gbfputc(9, file_out); + gbfputcstr(wpt->url, file_out); + } + gbfputc(0xff, file_out); } static void data_write(void) { - setshort_length(mkshort_handle, 6); + setshort_length(mkshort_handle, 6); - gbfprintf(file_out, - "TerraByte Location File Copyright 2001 TopoGrafix\n"); - /* - * I don't know what this is. - */ - gbfprintf(file_out, "%c", 0xb); + gbfprintf(file_out, + "TerraByte Location File Copyright 2001 TopoGrafix\n"); + /* + * I don't know what this is. + */ + gbfprintf(file_out, "%c", 0xb); - waypt_disp_all(ez_disp); + waypt_disp_all(ez_disp); - /* - * Files seem to always end in a zero. - */ - gbfputc(0x00, file_out); + /* + * Files seem to always end in a zero. + */ + gbfputc(0x00, file_out); } ff_vecs_t easygps_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - easygps_args, - CET_CHARSET_ASCII, 0 /* CET REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + easygps_args, + CET_CHARSET_ASCII, 0 /* CET REVIEW */ }; diff --git a/gpsbabel/enigma.c b/gpsbabel/enigma.c index fd006715f..7b408f9ce 100755 --- a/gpsbabel/enigma.c +++ b/gpsbabel/enigma.c @@ -54,21 +54,21 @@ #define WTYPE_ALTITUDECHANGE 26 // Location at which altitude should be changed union wpt_data { - gbint32 wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet - gbint32 tg_altitude; // Waypoint type 26: target altitude in feet - gbuint32 frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000) - gbint32 dummy; // waypoint type 7, unused + gbint32 wp_altitude; // Waypoint type 0-6,8: waypoint altitude in feet + gbint32 tg_altitude; // Waypoint type 26: target altitude in feet + gbuint32 frequency; // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000) + gbint32 dummy; // waypoint type 7, unused }; typedef struct enigma_wpt { - gbint32 latitude; - gbint32 longitude; - union wpt_data data; - gbuint8 waypoint_type; - gbuint8 shortname_len; - char shortname[6]; - gbuint8 longname_len; - char longname[27]; + gbint32 latitude; + gbint32 longitude; + union wpt_data data; + gbuint8 waypoint_type; + gbuint8 shortname_len; + char shortname[6]; + gbuint8 longname_len; + char longname[27]; } ENIGMA_WPT; static gbfile *file_in, *file_out; @@ -76,80 +76,79 @@ static gbfile *file_in, *file_out; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } -gbint32 decToEnigmaPosition (double val) +gbint32 decToEnigmaPosition(double val) { - int degrees = fabs(val); - double frac = fabs(val) - degrees; - int enigmadeg = degrees * 180000; - int enigmafrac = 180000 * frac; - int sign = (val < 0) ? -1 : +1; - return sign * (enigmadeg + enigmafrac); + int degrees = fabs(val); + double frac = fabs(val) - degrees; + int enigmadeg = degrees * 180000; + int enigmafrac = 180000 * frac; + int sign = (val < 0) ? -1 : +1; + return sign * (enigmadeg + enigmafrac); } -float enigmaPositionToDec (gbint32 val) +float enigmaPositionToDec(gbint32 val) { - int deg = abs(val) / 180000; - int enigmafrac = abs(val) % 180000; - double frac = (double)enigmafrac / 180000; - int sign = (val < 0) ? -1 : +1; - return sign * (deg + frac); + int deg = abs(val) / 180000; + int enigmafrac = abs(val) % 180000; + double frac = (double)enigmafrac / 180000; + int sign = (val < 0) ? -1 : +1; + return sign * (deg + frac); } static void data_read(void) { - struct enigma_wpt ewpt; - route_head *route = route_head_alloc(); - route_add_head (route); - - while (1 == gbfread(&ewpt, sizeof (ewpt), 1, file_in)) { - waypoint *wpt = waypt_new(); - wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude)); - wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude)); - wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len); - wpt->description = xstrndup(ewpt.longname, ewpt.longname_len); - switch (ewpt.waypoint_type) - { - case WTYPE_WAYPOINT: // 0 - case WTYPE_AIRPORT: // 1 - case WTYPE_MAJORAIRPORT: // 2 - case WTYPE_SEAPLANEBASE: // 3 - case WTYPE_AIRFIELD: // 4 - case WTYPE_PRIVATEAIRFIELD: // 5 - case WTYPE_ULTRALIGHTFIELD: // 6 - case WTYPE_HELIPORT: // 8 - // waypoint altitude - wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000); - break; - case WTYPE_ALTITUDECHANGE: // 26 - // target altitude - wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000); - break; - case WTYPE_INTERSECTION: // 7 - // unused - break; - default: - // frequency - // wpt->frequency = wpt.le_readu32(ewpt.data.frequency); - ; - } - route_add_wpt(route, wpt); - } + struct enigma_wpt ewpt; + route_head *route = route_head_alloc(); + route_add_head(route); + + while (1 == gbfread(&ewpt, sizeof(ewpt), 1, file_in)) { + waypoint *wpt = waypt_new(); + wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude)); + wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude)); + wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len); + wpt->description = xstrndup(ewpt.longname, ewpt.longname_len); + switch (ewpt.waypoint_type) { + case WTYPE_WAYPOINT: // 0 + case WTYPE_AIRPORT: // 1 + case WTYPE_MAJORAIRPORT: // 2 + case WTYPE_SEAPLANEBASE: // 3 + case WTYPE_AIRFIELD: // 4 + case WTYPE_PRIVATEAIRFIELD: // 5 + case WTYPE_ULTRALIGHTFIELD: // 6 + case WTYPE_HELIPORT: // 8 + // waypoint altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000); + break; + case WTYPE_ALTITUDECHANGE: // 26 + // target altitude + wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000); + break; + case WTYPE_INTERSECTION: // 7 + // unused + break; + default: + // frequency + // wpt->frequency = wpt.le_readu32(ewpt.data.frequency); + ; + } + route_add_wpt(route, wpt); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } static void @@ -167,54 +166,53 @@ route_head_noop(const route_head *wp) static void enigma_waypt_disp(const waypoint *wpt) { - struct enigma_wpt ewpt; - - memset (&ewpt, 0, sizeof (ewpt)); - - le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude)); - le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude)); - ewpt.waypoint_type = WTYPE_WAYPOINT; - if (wpt->altitude != unknown_alt) - le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000); - if (wpt->shortname != NULL) - { - ewpt.shortname_len = min (6, strlen (wpt->shortname)); - strncpy(ewpt.shortname, wpt->shortname, 6); - } - if (wpt->description != NULL) - { - ewpt.longname_len = min (27, strlen (wpt->description)); - strncpy(ewpt.longname, wpt->description, 27); - } - gbfwrite(&ewpt, sizeof (ewpt), 1, file_out); + struct enigma_wpt ewpt; + + memset(&ewpt, 0, sizeof(ewpt)); + + le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude)); + le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude)); + ewpt.waypoint_type = WTYPE_WAYPOINT; + if (wpt->altitude != unknown_alt) { + le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000); + } + if (wpt->shortname != NULL) { + ewpt.shortname_len = min(6, strlen(wpt->shortname)); + strncpy(ewpt.shortname, wpt->shortname, 6); + } + if (wpt->description != NULL) { + ewpt.longname_len = min(27, strlen(wpt->description)); + strncpy(ewpt.longname, wpt->description, 27); + } + gbfwrite(&ewpt, sizeof(ewpt), 1, file_out); } static void data_write(void) { - route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp); + route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp); } static void wr_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } ff_vecs_t enigma_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_read | ff_cap_write /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_read | ff_cap_write /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/exif.c b/gpsbabel/exif.c index 29d0004c2..30d196279 100644 --- a/gpsbabel/exif.c +++ b/gpsbabel/exif.c @@ -93,35 +93,35 @@ #define GPS_IFD_TAG_DATESTAMP 0x001D typedef struct exif_tag_s { - queue Q; - gbuint16 id; - gbuint16 type; - gbuint32 count; - gbuint32 value; - gbuint32 origin; - gbuint32 size; + queue Q; + gbuint16 id; + gbuint16 type; + gbuint32 count; + gbuint32 value; + gbuint32 origin; + gbuint32 size; #ifdef EXIF_DBG - gbuint32 offs; + gbuint32 offs; #endif - unsigned char data_is_dynamic:1; - void *data; + unsigned char data_is_dynamic:1; + void *data; } exif_tag_t; typedef struct exif_ifd_s { - queue Q; - gbuint32 next_ifd; - gbuint16 nr; - gbuint16 count; - queue tags; + queue Q; + gbuint32 next_ifd; + gbuint16 nr; + gbuint16 count; + queue tags; } exif_ifd_t, *exif_ifd_p; typedef struct exif_app_s { - queue Q; - gbuint16 marker; - gbsize_t len; - gbfile *fcache; - gbfile *fexif; - queue ifds; + queue Q; + gbuint16 marker; + gbsize_t len; + gbfile *fcache; + gbfile *fexif; + queue ifds; } exif_app_t; static gbfile *fin, *fout; @@ -135,1028 +135,1189 @@ static char *exif_fout_name; static char *opt_filename, *opt_overwrite, *opt_frame, *opt_name; arglist_t exif_args[] = { - { "filename", &opt_filename, "Set waypoint name to source filename", "Y", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "frame", &opt_frame, "Time-frame (in seconds)", "10", ARGTYPE_INT, "0", NULL }, - { "name", &opt_name, "Locate waypoint for tagging by this name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "overwrite", &opt_overwrite, "!OVERWRITE! the original file. Default=N", "N", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { "filename", &opt_filename, "Set waypoint name to source filename", "Y", ARGTYPE_BOOL, ARG_NOMINMAX }, + { "frame", &opt_frame, "Time-frame (in seconds)", "10", ARGTYPE_INT, "0", NULL }, + { "name", &opt_name, "Locate waypoint for tagging by this name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "overwrite", &opt_overwrite, "!OVERWRITE! the original file. Default=N", "N", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #ifdef EXIF_DBG static void print_buff(const char *buf, int sz, const char *cmt) { - int i; - - printf("%s: ", cmt); - for (i = 0; i < sz; i++) - printf("%02x ", buf[i] & 0xFF); - for (i = 0; i < sz; i++) { - char c = buf[i]; - if (isspace(c)) c = ' '; - else if (! isprint(c)) c = '.'; - printf("%c", c); - } + int i; + + printf("%s: ", cmt); + for (i = 0; i < sz; i++) { + printf("%02x ", buf[i] & 0xFF); + } + for (i = 0; i < sz; i++) { + char c = buf[i]; + if (isspace(c)) { + c = ' '; + } else if (! isprint(c)) { + c = '.'; + } + printf("%c", c); + } } #endif static gbuint16 exif_type_size(const gbuint16 type) { - gbuint16 size; - - switch(type) { - case EXIF_TYPE_BYTE: - case EXIF_TYPE_ASCII: - case EXIF_TYPE_UNK: size = 1; break; - - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - case EXIF_TYPE_UNICODE: size = 2; break; - case EXIF_TYPE_IFD: - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - case EXIF_TYPE_FLOAT: size = 4; break; - - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - case EXIF_TYPE_DOUBLE: - case EXIF_TYPE_LONG8: - case EXIF_TYPE_SLONG8: - case EXIF_TYPE_IFD8: size = 8; break; - - default: - fatal(MYNAME ": Unknown data type %d! Please report.\n", type); - } - return size; + gbuint16 size; + + switch (type) { + case EXIF_TYPE_BYTE: + case EXIF_TYPE_ASCII: + case EXIF_TYPE_UNK: + size = 1; + break; + + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + case EXIF_TYPE_UNICODE: + size = 2; + break; + case EXIF_TYPE_IFD: + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + case EXIF_TYPE_FLOAT: + size = 4; + break; + + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + case EXIF_TYPE_DOUBLE: + case EXIF_TYPE_LONG8: + case EXIF_TYPE_SLONG8: + case EXIF_TYPE_IFD8: + size = 8; + break; + + default: + fatal(MYNAME ": Unknown data type %d! Please report.\n", type); + } + return size; } static char * exif_time_str(const time_t time) { - struct tm tm; - char *res; + struct tm tm; + char *res; - tm = *localtime(&time); - tm.tm_year += 1900; - tm.tm_mon += 1; - xasprintf(&res, "%04d/%02d/%02d, %02d:%02d:%02d", - tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + tm = *localtime(&time); + tm.tm_year += 1900; + tm.tm_mon += 1; + xasprintf(&res, "%04d/%02d/%02d, %02d:%02d:%02d", + tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - return res; + return res; } static char * exif_read_str(exif_tag_t *tag) { - // Panasonic DMC-TZ10 stores datum with trailing spaces. - char *buf = xstrndup((char *)tag->data, tag->size); - rtrim (buf); - return buf; + // Panasonic DMC-TZ10 stores datum with trailing spaces. + char *buf = xstrndup((char *)tag->data, tag->size); + rtrim(buf); + return buf; } static double exif_read_double(const exif_tag_t *tag, const int index) { - unsigned int num, den; - gbint32 *data = (void *)tag->data; + unsigned int num, den; + gbint32 *data = (void *)tag->data; - num = data[index * 2]; - den = data[(index * 2) + 1]; - if (den == 0) den = 1; + num = data[index * 2]; + den = data[(index * 2) + 1]; + if (den == 0) { + den = 1; + } - return (double)num / (double)den; + return (double)num / (double)den; } static double exif_read_coord(const exif_tag_t *tag) { - double res, min, sec; + double res, min, sec; - res = exif_read_double(tag, 0); - if (tag->count == 1) return res; + res = exif_read_double(tag, 0); + if (tag->count == 1) { + return res; + } - min = exif_read_double(tag, 1); - res += (min / 60); - if (tag->count == 2) return res; + min = exif_read_double(tag, 1); + res += (min / 60); + if (tag->count == 2) { + return res; + } - sec = exif_read_double(tag, 2); - res += (sec / 3600); + sec = exif_read_double(tag, 2); + res += (sec / 3600); - return res; + return res; } static time_t exif_read_timestamp(const exif_tag_t *tag) { - double hour, min, sec; + double hour, min, sec; - hour = exif_read_double(tag, 0); - min = exif_read_double(tag, 1); - sec = exif_read_double(tag, 2); + hour = exif_read_double(tag, 0); + min = exif_read_double(tag, 1); + sec = exif_read_double(tag, 2); - return ((int)hour * SECONDS_PER_HOUR) + ((int)min * 60) + (int)sec; + return ((int)hour * SECONDS_PER_HOUR) + ((int)min * 60) + (int)sec; } static time_t exif_read_datestamp(const exif_tag_t *tag) { - struct tm tm; - char *str; + struct tm tm; + char *str; - memset(&tm, 0, sizeof(tm)); - str = xstrndup((char *)tag->data, tag->size); - sscanf(str, "%d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday); - xfree(str); + memset(&tm, 0, sizeof(tm)); + str = xstrndup((char *)tag->data, tag->size); + sscanf(str, "%d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday); + xfree(str); - tm.tm_year -= 1900; - tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_mon -= 1; - return mkgmtime(&tm); + return mkgmtime(&tm); } static void exif_release_tag(exif_tag_t *tag) { - dequeue(&tag->Q); - if (tag->data_is_dynamic) xfree(tag->data); - xfree(tag); + dequeue(&tag->Q); + if (tag->data_is_dynamic) { + xfree(tag->data); + } + xfree(tag); } static void exif_release_ifd(exif_ifd_t *ifd) { - if (ifd != NULL) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_release_tag((exif_tag_t *)elem); - } - xfree(ifd); - } + if (ifd != NULL) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_release_tag((exif_tag_t *)elem); + } + xfree(ifd); + } } static void exif_release_apps(void) { - queue *e0, *t0; - - QUEUE_FOR_EACH(&exif_apps, e0, t0) { - queue *e1, *t1; - exif_app_t *app = (exif_app_t *)dequeue(e0); - - if (app->fcache) gbfclose(app->fcache); - if (app->fexif) gbfclose(app->fexif); - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)dequeue(e1); - exif_release_ifd(ifd); - } - xfree(app); - } + queue *e0, *t0; + + QUEUE_FOR_EACH(&exif_apps, e0, t0) { + queue *e1, *t1; + exif_app_t *app = (exif_app_t *)dequeue(e0); + + if (app->fcache) { + gbfclose(app->fcache); + } + if (app->fexif) { + gbfclose(app->fexif); + } + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t *ifd = (exif_ifd_t *)dequeue(e1); + exif_release_ifd(ifd); + } + xfree(app); + } } static gbuint32 exif_ifd_size(exif_ifd_t *ifd) { - queue *elem, *tmp; - gbuint32 res = 6; /* nr of tags + next_ifd */ - - res += (ifd->count * 12); - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if (tag->size > 4) { - gbuint32 size = tag->size; - if (size & 1) size++; - res += size; - } - } - - return res; + queue *elem, *tmp; + gbuint32 res = 6; /* nr of tags + next_ifd */ + + res += (ifd->count * 12); + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t *tag = (exif_tag_t *)elem; + if (tag->size > 4) { + gbuint32 size = tag->size; + if (size & 1) { + size++; + } + res += size; + } + } + + return res; } static exif_app_t * exif_load_apps(void) { - exif_app_t *exif_app = NULL; + exif_app_t *exif_app = NULL; - while (! gbfeof(fin)) { - exif_app_t *app = xcalloc(sizeof(*app), 1); + while (! gbfeof(fin)) { + exif_app_t *app = xcalloc(sizeof(*app), 1); - ENQUEUE_TAIL(&exif_apps, &app->Q); - QUEUE_INIT(&app->ifds); - app->fcache = gbfopen(NULL, "wb", MYNAME); + ENQUEUE_TAIL(&exif_apps, &app->Q); + QUEUE_INIT(&app->ifds); + app->fcache = gbfopen(NULL, "wb", MYNAME); - app->marker = gbfgetuint16(fin); - app->len = gbfgetuint16(fin); + app->marker = gbfgetuint16(fin); + app->len = gbfgetuint16(fin); #ifdef EXIF_DBG - printf(MYNAME ": api = %02X, len = %d, offs = %04X\n", app->marker & 0xFF, app->len, gbftell(fin)); + printf(MYNAME ": api = %02X, len = %d, offs = %04X\n", app->marker & 0xFF, app->len, gbftell(fin)); #endif - if (exif_app || (app->marker == 0xFFDA)) /* compressed data */ { - gbfcopyfrom(app->fcache, fin, 0x7FFFFFFF); + if (exif_app || (app->marker == 0xFFDA)) /* compressed data */ { + gbfcopyfrom(app->fcache, fin, 0x7FFFFFFF); #ifdef EXIF_DBG - printf(MYNAME ": compressed data size = %d\n", gbftell(app->fcache)); + printf(MYNAME ": compressed data size = %d\n", gbftell(app->fcache)); #endif - } - else { - gbfcopyfrom(app->fcache, fin, app->len - 2); - if (app->marker == 0xFFE1) { - exif_app = app; - } - } - } - - return exif_app; + } else { + gbfcopyfrom(app->fcache, fin, app->len - 2); + if (app->marker == 0xFFE1) { + exif_app = app; + } + } + } + + return exif_app; } static exif_ifd_t * exif_read_ifd(exif_app_t *app, const gbuint16 ifd_nr, gbsize_t offs, - gbuint32 *exif_ifd_ofs, gbuint32 *gps_ifd_ofs, gbuint32 *inter_ifd_ofs) + gbuint32 *exif_ifd_ofs, gbuint32 *gps_ifd_ofs, gbuint32 *inter_ifd_ofs) { - queue *elem, *tmp; - gbuint16 i; - exif_ifd_t *ifd; - gbfile *fin = app->fexif; + queue *elem, *tmp; + gbuint16 i; + exif_ifd_t *ifd; + gbfile *fin = app->fexif; - ifd = xcalloc(sizeof(*ifd), 1); - QUEUE_INIT(&ifd->tags); - ENQUEUE_TAIL(&app->ifds, &ifd->Q); - ifd->nr = ifd_nr; + ifd = xcalloc(sizeof(*ifd), 1); + QUEUE_INIT(&ifd->tags); + ENQUEUE_TAIL(&app->ifds, &ifd->Q); + ifd->nr = ifd_nr; - gbfseek(fin, offs, SEEK_SET); - ifd->count = gbfgetuint16(fin); + gbfseek(fin, offs, SEEK_SET); + ifd->count = gbfgetuint16(fin); #ifdef EXIF_DBG - { - char *name; - switch(ifd_nr) { - case IFD0: name = "IFD0"; break; - case IFD1: name = "IFD1"; break; - case GPS_IFD: name = "GPS"; break; - case EXIF_IFD: name = "EXIF"; break; - case INTER_IFD: name = "INTER"; break; - default: name = "private"; break; - } - printf(MYNAME "-offs 0x%04X: Number of items in IFD%d \"%s\" = %d (0x%2x)\n", - offs, ifd_nr, name, ifd->count, ifd->count); - } + { + char *name; + switch (ifd_nr) { + case IFD0: + name = "IFD0"; + break; + case IFD1: + name = "IFD1"; + break; + case GPS_IFD: + name = "GPS"; + break; + case EXIF_IFD: + name = "EXIF"; + break; + case INTER_IFD: + name = "INTER"; + break; + default: + name = "private"; + break; + } + printf(MYNAME "-offs 0x%04X: Number of items in IFD%d \"%s\" = %d (0x%2x)\n", + offs, ifd_nr, name, ifd->count, ifd->count); + } #endif - if (ifd->count == 0) return ifd; + if (ifd->count == 0) { + return ifd; + } - for (i = 0; i < ifd->count; i++) { - exif_tag_t *tag; - offs = gbftell(fin); + for (i = 0; i < ifd->count; i++) { + exif_tag_t *tag; + offs = gbftell(fin); - tag = xcalloc(sizeof(*tag), 1); + tag = xcalloc(sizeof(*tag), 1); - ENQUEUE_TAIL(&ifd->tags, &tag->Q); + ENQUEUE_TAIL(&ifd->tags, &tag->Q); - tag->id = gbfgetuint16(fin); - tag->type = gbfgetuint16(fin); - tag->count = gbfgetuint32(fin); - tag->size = exif_type_size(tag->type) * tag->count; - tag->data = &tag->value; + tag->id = gbfgetuint16(fin); + tag->type = gbfgetuint16(fin); + tag->count = gbfgetuint32(fin); + tag->size = exif_type_size(tag->type) * tag->count; + tag->data = &tag->value; #ifdef EXIF_DBG - tag->offs = offs; + tag->offs = offs; #endif - if (BYTE_TYPE(tag->type) && (tag->count <= 4)) { - gbfread(tag->data, 4, 1, fin); - } - else { - tag->value = gbfgetuint32(fin); - tag->origin = tag->value; - } - - if (ifd_nr == IFD0) { - if (tag->id == IFD0_TAG_EXIF_IFD_OFFS) *exif_ifd_ofs = tag->value; - else if (tag->id == IFD0_TAG_GPS_IFD_OFFS) *gps_ifd_ofs = tag->value; - } - else if (ifd_nr == EXIF_IFD) { - if (tag->id == EXIF_IFD_TAG_INTER_IFD_OFFS) *inter_ifd_ofs = tag->value; - } - } - - ifd->next_ifd = gbfgetuint16(fin); - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if ((tag->size > 4) && (tag->value)) { - gbuint16 i; - char *ptr; - - tag->data = xmalloc(tag->size); - tag->data_is_dynamic = 1; - - ptr = tag->data; - gbfseek(fin, tag->value, SEEK_SET); - - if (BYTE_TYPE(tag->type)) gbfread(ptr, tag->count, 1, fin); - else for (i = 0; i < tag->count; i++) { - switch(tag->type) { - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - *(gbint16 *)ptr = gbfgetuint16(fin); - break; - case EXIF_TYPE_IFD: - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - *(gbint32 *)ptr = gbfgetuint32(fin); - break; - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - *(gbint32 *)ptr = gbfgetuint32(fin); - *(gbint32 *)(ptr+4) = gbfgetuint32(fin); - break; - case EXIF_TYPE_FLOAT: - *(float *)ptr = gbfgetflt(fin); - break; - case EXIF_TYPE_DOUBLE: - *(double *)ptr = gbfgetdbl(fin); - break; - default: - gbfread(ptr, 1, 1, fin); - break; - } - ptr += (tag->size / tag->count); - } - } + if (BYTE_TYPE(tag->type) && (tag->count <= 4)) { + gbfread(tag->data, 4, 1, fin); + } else { + tag->value = gbfgetuint32(fin); + tag->origin = tag->value; + } + + if (ifd_nr == IFD0) { + if (tag->id == IFD0_TAG_EXIF_IFD_OFFS) { + *exif_ifd_ofs = tag->value; + } else if (tag->id == IFD0_TAG_GPS_IFD_OFFS) { + *gps_ifd_ofs = tag->value; + } + } else if (ifd_nr == EXIF_IFD) { + if (tag->id == EXIF_IFD_TAG_INTER_IFD_OFFS) { + *inter_ifd_ofs = tag->value; + } + } + } + + ifd->next_ifd = gbfgetuint16(fin); + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t *tag = (exif_tag_t *)elem; + if ((tag->size > 4) && (tag->value)) { + gbuint16 i; + char *ptr; + + tag->data = xmalloc(tag->size); + tag->data_is_dynamic = 1; + + ptr = tag->data; + gbfseek(fin, tag->value, SEEK_SET); + + if (BYTE_TYPE(tag->type)) { + gbfread(ptr, tag->count, 1, fin); + } else for (i = 0; i < tag->count; i++) { + switch (tag->type) { + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + *(gbint16 *)ptr = gbfgetuint16(fin); + break; + case EXIF_TYPE_IFD: + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + *(gbint32 *)ptr = gbfgetuint32(fin); + break; + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + *(gbint32 *)ptr = gbfgetuint32(fin); + *(gbint32 *)(ptr+4) = gbfgetuint32(fin); + break; + case EXIF_TYPE_FLOAT: + *(float *)ptr = gbfgetflt(fin); + break; + case EXIF_TYPE_DOUBLE: + *(double *)ptr = gbfgetdbl(fin); + break; + default: + gbfread(ptr, 1, 1, fin); + break; + } + ptr += (tag->size / tag->count); + } + } #ifdef EXIF_DBG - printf(MYNAME "-offs 0x%04X: ifd=%d id=0x%04X t=0x%04X c=%4d s=%4d v=0x%08X", - tag->offs, ifd->nr, tag->id, tag->type, tag->count, tag->size, tag->value); - if (tag->type == EXIF_TYPE_ASCII) printf(" \"%s\"", exif_read_str(tag)); - printf("\n"); + printf(MYNAME "-offs 0x%04X: ifd=%d id=0x%04X t=0x%04X c=%4d s=%4d v=0x%08X", + tag->offs, ifd->nr, tag->id, tag->type, tag->count, tag->size, tag->value); + if (tag->type == EXIF_TYPE_ASCII) { + printf(" \"%s\"", exif_read_str(tag)); + } + printf("\n"); #endif - } + } - return ifd; + return ifd; } static void exif_read_app(exif_app_t *app) { - gbsize_t offs; - gbuint32 exif_ifd_ofs, gps_ifd_ofs, inter_ifd_ofs; - exif_ifd_t *ifd; - gbfile *fin = app->fexif; + gbsize_t offs; + gbuint32 exif_ifd_ofs, gps_ifd_ofs, inter_ifd_ofs; + exif_ifd_t *ifd; + gbfile *fin = app->fexif; #ifdef EXIF_DBG - printf(MYNAME ": read_app...\n"); - print_buff((const char *)fin->handle.mem, 16, MYNAME); - printf("\n"); + printf(MYNAME ": read_app...\n"); + print_buff((const char *)fin->handle.mem, 16, MYNAME); + printf("\n"); #endif - exif_ifd_ofs = gps_ifd_ofs = inter_ifd_ofs = 0; - - gbfseek(fin, 4, SEEK_SET); - offs = gbfgetuint32(fin); - - ifd = exif_read_ifd(app, IFD0, offs, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); - if (ifd == NULL) return; - - if (ifd->next_ifd) - ifd = exif_read_ifd(app, IFD1, ifd->next_ifd, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); - if (exif_ifd_ofs) - ifd = exif_read_ifd(app, EXIF_IFD, exif_ifd_ofs, NULL, NULL, &inter_ifd_ofs); - if (gps_ifd_ofs) - ifd = exif_read_ifd(app, 3, gps_ifd_ofs, NULL, NULL, NULL); - if (inter_ifd_ofs) - ifd = exif_read_ifd(app, 4, inter_ifd_ofs, NULL, NULL, NULL); + exif_ifd_ofs = gps_ifd_ofs = inter_ifd_ofs = 0; + + gbfseek(fin, 4, SEEK_SET); + offs = gbfgetuint32(fin); + + ifd = exif_read_ifd(app, IFD0, offs, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); + if (ifd == NULL) { + return; + } + + if (ifd->next_ifd) { + ifd = exif_read_ifd(app, IFD1, ifd->next_ifd, &exif_ifd_ofs, &gps_ifd_ofs, &inter_ifd_ofs); + } + if (exif_ifd_ofs) { + ifd = exif_read_ifd(app, EXIF_IFD, exif_ifd_ofs, NULL, NULL, &inter_ifd_ofs); + } + if (gps_ifd_ofs) { + ifd = exif_read_ifd(app, 3, gps_ifd_ofs, NULL, NULL, NULL); + } + if (inter_ifd_ofs) { + ifd = exif_read_ifd(app, 4, inter_ifd_ofs, NULL, NULL, NULL); + } } static void exif_examine_app(exif_app_t *app) { - gbuint16 endianess; - gbuint32 ident; - gbfile *ftmp = exif_app->fcache; - int i; + gbuint16 endianess; + gbuint32 ident; + gbfile *ftmp = exif_app->fcache; + int i; - gbfrewind(ftmp); - ident = gbfgetuint32(ftmp); - is_fatal(ident != 0x66697845, MYNAME ": Invalid EXIF header magic."); - is_fatal(gbfgetint16(ftmp) != 0, MYNAME ": Error in EXIF header."); - endianess = gbfgetint16(ftmp); + gbfrewind(ftmp); + ident = gbfgetuint32(ftmp); + is_fatal(ident != 0x66697845, MYNAME ": Invalid EXIF header magic."); + is_fatal(gbfgetint16(ftmp) != 0, MYNAME ": Error in EXIF header."); + endianess = gbfgetint16(ftmp); #ifdef EXIF_DBG - printf(MYNAME ": endianess = 0x%04X\n", endianess); + printf(MYNAME ": endianess = 0x%04X\n", endianess); #endif - if (endianess == 0x4949) ftmp->big_endian = 0; - else if (endianess == 0x4D4D) ftmp->big_endian = 1; - else fatal(MYNAME ": Invalid endianess identifier 0x%04X!\n", endianess); - - gbfseek(ftmp, 6, SEEK_SET); - app->fexif = gbfopen(NULL, "wb", MYNAME); - app->fexif->big_endian = ftmp->big_endian; - i = gbfcopyfrom(app->fexif, ftmp, 0x7FFFFFFF); - - exif_read_app(exif_app); + if (endianess == 0x4949) { + ftmp->big_endian = 0; + } else if (endianess == 0x4D4D) { + ftmp->big_endian = 1; + } else { + fatal(MYNAME ": Invalid endianess identifier 0x%04X!\n", endianess); + } + + gbfseek(ftmp, 6, SEEK_SET); + app->fexif = gbfopen(NULL, "wb", MYNAME); + app->fexif->big_endian = ftmp->big_endian; + i = gbfcopyfrom(app->fexif, ftmp, 0x7FFFFFFF); + + exif_read_app(exif_app); } static exif_ifd_t * exif_find_ifd(exif_app_t *app, const gbuint16 ifd_nr) { - queue *e0, *t0; + queue *e0, *t0; - QUEUE_FOR_EACH(&app->ifds, e0, t0) { - exif_ifd_t *ifd = (exif_ifd_t *)e0; + QUEUE_FOR_EACH(&app->ifds, e0, t0) { + exif_ifd_t *ifd = (exif_ifd_t *)e0; - if (ifd->nr == ifd_nr) return ifd; - } - return NULL; + if (ifd->nr == ifd_nr) { + return ifd; + } + } + return NULL; } static exif_tag_t * exif_find_tag(exif_app_t *app, const gbuint16 ifd_nr, const gbuint16 tag_id) { - exif_ifd_t *ifd = exif_find_ifd(app, ifd_nr); - if (ifd != NULL) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - if (tag->id == tag_id) return tag; - } - } - return NULL; + exif_ifd_t *ifd = exif_find_ifd(app, ifd_nr); + if (ifd != NULL) { + queue *elem, *tmp; + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t *tag = (exif_tag_t *)elem; + if (tag->id == tag_id) { + return tag; + } + } + } + return NULL; } static time_t exif_get_exif_time(exif_app_t *app) { - exif_tag_t *tag; - time_t res = 0; - - tag = exif_find_tag(app, EXIF_IFD, 0x9003); /* DateTimeOriginal from EXIF */ - if (! tag) tag = exif_find_tag(app, IFD0, 0x0132); /* DateTime from IFD0 */ - if (! tag) tag = exif_find_tag(app, EXIF_IFD, 0x9004); /* DateTimeDigitized from EXIF */ - if (tag) { - struct tm tm; - char *c, *str; - - memset(&tm, 0, sizeof(tm)); - str = exif_read_str(tag); - c = strptime(str, "%Y:%m:%d %H:%M:%S", &tm); - if (c && (*c == '\0')) res = mklocaltime(&tm); - - xfree(str); - } - return res; + exif_tag_t *tag; + time_t res = 0; + + tag = exif_find_tag(app, EXIF_IFD, 0x9003); /* DateTimeOriginal from EXIF */ + if (! tag) { + tag = exif_find_tag(app, IFD0, 0x0132); /* DateTime from IFD0 */ + } + if (! tag) { + tag = exif_find_tag(app, EXIF_IFD, 0x9004); /* DateTimeDigitized from EXIF */ + } + if (tag) { + struct tm tm; + char *c, *str; + + memset(&tm, 0, sizeof(tm)); + str = exif_read_str(tag); + c = strptime(str, "%Y:%m:%d %H:%M:%S", &tm); + if (c && (*c == '\0')) { + res = mklocaltime(&tm); + } + + xfree(str); + } + return res; } static waypoint * exif_waypt_from_exif_app(exif_app_t *app) { - waypoint *wpt; - queue *elem, *tmp; - exif_ifd_t *ifd; - exif_tag_t *tag; - char lat_ref = '\0'; - char lon_ref = '\0'; - char alt_ref = 0; - char speed_ref = '\0'; - char *datum = NULL; - char mode = '\0'; - double gpsdop = unknown_alt; - double alt = unknown_alt; - time_t timestamp = UNKNOWN_TIMESTAMP; - time_t datestamp = UNKNOWN_TIMESTAMP; - - ifd = exif_find_ifd(app, GPS_IFD); - if (ifd == NULL) return NULL; - - wpt = waypt_new(); - - wpt->latitude = unknown_alt; - wpt->longitude = unknown_alt; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - tag = (exif_tag_t *)elem; - - switch(tag->id) { - case GPS_IFD_TAG_VERSION: break; - case GPS_IFD_TAG_LATREF: lat_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_LAT: wpt->latitude = exif_read_coord(tag); break; - case GPS_IFD_TAG_LONREF: lon_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_LON: wpt->longitude = exif_read_coord(tag); break; - case GPS_IFD_TAG_ALTREF: alt_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_ALT: alt = exif_read_double(tag, 0); break; - case GPS_IFD_TAG_TIMESTAMP: timestamp = exif_read_timestamp(tag); break; - case GPS_IFD_TAG_SAT: wpt->sat = atoi((char *)tag->data); break; - case GPS_IFD_TAG_MODE: mode = *(char *)tag->data; break; - case GPS_IFD_TAG_DOP: gpsdop = exif_read_double(tag, 0); break; - case GPS_IFD_TAG_SPEEDREF: speed_ref = *(char *)tag->data; break; - case GPS_IFD_TAG_SPEED: WAYPT_SET(wpt, speed, exif_read_double(tag, 0)); break; - case GPS_IFD_TAG_DATUM: datum = exif_read_str(tag); break; - case GPS_IFD_TAG_DATESTAMP: datestamp = exif_read_datestamp(tag); break; - } - } - - if ((wpt->latitude == unknown_alt) || (wpt->longitude == unknown_alt)) - fatal(MYNAME ": Missing GPSLatitude and/or GPSLongitude!\n"); - - if (lat_ref == 'S') - wpt->latitude *= -1; - else if (lat_ref != 'N') - warning(MYNAME ": GPSLatitudeRef not set! Using N(orth).\n"); - - if (lon_ref == 'W') - wpt->longitude *= -1; - else if (lon_ref != 'E') - warning(MYNAME ": GPSLongitudeRef not set! Using E(east).\n"); + waypoint *wpt; + queue *elem, *tmp; + exif_ifd_t *ifd; + exif_tag_t *tag; + char lat_ref = '\0'; + char lon_ref = '\0'; + char alt_ref = 0; + char speed_ref = '\0'; + char *datum = NULL; + char mode = '\0'; + double gpsdop = unknown_alt; + double alt = unknown_alt; + time_t timestamp = UNKNOWN_TIMESTAMP; + time_t datestamp = UNKNOWN_TIMESTAMP; + + ifd = exif_find_ifd(app, GPS_IFD); + if (ifd == NULL) { + return NULL; + } + + wpt = waypt_new(); + + wpt->latitude = unknown_alt; + wpt->longitude = unknown_alt; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + tag = (exif_tag_t *)elem; + + switch (tag->id) { + case GPS_IFD_TAG_VERSION: + break; + case GPS_IFD_TAG_LATREF: + lat_ref = *(char *)tag->data; + break; + case GPS_IFD_TAG_LAT: + wpt->latitude = exif_read_coord(tag); + break; + case GPS_IFD_TAG_LONREF: + lon_ref = *(char *)tag->data; + break; + case GPS_IFD_TAG_LON: + wpt->longitude = exif_read_coord(tag); + break; + case GPS_IFD_TAG_ALTREF: + alt_ref = *(char *)tag->data; + break; + case GPS_IFD_TAG_ALT: + alt = exif_read_double(tag, 0); + break; + case GPS_IFD_TAG_TIMESTAMP: + timestamp = exif_read_timestamp(tag); + break; + case GPS_IFD_TAG_SAT: + wpt->sat = atoi((char *)tag->data); + break; + case GPS_IFD_TAG_MODE: + mode = *(char *)tag->data; + break; + case GPS_IFD_TAG_DOP: + gpsdop = exif_read_double(tag, 0); + break; + case GPS_IFD_TAG_SPEEDREF: + speed_ref = *(char *)tag->data; + break; + case GPS_IFD_TAG_SPEED: + WAYPT_SET(wpt, speed, exif_read_double(tag, 0)); + break; + case GPS_IFD_TAG_DATUM: + datum = exif_read_str(tag); + break; + case GPS_IFD_TAG_DATESTAMP: + datestamp = exif_read_datestamp(tag); + break; + } + } + + if ((wpt->latitude == unknown_alt) || (wpt->longitude == unknown_alt)) { + fatal(MYNAME ": Missing GPSLatitude and/or GPSLongitude!\n"); + } + + if (lat_ref == 'S') { + wpt->latitude *= -1; + } else if (lat_ref != 'N') { + warning(MYNAME ": GPSLatitudeRef not set! Using N(orth).\n"); + } + + if (lon_ref == 'W') { + wpt->longitude *= -1; + } else if (lon_ref != 'E') { + warning(MYNAME ": GPSLongitudeRef not set! Using E(east).\n"); + } #ifdef EXIF_DBG - printf(MYNAME "-GPSLatitude = %12.7f\n", wpt->latitude); - printf(MYNAME "-GPSLongitude = %12.7f\n", wpt->longitude); + printf(MYNAME "-GPSLatitude = %12.7f\n", wpt->latitude); + printf(MYNAME "-GPSLongitude = %12.7f\n", wpt->longitude); #endif - if (datum) { - int idatum = gt_lookup_datum_index(datum, MYNAME); - if (idatum < 0) - fatal(MYNAME ": Unknown GPSMapDatum \"%s\"!\n", datum); - if (idatum != DATUM_WGS84) { - double alt; - GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, - &wpt->latitude, &wpt->longitude, &alt, idatum); - } - xfree(datum); - } - - if (alt != unknown_alt) { - if (alt_ref != 0) - warning(MYNAME ": Invalid GPSAltitudeRef (%d)! Using 0 (= Sea level).\n", alt_ref); - wpt->altitude = alt; + if (datum) { + int idatum = gt_lookup_datum_index(datum, MYNAME); + if (idatum < 0) { + fatal(MYNAME ": Unknown GPSMapDatum \"%s\"!\n", datum); + } + if (idatum != DATUM_WGS84) { + double alt; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + &wpt->latitude, &wpt->longitude, &alt, idatum); + } + xfree(datum); + } + + if (alt != unknown_alt) { + if (alt_ref != 0) { + warning(MYNAME ": Invalid GPSAltitudeRef (%d)! Using 0 (= Sea level).\n", alt_ref); + } + wpt->altitude = alt; #ifdef EXIF_DBG - printf(MYNAME "-GPSAltitude = %12.7f m\n", wpt->altitude); + printf(MYNAME "-GPSAltitude = %12.7f m\n", wpt->altitude); #endif - } - - if WAYPT_HAS(wpt, speed) { - switch(speed_ref) { - case 'K': - wpt->speed = KPH_TO_MPS(wpt->speed); - break; - case 'M': - wpt->speed = MPH_TO_MPS(wpt->speed); - break; - case 'N': - wpt->speed = KNOTS_TO_MPS(wpt->speed); - break; - default: - wpt->speed = 0; - WAYPT_UNSET(wpt, speed); - warning(MYNAME ": Unknown GPSSpeedRef unit %c (0x%02x)!\n", speed_ref, speed_ref); - } + } + + if WAYPT_HAS(wpt, speed) { + switch (speed_ref) { + case 'K': + wpt->speed = KPH_TO_MPS(wpt->speed); + break; + case 'M': + wpt->speed = MPH_TO_MPS(wpt->speed); + break; + case 'N': + wpt->speed = KNOTS_TO_MPS(wpt->speed); + break; + default: + wpt->speed = 0; + WAYPT_UNSET(wpt, speed); + warning(MYNAME ": Unknown GPSSpeedRef unit %c (0x%02x)!\n", speed_ref, speed_ref); + } #ifdef EXIF_DBG - if WAYPT_HAS(wpt, speed) printf(MYNAME "-GPSSpeed = %12.2f m/s\n", wpt->speed); + if WAYPT_HAS(wpt, speed) { + printf(MYNAME "-GPSSpeed = %12.2f m/s\n", wpt->speed); + } #endif - } - - if (mode == '2') { - wpt->fix = fix_2d; - if (gpsdop != unknown_alt) wpt->hdop = gpsdop; - } - else if (mode == '3') { - wpt->fix = fix_3d; - if (gpsdop != unknown_alt) wpt->pdop = gpsdop; - } - - if (timestamp != UNKNOWN_TIMESTAMP) { - if (datestamp != UNKNOWN_TIMESTAMP) timestamp += datestamp; - } - else timestamp = datestamp; - if (timestamp != UNKNOWN_TIMESTAMP) { + } + + if (mode == '2') { + wpt->fix = fix_2d; + if (gpsdop != unknown_alt) { + wpt->hdop = gpsdop; + } + } else if (mode == '3') { + wpt->fix = fix_3d; + if (gpsdop != unknown_alt) { + wpt->pdop = gpsdop; + } + } + + if (timestamp != UNKNOWN_TIMESTAMP) { + if (datestamp != UNKNOWN_TIMESTAMP) { + timestamp += datestamp; + } + } else { + timestamp = datestamp; + } + if (timestamp != UNKNOWN_TIMESTAMP) { #ifdef EXIF_DBG - char *str = exif_time_str(timestamp); - printf(MYNAME "-GPSTimeStamp = %s\n", str); - xfree(str); + char *str = exif_time_str(timestamp); + printf(MYNAME "-GPSTimeStamp = %s\n", str); + xfree(str); #endif - wpt->creation_time = timestamp; - } - else - wpt->creation_time = exif_get_exif_time(app); - - tag = exif_find_tag(app, EXIF_IFD, EXIF_IFD_TAG_USER_CMT); /* UserComment */ - if (tag && (tag->size > 8)) { - char *str = NULL; - if (memcmp(tag->data, "ASCII\0\0\0", 8) == 0) { - str = xstrndup((char *)tag->data + 8, tag->size - 8); - } - else if (memcmp(tag->data, "UNICODE\0", 8) == 0) { - int i, len = (tag->size - 8) / 2; - gbint16 *s = (void *)((char *)tag->data + 8); - for (i = 0; i < len; i++) s[i] = be_read16(&s[i]); /* always BE ? */ - str = cet_str_uni_to_any(s, len, global_opts.charset); - } - if (str != NULL) { - wpt->notes = str; - } - } - - if (opt_filename) { - char *c, *cx; - char *str = xstrdup(fin->name); - - cx = str; - if ((c = strrchr(cx, ':'))) cx = c + 1; - if ((c = strrchr(cx, '\\'))) cx = c + 1; - if ((c = strrchr(cx, '/'))) cx = c + 1; - if (((c = strchr(cx, '.'))) && (c != cx)) *c = '\0'; - - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = xstrdup(cx); - xfree(str); - } - - return wpt; + wpt->creation_time = timestamp; + } else { + wpt->creation_time = exif_get_exif_time(app); + } + + tag = exif_find_tag(app, EXIF_IFD, EXIF_IFD_TAG_USER_CMT); /* UserComment */ + if (tag && (tag->size > 8)) { + char *str = NULL; + if (memcmp(tag->data, "ASCII\0\0\0", 8) == 0) { + str = xstrndup((char *)tag->data + 8, tag->size - 8); + } else if (memcmp(tag->data, "UNICODE\0", 8) == 0) { + int i, len = (tag->size - 8) / 2; + gbint16 *s = (void *)((char *)tag->data + 8); + for (i = 0; i < len; i++) { + s[i] = be_read16(&s[i]); /* always BE ? */ + } + str = cet_str_uni_to_any(s, len, global_opts.charset); + } + if (str != NULL) { + wpt->notes = str; + } + } + + if (opt_filename) { + char *c, *cx; + char *str = xstrdup(fin->name); + + cx = str; + if ((c = strrchr(cx, ':'))) { + cx = c + 1; + } + if ((c = strrchr(cx, '\\'))) { + cx = c + 1; + } + if ((c = strrchr(cx, '/'))) { + cx = c + 1; + } + if (((c = strchr(cx, '.'))) && (c != cx)) { + *c = '\0'; + } + + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(cx); + xfree(str); + } + + return wpt; } static void exif_dec2frac(double val, gbint32 *num, gbint32 *den) { - char sval[16], snum[16]; - char dot = 0; - int den1 = 1; - int num1, num2, den2, rem; - char *cx; - double vx; - - if (val < 0.000000001) val = 0.0; - else if (val > 999999999.0) - fatal(MYNAME ": Value (%f) to big for a rational representation!\n", val); - - num1 = 0; - vx = fabs(val); - while (vx > 1) { - num1++; - vx = vx / 10; - } - - snprintf(sval, sizeof(sval), "%*.*f", 9, 9 - num1, fabs(val)); - snum[0] = '\0'; - - cx = sval; - while (*cx) { - if (dot) den1 *= 10; - if (*cx == '.') dot = 1; - else strncat(snum, cx, 1); - cx++; - } - - num1 = atoi(snum); - if (den1 == 1) { - *num = num1; - *den = den1; - } - - num2 = num1; - den2 = den1; - rem = 1; - - /* Euclid's Algorithm to find the gcd */ - while (num2 % den2) { - rem = num2 % den2; - num2 = den2; - den2 = rem; - } - if (den2 != den1) rem = den2; - - *num = num1 / rem; - *den = den1 / rem; + char sval[16], snum[16]; + char dot = 0; + int den1 = 1; + int num1, num2, den2, rem; + char *cx; + double vx; + + if (val < 0.000000001) { + val = 0.0; + } else if (val > 999999999.0) { + fatal(MYNAME ": Value (%f) to big for a rational representation!\n", val); + } + + num1 = 0; + vx = fabs(val); + while (vx > 1) { + num1++; + vx = vx / 10; + } + + snprintf(sval, sizeof(sval), "%*.*f", 9, 9 - num1, fabs(val)); + snum[0] = '\0'; + + cx = sval; + while (*cx) { + if (dot) { + den1 *= 10; + } + if (*cx == '.') { + dot = 1; + } else { + strncat(snum, cx, 1); + } + cx++; + } + + num1 = atoi(snum); + if (den1 == 1) { + *num = num1; + *den = den1; + } + + num2 = num1; + den2 = den1; + rem = 1; + + /* Euclid's Algorithm to find the gcd */ + while (num2 % den2) { + rem = num2 % den2; + num2 = den2; + den2 = rem; + } + if (den2 != den1) { + rem = den2; + } + + *num = num1 / rem; + *den = den1 / rem; } static exif_tag_t * exif_put_value(const int ifd_nr, const gbuint16 tag_id, const gbuint16 type, const gbuint32 count, const int index, const void *data) { - exif_tag_t *tag = NULL; - exif_ifd_t *ifd; - gbuint16 item_size, size; - - ifd = exif_find_ifd(exif_app, ifd_nr); - if (ifd == NULL) { - ifd = xcalloc(sizeof(*ifd), 1); - ifd->nr = ifd_nr; - QUEUE_INIT(&ifd->tags); - ENQUEUE_TAIL(&exif_app->ifds, &ifd->Q); - } - else tag = exif_find_tag(exif_app, ifd_nr, tag_id); - - item_size = exif_type_size(type); - - if ((data == NULL) || (count < 1) || (index < 0)) size = 0; - else size = (index + count) * item_size; - - if (tag == NULL) { - if (size == 0) return NULL; - - tag = xcalloc(sizeof(*tag), 1); - - tag->id = tag_id; - tag->type = type; - tag->count = index + count; - tag->size = size; - tag->data = xcalloc((size < 4) ? 4 : size, 1); - tag->data_is_dynamic = 1; - ifd->count++; - - ENQUEUE_TAIL(&ifd->tags, &tag->Q); - } - else { - if (size == 0) { /* remove this element */ - ifd->count--; - exif_release_tag(tag); - return NULL; - } - if (tag->count < (index + count)) { - if (! tag->data_is_dynamic) { - void *tmp = xmalloc(tag->size < 4 ? 4 : tag->size); - memcpy(tmp, tag->data, tag->size); - tag->data = tmp; - tag->data_is_dynamic = 1; - } - tag->size = size; - tag->count = index + count; - tag->data = xrealloc(tag->data, size < 4 ? 4 : size); - } - } - - switch(type) { - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: { - double val = *(double *)data; - gbuint32 *dest = tag->data; - - if ((int)val == val) { - dest[index * 2] = (int)val; - dest[(index * 2) + 1] = 1; - } - else { - gbint32 Nom, Den; - exif_dec2frac(val, &Nom, &Den); - if ((type == EXIF_TYPE_SRAT) && (val < 0.0)) Nom *= -1; - dest[index * 2] = Nom; - dest[(index * 2) + 1] = Den; - } - } - break; - default: { - char *dest = tag->data; - memcpy(&dest[index * item_size], data, count * item_size); - } - } - return tag; + exif_tag_t *tag = NULL; + exif_ifd_t *ifd; + gbuint16 item_size, size; + + ifd = exif_find_ifd(exif_app, ifd_nr); + if (ifd == NULL) { + ifd = xcalloc(sizeof(*ifd), 1); + ifd->nr = ifd_nr; + QUEUE_INIT(&ifd->tags); + ENQUEUE_TAIL(&exif_app->ifds, &ifd->Q); + } else { + tag = exif_find_tag(exif_app, ifd_nr, tag_id); + } + + item_size = exif_type_size(type); + + if ((data == NULL) || (count < 1) || (index < 0)) { + size = 0; + } else { + size = (index + count) * item_size; + } + + if (tag == NULL) { + if (size == 0) { + return NULL; + } + + tag = xcalloc(sizeof(*tag), 1); + + tag->id = tag_id; + tag->type = type; + tag->count = index + count; + tag->size = size; + tag->data = xcalloc((size < 4) ? 4 : size, 1); + tag->data_is_dynamic = 1; + ifd->count++; + + ENQUEUE_TAIL(&ifd->tags, &tag->Q); + } else { + if (size == 0) { /* remove this element */ + ifd->count--; + exif_release_tag(tag); + return NULL; + } + if (tag->count < (index + count)) { + if (! tag->data_is_dynamic) { + void *tmp = xmalloc(tag->size < 4 ? 4 : tag->size); + memcpy(tmp, tag->data, tag->size); + tag->data = tmp; + tag->data_is_dynamic = 1; + } + tag->size = size; + tag->count = index + count; + tag->data = xrealloc(tag->data, size < 4 ? 4 : size); + } + } + + switch (type) { + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: { + double val = *(double *)data; + gbuint32 *dest = tag->data; + + if ((int)val == val) { + dest[index * 2] = (int)val; + dest[(index * 2) + 1] = 1; + } else { + gbint32 Nom, Den; + exif_dec2frac(val, &Nom, &Den); + if ((type == EXIF_TYPE_SRAT) && (val < 0.0)) { + Nom *= -1; + } + dest[index * 2] = Nom; + dest[(index * 2) + 1] = Den; + } + } + break; + default: { + char *dest = tag->data; + memcpy(&dest[index * item_size], data, count * item_size); + } + } + return tag; } static void exif_put_double(const int ifd_nr, const int tag_id, const int index, const double val) { - double d = fabs(val); - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_RAT, 1, index, &d); + double d = fabs(val); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_RAT, 1, index, &d); } static void exif_put_str(const int ifd_nr, const int tag_id, const char *val) { - int len = (val) ? strlen(val) + 1 : 0; - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_ASCII, len, 0, val); + int len = (val) ? strlen(val) + 1 : 0; + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_ASCII, len, 0, val); } static void exif_put_coord(const int ifd_nr, const int tag_id, const double val) { - double vmin, vsec; - int vint; + double vmin, vsec; + int vint; - vint = abs((int) val); - vmin = 60.0 * (fabs(val) - vint); - vsec = 60.0 * (vmin - floor(vmin)); - vmin = floor(vmin); + vint = abs((int) val); + vmin = 60.0 * (fabs(val) - vint); + vsec = 60.0 * (vmin - floor(vmin)); + vmin = floor(vmin); - exif_put_double(ifd_nr, tag_id, 0, (double)vint); - exif_put_double(ifd_nr, tag_id, 1, (double)vmin); - exif_put_double(ifd_nr, tag_id, 2, (double)vsec); + exif_put_double(ifd_nr, tag_id, 0, (double)vint); + exif_put_double(ifd_nr, tag_id, 1, (double)vmin); + exif_put_double(ifd_nr, tag_id, 2, (double)vsec); } static void exif_put_long(const int ifd_nr, const int tag_id, const int index, const gbint32 val) { - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_LONG, 1, index, &val); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_LONG, 1, index, &val); } static void exif_remove_tag(const int ifd_nr, const int tag_id) { - exif_put_value(ifd_nr, tag_id, EXIF_TYPE_BYTE, 0, 0, NULL); + exif_put_value(ifd_nr, tag_id, EXIF_TYPE_BYTE, 0, 0, NULL); } static void exif_find_wpt_by_time(const waypoint *wpt) { - if (wpt->creation_time <= 0) return; - - if (exif_wpt_ref == NULL) exif_wpt_ref = wpt; - else if (abs(exif_time_ref - wpt->creation_time) < abs(exif_time_ref - exif_wpt_ref->creation_time)) - exif_wpt_ref = wpt; + if (wpt->creation_time <= 0) { + return; + } + + if (exif_wpt_ref == NULL) { + exif_wpt_ref = wpt; + } else if (abs(exif_time_ref - wpt->creation_time) < abs(exif_time_ref - exif_wpt_ref->creation_time)) { + exif_wpt_ref = wpt; + } } static void exif_find_wpt_by_name(const waypoint *wpt) { - if (exif_wpt_ref != NULL) - return; - else if ((wpt->shortname != NULL) && (case_ignore_strcmp(wpt->shortname, opt_name) == 0)) - exif_wpt_ref = wpt; + if (exif_wpt_ref != NULL) { + return; + } else if ((wpt->shortname != NULL) && (case_ignore_strcmp(wpt->shortname, opt_name) == 0)) { + exif_wpt_ref = wpt; + } } static int exif_sort_tags_cb(const queue *A, const queue *B) { - exif_tag_t *ta = (exif_tag_t *)A; - exif_tag_t *tb = (exif_tag_t *)B; + exif_tag_t *ta = (exif_tag_t *)A; + exif_tag_t *tb = (exif_tag_t *)B; - return ta->id - tb->id; + return ta->id - tb->id; } static int exif_sort_ifds_cb(const queue *A, const queue *B) { - exif_ifd_t *ia = (exif_ifd_t *)A; - exif_ifd_t *ib = (exif_ifd_t *)B; + exif_ifd_t *ia = (exif_ifd_t *)A; + exif_ifd_t *ib = (exif_ifd_t *)B; - return ia->nr - ib->nr; + return ia->nr - ib->nr; } static void exif_write_value(exif_tag_t *tag, gbfile *fout) { - if (tag->size > 4) gbfputuint32(tag->value, fout); /* offset to data */ - else { - char *data = tag->data; - - if BYTE_TYPE(tag->type) gbfwrite(data, 4, 1, fout); - else if WORD_TYPE(tag->type) { - gbfputuint16(*(gbuint16 *)data, fout); - gbfputuint16(*(gbuint16 *)(data+2), fout); - } - else if LONG_TYPE(tag->type) gbfputuint32(*(gbuint32 *)data, fout); - else if (tag->type == EXIF_TYPE_FLOAT) gbfputflt(*(float *)data, fout); - else fatal(MYNAME ": Unknown data type %d!\n", tag->type); - } + if (tag->size > 4) { + gbfputuint32(tag->value, fout); /* offset to data */ + } else { + char *data = tag->data; + + if BYTE_TYPE(tag->type) { + gbfwrite(data, 4, 1, fout); + } else if WORD_TYPE(tag->type) { + gbfputuint16(*(gbuint16 *)data, fout); + gbfputuint16(*(gbuint16 *)(data+2), fout); + } else if LONG_TYPE(tag->type) { + gbfputuint32(*(gbuint32 *)data, fout); + } else if (tag->type == EXIF_TYPE_FLOAT) { + gbfputflt(*(float *)data, fout); + } else { + fatal(MYNAME ": Unknown data type %d!\n", tag->type); + } + } } static void exif_write_ifd(const exif_ifd_t *ifd, const char next, gbfile *fout) { - gbsize_t offs; - queue *elem, *tmp; - - gbfputuint16(ifd->count, fout); - offs = gbftell(fout) + (ifd->count * 12) + 4; - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - - gbfputuint16(tag->id, fout); - gbfputuint16(tag->type, fout); - gbfputuint32(tag->count, fout); - if (tag->size > 4) { - tag->value = offs; - offs += tag->size; - if (offs & 1) offs++; - gbfputuint32(tag->value, fout); - } - else exif_write_value(tag, fout); - } - - if (next) gbfputuint32(offs, fout); - else gbfputuint32(0, fout); - - QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { - exif_tag_t *tag = (exif_tag_t *)elem; - - if (tag->size > 4) { - gbuint16 i; - char *ptr = tag->data; - - if BYTE_TYPE(tag->type) gbfwrite(tag->data, tag->size, 1, fout); - else for (i = 0; i < tag->count; i++) { - switch(tag->type) { - case EXIF_TYPE_SHORT: - case EXIF_TYPE_SSHORT: - gbfputuint16(*(gbint16 *)ptr, fout); - break; - case EXIF_TYPE_LONG: - case EXIF_TYPE_SLONG: - case EXIF_TYPE_IFD: - gbfputuint32(*(gbint32 *)ptr, fout); - break; - case EXIF_TYPE_RAT: - case EXIF_TYPE_SRAT: - gbfputuint32(*(gbint32 *)ptr, fout); - gbfputuint32(*(gbint32 *)(ptr+4), fout); - break; - case EXIF_TYPE_FLOAT: - gbfputflt(*(float *)ptr, fout); - break; - case EXIF_TYPE_DOUBLE: - gbfputdbl(*(double *)ptr, fout); - break; - default: - gbfwrite(ptr, exif_type_size(tag->type), 1, fin); - break; - } - ptr += (tag->size / tag->count); - } - if (gbftell(fout) & 1) gbfputc(0, fout); - } - } + gbsize_t offs; + queue *elem, *tmp; + + gbfputuint16(ifd->count, fout); + offs = gbftell(fout) + (ifd->count * 12) + 4; + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t *tag = (exif_tag_t *)elem; + + gbfputuint16(tag->id, fout); + gbfputuint16(tag->type, fout); + gbfputuint32(tag->count, fout); + if (tag->size > 4) { + tag->value = offs; + offs += tag->size; + if (offs & 1) { + offs++; + } + gbfputuint32(tag->value, fout); + } else { + exif_write_value(tag, fout); + } + } + + if (next) { + gbfputuint32(offs, fout); + } else { + gbfputuint32(0, fout); + } + + QUEUE_FOR_EACH(&ifd->tags, elem, tmp) { + exif_tag_t *tag = (exif_tag_t *)elem; + + if (tag->size > 4) { + gbuint16 i; + char *ptr = tag->data; + + if BYTE_TYPE(tag->type) { + gbfwrite(tag->data, tag->size, 1, fout); + } else for (i = 0; i < tag->count; i++) { + switch (tag->type) { + case EXIF_TYPE_SHORT: + case EXIF_TYPE_SSHORT: + gbfputuint16(*(gbint16 *)ptr, fout); + break; + case EXIF_TYPE_LONG: + case EXIF_TYPE_SLONG: + case EXIF_TYPE_IFD: + gbfputuint32(*(gbint32 *)ptr, fout); + break; + case EXIF_TYPE_RAT: + case EXIF_TYPE_SRAT: + gbfputuint32(*(gbint32 *)ptr, fout); + gbfputuint32(*(gbint32 *)(ptr+4), fout); + break; + case EXIF_TYPE_FLOAT: + gbfputflt(*(float *)ptr, fout); + break; + case EXIF_TYPE_DOUBLE: + gbfputdbl(*(double *)ptr, fout); + break; + default: + gbfwrite(ptr, exif_type_size(tag->type), 1, fin); + break; + } + ptr += (tag->size / tag->count); + } + if (gbftell(fout) & 1) { + gbfputc(0, fout); + } + } + } } static void exif_write_apps(void) { - queue *e0, *t0; - - gbfputuint16(0xFFD8, fout); - - QUEUE_FOR_EACH(&exif_apps, e0, t0) { - exif_app_t *app = (exif_app_t *)e0; - - gbfputuint16(app->marker, fout); - - if (app == exif_app) { - queue *e1, *t1; - gbuint16 len = 8; - gbfile *ftmp; - exif_tag_t *tag; - - exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); - exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); - - sortqueue(&exif_app->ifds, exif_sort_ifds_cb); - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - - if (ifd->nr == GPS_IFD) exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, len); - else if (ifd->nr == EXIF_IFD) exif_put_long(IFD0, IFD0_TAG_EXIF_IFD_OFFS, 0, len); - else if (ifd->nr == INTER_IFD) exif_put_long(EXIF_IFD, EXIF_IFD_TAG_INTER_IFD_OFFS, 0, len); - - len += exif_ifd_size(ifd); - } - - len += 4; /* DWORD(0) after last ifd */ - - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) - exif_put_long(IFD1, IFD1_TAG_JPEG_OFFS, 0, len); - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - sortqueue(&ifd->tags, exif_sort_tags_cb); - } - - ftmp = gbfopen_be(NULL, "wb", MYNAME); - ftmp->big_endian = app->fcache->big_endian; - - gbfwrite((ftmp->big_endian) ? "MM" : "II", 2, 1, ftmp); - gbfputuint16(0x2A, ftmp); - gbfputuint32(0x08, ftmp); /* offset to first IFD */ - - QUEUE_FOR_EACH(&app->ifds, e1, t1) { - exif_ifd_t *ifd = (exif_ifd_t *)e1; - exif_ifd_t *ifd_next = (exif_ifd_t *)t1; - char next; - - if ((ifd->nr == IFD0) && (ifd_next->nr == IFD1)) next = 1; - else next = 0; - - exif_write_ifd(ifd, next, ftmp); - len = gbftell(ftmp); - } - - gbfputuint32(0, ftmp); /* DWORD(0) after last ifd */ - - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { - gbsize_t offs = tag->origin; - if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_SIZE))) { - gbfseek(app->fexif, offs, SEEK_SET); - gbfcopyfrom(ftmp, app->fexif, tag->value); - } - } - - len = gbftell(ftmp); - gbfrewind(ftmp); - gbfputuint16(len + 8, fout); - gbfwrite("Exif\0\0", 6, 1, fout); - gbfcopyfrom(fout, ftmp, len); - - gbfclose(ftmp); - } - else { - gbfputuint16(app->len, fout); - gbfrewind(app->fcache); - gbfcopyfrom(fout, app->fcache, 0x7FFFFFFF); - } - } + queue *e0, *t0; + + gbfputuint16(0xFFD8, fout); + + QUEUE_FOR_EACH(&exif_apps, e0, t0) { + exif_app_t *app = (exif_app_t *)e0; + + gbfputuint16(app->marker, fout); + + if (app == exif_app) { + queue *e1, *t1; + gbuint16 len = 8; + gbfile *ftmp; + exif_tag_t *tag; + + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); + exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); + + sortqueue(&exif_app->ifds, exif_sort_ifds_cb); + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t *ifd = (exif_ifd_t *)e1; + + if (ifd->nr == GPS_IFD) { + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, len); + } else if (ifd->nr == EXIF_IFD) { + exif_put_long(IFD0, IFD0_TAG_EXIF_IFD_OFFS, 0, len); + } else if (ifd->nr == INTER_IFD) { + exif_put_long(EXIF_IFD, EXIF_IFD_TAG_INTER_IFD_OFFS, 0, len); + } + + len += exif_ifd_size(ifd); + } + + len += 4; /* DWORD(0) after last ifd */ + + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { + exif_put_long(IFD1, IFD1_TAG_JPEG_OFFS, 0, len); + } + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t *ifd = (exif_ifd_t *)e1; + sortqueue(&ifd->tags, exif_sort_tags_cb); + } + + ftmp = gbfopen_be(NULL, "wb", MYNAME); + ftmp->big_endian = app->fcache->big_endian; + + gbfwrite((ftmp->big_endian) ? "MM" : "II", 2, 1, ftmp); + gbfputuint16(0x2A, ftmp); + gbfputuint32(0x08, ftmp); /* offset to first IFD */ + + QUEUE_FOR_EACH(&app->ifds, e1, t1) { + exif_ifd_t *ifd = (exif_ifd_t *)e1; + exif_ifd_t *ifd_next = (exif_ifd_t *)t1; + char next; + + if ((ifd->nr == IFD0) && (ifd_next->nr == IFD1)) { + next = 1; + } else { + next = 0; + } + + exif_write_ifd(ifd, next, ftmp); + len = gbftell(ftmp); + } + + gbfputuint32(0, ftmp); /* DWORD(0) after last ifd */ + + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_OFFS))) { + gbsize_t offs = tag->origin; + if ((tag = exif_find_tag(app, IFD1, IFD1_TAG_JPEG_SIZE))) { + gbfseek(app->fexif, offs, SEEK_SET); + gbfcopyfrom(ftmp, app->fexif, tag->value); + } + } + + len = gbftell(ftmp); + gbfrewind(ftmp); + gbfputuint16(len + 8, fout); + gbfwrite("Exif\0\0", 6, 1, fout); + gbfcopyfrom(fout, ftmp, len); + + gbfclose(ftmp); + } else { + gbfputuint16(app->len, fout); + gbfrewind(app->fcache); + gbfcopyfrom(fout, app->fcache, 0x7FFFFFFF); + } + } } /******************************************************************************* @@ -1166,213 +1327,226 @@ exif_write_apps(void) static void exif_rd_init(const char *fname) { - fin = gbfopen_be(fname, "rb", MYNAME); - QUEUE_INIT(&exif_apps); + fin = gbfopen_be(fname, "rb", MYNAME); + QUEUE_INIT(&exif_apps); } static void exif_rd_deinit(void) { - exif_release_apps(); - gbfclose(fin); + exif_release_apps(); + gbfclose(fin); } static void exif_read(void) { - gbuint16 soi; - waypoint *wpt; + gbuint16 soi; + waypoint *wpt; - soi = gbfgetuint16(fin); - is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); /* only jpeg for now */ + soi = gbfgetuint16(fin); + is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); /* only jpeg for now */ - exif_app = exif_load_apps(); - is_fatal(exif_app == NULL, MYNAME ": No EXIF header in source file \"%s\".", fin->name); + exif_app = exif_load_apps(); + is_fatal(exif_app == NULL, MYNAME ": No EXIF header in source file \"%s\".", fin->name); - exif_examine_app(exif_app); - wpt = exif_waypt_from_exif_app(exif_app); - if (wpt) waypt_add(wpt); + exif_examine_app(exif_app); + wpt = exif_waypt_from_exif_app(exif_app); + if (wpt) { + waypt_add(wpt); + } } static void exif_wr_init(const char *fname) { - gbuint16 soi; - char *tmpname; + gbuint16 soi; + char *tmpname; - exif_success = 0; - exif_fout_name = xstrdup(fname); + exif_success = 0; + exif_fout_name = xstrdup(fname); - QUEUE_INIT(&exif_apps); + QUEUE_INIT(&exif_apps); - fin = gbfopen_be(fname, "rb", MYNAME); - is_fatal(fin->is_pipe, MYNAME ": Sorry, this format cannot be used with pipes!"); + fin = gbfopen_be(fname, "rb", MYNAME); + is_fatal(fin->is_pipe, MYNAME ": Sorry, this format cannot be used with pipes!"); - soi = gbfgetuint16(fin); - is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); - exif_app = exif_load_apps(); - is_fatal(exif_app == NULL, MYNAME ": No EXIF header found in source file \"%s\".", fin->name); - exif_examine_app(exif_app); - gbfclose(fin); + soi = gbfgetuint16(fin); + is_fatal(soi != 0xFFD8, MYNAME ": Unknown image file."); + exif_app = exif_load_apps(); + is_fatal(exif_app == NULL, MYNAME ": No EXIF header found in source file \"%s\".", fin->name); + exif_examine_app(exif_app); + gbfclose(fin); - exif_time_ref = exif_get_exif_time(exif_app); - if (exif_time_ref == 0) fatal(MYNAME ": No valid timestamp found in picture!\n"); + exif_time_ref = exif_get_exif_time(exif_app); + if (exif_time_ref == 0) { + fatal(MYNAME ": No valid timestamp found in picture!\n"); + } - xasprintf(&tmpname, "%s.jpg", fname); - fout = gbfopen_be(tmpname, "wb", MYNAME); - xfree(tmpname); + xasprintf(&tmpname, "%s.jpg", fname); + fout = gbfopen_be(tmpname, "wb", MYNAME); + xfree(tmpname); } static void exif_wr_deinit(void) { - char *tmpname; - - exif_release_apps(); - tmpname = xstrdup(fout->name); - gbfclose(fout); - - if (exif_success) { - if (*opt_overwrite == '1') { - remove(exif_fout_name); - rename(tmpname, exif_fout_name); - } - } - else remove(tmpname); - - xfree(exif_fout_name); - xfree(tmpname); + char *tmpname; + + exif_release_apps(); + tmpname = xstrdup(fout->name); + gbfclose(fout); + + if (exif_success) { + if (*opt_overwrite == '1') { + remove(exif_fout_name); + rename(tmpname, exif_fout_name); + } + } else { + remove(tmpname); + } + + xfree(exif_fout_name); + xfree(tmpname); } static void exif_write(void) { - char alt_ref = 0; - time_t frame; - - exif_wpt_ref = NULL; - - if (opt_name) { - waypt_disp_all(exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) route_disp_all(NULL, NULL, exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) track_disp_all(NULL, NULL, exif_find_wpt_by_name); - if (exif_wpt_ref == NULL) { - warning(MYNAME ": No matching point with name \"%s\" found.\n", opt_name); - } - } - else { - char *str = exif_time_str(exif_time_ref); - - track_disp_all(NULL, NULL, exif_find_wpt_by_time); - route_disp_all(NULL, NULL, exif_find_wpt_by_time); - waypt_disp_all(exif_find_wpt_by_time); - - frame = atoi(opt_frame); - - if (exif_wpt_ref == NULL) - warning(MYNAME ": No point with a valid timestamp found.\n"); - else if (abs(exif_time_ref - exif_wpt_ref->creation_time) > frame) { - warning(MYNAME ": No matching point found for image date %s!\n", str); - if (exif_wpt_ref != NULL) { - char *str = exif_time_str(exif_wpt_ref->creation_time); - warning(MYNAME ": Best is from %s, %d second(s) away.\n", - str, abs(exif_time_ref - exif_wpt_ref->creation_time)); - xfree(str); - } - exif_wpt_ref = NULL; - } - xfree(str); - } - - if (exif_wpt_ref != NULL) { - const waypoint *wpt = exif_wpt_ref; - - exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); - exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); - exif_put_str(GPS_IFD, GPS_IFD_TAG_DATUM, "WGS-84"); - - exif_put_str(GPS_IFD, GPS_IFD_TAG_LATREF, wpt->latitude < 0 ? "S" : "N"); - exif_put_coord(GPS_IFD, GPS_IFD_TAG_LAT, fabs(wpt->latitude)); - exif_put_str(GPS_IFD, GPS_IFD_TAG_LONREF, wpt->longitude < 0 ? "W" : "E"); - exif_put_coord(GPS_IFD, GPS_IFD_TAG_LON, fabs(wpt->longitude)); - - if (wpt->altitude == unknown_alt) { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALT); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALTREF); - } - else { - exif_put_value(GPS_IFD, GPS_IFD_TAG_ALTREF, EXIF_TYPE_BYTE, 1, 0, &alt_ref); - exif_put_double(GPS_IFD, GPS_IFD_TAG_ALT, 0, wpt->altitude); - } - - if (wpt->creation_time) { - struct tm tm; - char buf[32]; - - tm = *gmtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon += 1; - - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 0, tm.tm_hour); - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 1, tm.tm_min); - exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 2, tm.tm_sec); - - snprintf(buf, sizeof(buf), "%04d:%02d:%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); - exif_put_str(GPS_IFD, GPS_IFD_TAG_DATESTAMP, buf); - } - else { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_TIMESTAMP); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DATESTAMP); - } - - if (wpt->sat > 0) { - char buf[16]; - snprintf(buf, sizeof(buf), "%d", wpt->sat); - exif_put_str(GPS_IFD, GPS_IFD_TAG_SAT, buf); - } - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SAT); - - if (wpt->fix == fix_2d) exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "2"); - else if (wpt->fix == fix_3d) exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "3"); - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_MODE); - - if (wpt->hdop > 0) exif_put_double(GPS_IFD, GPS_IFD_TAG_DOP, 0, wpt->hdop); - else exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DOP); - - if WAYPT_HAS(wpt, speed) { - exif_put_str(GPS_IFD, GPS_IFD_TAG_SPEEDREF, "K"); - exif_put_double(GPS_IFD, GPS_IFD_TAG_SPEED, 0, MPS_TO_KPH(wpt->speed)); - } - else { - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEEDREF); - exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEED); - } - - exif_write_apps(); /* Success, write the new file */ - - exif_success = 1; - } + char alt_ref = 0; + time_t frame; + + exif_wpt_ref = NULL; + + if (opt_name) { + waypt_disp_all(exif_find_wpt_by_name); + if (exif_wpt_ref == NULL) { + route_disp_all(NULL, NULL, exif_find_wpt_by_name); + } + if (exif_wpt_ref == NULL) { + track_disp_all(NULL, NULL, exif_find_wpt_by_name); + } + if (exif_wpt_ref == NULL) { + warning(MYNAME ": No matching point with name \"%s\" found.\n", opt_name); + } + } else { + char *str = exif_time_str(exif_time_ref); + + track_disp_all(NULL, NULL, exif_find_wpt_by_time); + route_disp_all(NULL, NULL, exif_find_wpt_by_time); + waypt_disp_all(exif_find_wpt_by_time); + + frame = atoi(opt_frame); + + if (exif_wpt_ref == NULL) { + warning(MYNAME ": No point with a valid timestamp found.\n"); + } else if (abs(exif_time_ref - exif_wpt_ref->creation_time) > frame) { + warning(MYNAME ": No matching point found for image date %s!\n", str); + if (exif_wpt_ref != NULL) { + char *str = exif_time_str(exif_wpt_ref->creation_time); + warning(MYNAME ": Best is from %s, %d second(s) away.\n", + str, abs(exif_time_ref - exif_wpt_ref->creation_time)); + xfree(str); + } + exif_wpt_ref = NULL; + } + xfree(str); + } + + if (exif_wpt_ref != NULL) { + const waypoint *wpt = exif_wpt_ref; + + exif_put_long(IFD0, IFD0_TAG_GPS_IFD_OFFS, 0, 0); + exif_put_long(GPS_IFD, GPS_IFD_TAG_VERSION, 0, 2); + exif_put_str(GPS_IFD, GPS_IFD_TAG_DATUM, "WGS-84"); + + exif_put_str(GPS_IFD, GPS_IFD_TAG_LATREF, wpt->latitude < 0 ? "S" : "N"); + exif_put_coord(GPS_IFD, GPS_IFD_TAG_LAT, fabs(wpt->latitude)); + exif_put_str(GPS_IFD, GPS_IFD_TAG_LONREF, wpt->longitude < 0 ? "W" : "E"); + exif_put_coord(GPS_IFD, GPS_IFD_TAG_LON, fabs(wpt->longitude)); + + if (wpt->altitude == unknown_alt) { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALT); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_ALTREF); + } else { + exif_put_value(GPS_IFD, GPS_IFD_TAG_ALTREF, EXIF_TYPE_BYTE, 1, 0, &alt_ref); + exif_put_double(GPS_IFD, GPS_IFD_TAG_ALT, 0, wpt->altitude); + } + + if (wpt->creation_time) { + struct tm tm; + char buf[32]; + + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon += 1; + + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 0, tm.tm_hour); + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 1, tm.tm_min); + exif_put_double(GPS_IFD, GPS_IFD_TAG_TIMESTAMP, 2, tm.tm_sec); + + snprintf(buf, sizeof(buf), "%04d:%02d:%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); + exif_put_str(GPS_IFD, GPS_IFD_TAG_DATESTAMP, buf); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_TIMESTAMP); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DATESTAMP); + } + + if (wpt->sat > 0) { + char buf[16]; + snprintf(buf, sizeof(buf), "%d", wpt->sat); + exif_put_str(GPS_IFD, GPS_IFD_TAG_SAT, buf); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SAT); + } + + if (wpt->fix == fix_2d) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "2"); + } else if (wpt->fix == fix_3d) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_MODE, "3"); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_MODE); + } + + if (wpt->hdop > 0) { + exif_put_double(GPS_IFD, GPS_IFD_TAG_DOP, 0, wpt->hdop); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_DOP); + } + + if WAYPT_HAS(wpt, speed) { + exif_put_str(GPS_IFD, GPS_IFD_TAG_SPEEDREF, "K"); + exif_put_double(GPS_IFD, GPS_IFD_TAG_SPEED, 0, MPS_TO_KPH(wpt->speed)); + } else { + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEEDREF); + exif_remove_tag(GPS_IFD, GPS_IFD_TAG_SPEED); + } + + exif_write_apps(); /* Success, write the new file */ + + exif_success = 1; + } } /**************************************************************************/ ff_vecs_t exif_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - exif_rd_init, - exif_wr_init, - exif_rd_deinit, - exif_wr_deinit, - exif_read, - exif_write, - NULL, - exif_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + exif_rd_init, + exif_wr_init, + exif_rd_deinit, + exif_wr_deinit, + exif_read, + exif_write, + NULL, + exif_args, + CET_CHARSET_UTF8, 0 }; /**************************************************************************/ diff --git a/gpsbabel/explorist_ini.c b/gpsbabel/explorist_ini.c index accf8d706..bc1c702c4 100644 --- a/gpsbabel/explorist_ini.c +++ b/gpsbabel/explorist_ini.c @@ -6,12 +6,14 @@ static inifile_t *inifile; static const char myname[] = "explorist"; const char * -explorist_read_value(const char* section, const char *key) { +explorist_read_value(const char* section, const char *key) +{ return inifile_readstr(inifile, section, key); } static mag_info * -explorist_ini_try(const char *path) { +explorist_ini_try(const char *path) +{ mag_info *info = NULL; char *inipath; char *s; @@ -19,7 +21,7 @@ explorist_ini_try(const char *path) { xasprintf(&inipath, "%s/%s", path, "APP/Atlas.ini"); inifile = inifile_init(inipath, myname); if (!inifile) { - xfree (inipath); + xfree(inipath); return NULL; } @@ -45,22 +47,26 @@ explorist_ini_try(const char *path) { } inifile_done(inifile); - xfree (inipath); + xfree(inipath); return info; } mag_info * -explorist_ini_get(const char **dirlist) { +explorist_ini_get(const char **dirlist) +{ mag_info *r = NULL; while (dirlist && *dirlist) { r = explorist_ini_try(*dirlist); - if (r) return r; + if (r) { + return r; + } } return r; } void -explorist_ini_done(mag_info *info) { +explorist_ini_done(mag_info *info) +{ xfree(info->geo_path); xfree(info->track_path); xfree(info->waypoint_path); diff --git a/gpsbabel/fatal.c b/gpsbabel/fatal.c index 30275f474..52a11f095 100644 --- a/gpsbabel/fatal.c +++ b/gpsbabel/fatal.c @@ -23,19 +23,19 @@ void fatal(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); } void warning(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); } diff --git a/gpsbabel/filter_skeleton.c b/gpsbabel/filter_skeleton.c index 8c5651af7..3567b4888 100644 --- a/gpsbabel/filter_skeleton.c +++ b/gpsbabel/filter_skeleton.c @@ -1,11 +1,11 @@ /* - Filter skeleton: - - Simply copy this file to .c and - rename all filter_skeleton tokens to . Replace + Filter skeleton: + + Simply copy this file to .c and + rename all filter_skeleton tokens to . Replace the stupid name and address in the Copyright few lines below. - To active your new filter you have to create a new section in + To active your new filter you have to create a new section in filter_vecs and finally add complying statements to Makefile. Copyright (C) YYYY John Doe, anybody@wherever.com @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" #include @@ -34,13 +34,13 @@ #if FILTERS_ENABLED -// Any arg in this list will appear in command line help and will be +// Any arg in this list will appear in command line help and will be // populated for you. static arglist_t filter_skeleton_args[] = { -// {"foo", &fooopt, "The text of the foo option in help", -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -48,17 +48,17 @@ arglist_t filter_skeleton_args[] = { *******************************************************************************/ static void -filter_skeleton_init(const char *args) +filter_skeleton_init(const char *args) { /* Called before filter processing */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* This may be used to parse filter options, allocate memory, and do other * housekeeping that should be done before filtering */ } -static void +static void filter_skeleton_process(void) /* this procedure must be present in vecs */ { // Here is how you register callbacks for all waypoints, routes, tracks. @@ -68,12 +68,12 @@ filter_skeleton_process(void) /* this procedure must be present in vecs */ } static void -filter_skeleton_deinit(void) +filter_skeleton_deinit(void) { /* called after filter processing */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* This should be used to clean up any memory allocations that are no longer * needed after the filter terminates. */ } @@ -82,12 +82,12 @@ static void filter_skeleton_exit(void) { /* called on program exit */ - + /* optional. If not needed, delete and replace entry in vecs with NULL */ - + /* You should not need this for simple filters, but it may be used to - * clean up memory allocations that must persist from one invocation of - * your filter to the next (for example, the stack in the stack filter.) + * clean up memory allocations that must persist from one invocation of + * your filter to the next (for example, the stack in the stack filter.) * Note that this member will be called even if your filter has not been * used, so it *cannot* assume that _init or _process has been called * previously. */ @@ -96,11 +96,11 @@ filter_skeleton_exit(void) /*******************************************************************************/ filter_vecs_t filter_skeleton_vecs = { - filter_skeleton_init, - filter_skeleton_process, - filter_skeleton_deinit, - filter_skeleton_exit, - filter_skeleton_args + filter_skeleton_init, + filter_skeleton_process, + filter_skeleton_deinit, + filter_skeleton_exit, + filter_skeleton_args }; /*******************************************************************************/ diff --git a/gpsbabel/filter_vecs.c b/gpsbabel/filter_vecs.c index f65d8e12e..c4597c3a3 100644 --- a/gpsbabel/filter_vecs.c +++ b/gpsbabel/filter_vecs.c @@ -1,6 +1,6 @@ /* Describe vectors containing filter operations. - + Copyright (C) 2002,2004,2005,2006,2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -25,9 +25,9 @@ #include "gbversion.h" typedef struct { - filter_vecs_t *vec; - const char *name; - const char *desc; + filter_vecs_t *vec; + const char *name; + const char *desc; } fl_vecs_t; extern filter_vecs_t position_vecs; @@ -50,203 +50,208 @@ extern filter_vecs_t swapdata_vecs; static fl_vecs_t filter_vec_list[] = { #if FILTERS_ENABLED - { - &arcdist_vecs, - "arc", - "Include Only Points Within Distance of Arc", - }, - { - &discard_vecs, - "discard", - "Remove unreliable points with high hdop or vdop" - }, - { - &duplicate_vecs, - "duplicate", - "Remove Duplicates", - }, - { - &interpolatefilt_vecs, - "interpolate", - "Interpolate between trackpoints" - }, - { - &nuke_vecs, - "nuketypes", - "Remove all waypoints, tracks, or routes" - }, - { - &polygon_vecs, - "polygon", - "Include Only Points Inside Polygon", - }, - { - &position_vecs, - "position", - "Remove Points Within Distance", - }, - { - &radius_vecs, - "radius", - "Include Only Points Within Radius", - }, - { - &routesimple_vecs, - "simplify", - "Simplify routes", - }, - { - &sort_vecs, - "sort", - "Rearrange waypoints by resorting", - }, - { - &stackfilt_vecs, - "stack", - "Save and restore waypoint lists" - }, - { - &reverse_route_vecs, - "reverse", - "Reverse stops within routes", - }, - { - &trackfilter_vecs, - "track", - "Manipulate track lists" - }, - { - &transform_vecs, - "transform", - "Transform waypoints into a route, tracks into routes, ..." - }, - { - &height_vecs, - "height", - "Manipulate altitudes" - }, - { - &swapdata_vecs, - "swap", - "Swap latitude and longitude of all loaded points" - }, - + { + &arcdist_vecs, + "arc", + "Include Only Points Within Distance of Arc", + }, + { + &discard_vecs, + "discard", + "Remove unreliable points with high hdop or vdop" + }, + { + &duplicate_vecs, + "duplicate", + "Remove Duplicates", + }, + { + &interpolatefilt_vecs, + "interpolate", + "Interpolate between trackpoints" + }, + { + &nuke_vecs, + "nuketypes", + "Remove all waypoints, tracks, or routes" + }, + { + &polygon_vecs, + "polygon", + "Include Only Points Inside Polygon", + }, + { + &position_vecs, + "position", + "Remove Points Within Distance", + }, + { + &radius_vecs, + "radius", + "Include Only Points Within Radius", + }, + { + &routesimple_vecs, + "simplify", + "Simplify routes", + }, + { + &sort_vecs, + "sort", + "Rearrange waypoints by resorting", + }, + { + &stackfilt_vecs, + "stack", + "Save and restore waypoint lists" + }, + { + &reverse_route_vecs, + "reverse", + "Reverse stops within routes", + }, + { + &trackfilter_vecs, + "track", + "Manipulate track lists" + }, + { + &transform_vecs, + "transform", + "Transform waypoints into a route, tracks into routes, ..." + }, + { + &height_vecs, + "height", + "Manipulate altitudes" + }, + { + &swapdata_vecs, + "swap", + "Swap latitude and longitude of all loaded points" + }, + #elif defined (MINIMAL_FILTERS) - { - &trackfilter_vecs, - "track", - "Manipulate track lists" - }, + { + &trackfilter_vecs, + "track", + "Manipulate track lists" + }, #endif - { - NULL, - NULL, - NULL - } + { + NULL, + NULL, + NULL + } }; filter_vecs_t * find_filter_vec(char *const vecname, char **opts) { - fl_vecs_t *vec = filter_vec_list; - char *v = xstrdup(vecname); - char *svecname = strtok(v, ","); - int found = 0; - - while (vec->vec) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, vec->name)) { - vec++; - continue; - } - - /* step 1: initialize by inifile or default values */ - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++) { - const char *temp; - - temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); - if (temp == NULL) temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); - if (temp == NULL) temp = ap->defaultvalue; - assign_option(vec->name, ap, temp); - } - } - - /* step 2: override settings with command-line values */ - res = strchr(vecname, ','); - if (res) { - *opts = res+1; - - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++){ - char *opt; - - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(vec->name, ap, opt); - xfree(opt); - } - } - } - } - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(vec->name, vec->vec->args); - - xfree(v); - return vec->vec; - - } - xfree(v); - return NULL; + fl_vecs_t *vec = filter_vec_list; + char *v = xstrdup(vecname); + char *svecname = strtok(v, ","); + int found = 0; + + while (vec->vec) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + /* step 1: initialize by inifile or default values */ + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + const char *temp; + + temp = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (temp == NULL) { + temp = inifile_readstr(global_opts.inifile, "Common filter settings", ap->argstring); + } + if (temp == NULL) { + temp = ap->defaultvalue; + } + assign_option(vec->name, ap, temp); + } + } + + /* step 2: override settings with command-line values */ + res = strchr(vecname, ','); + if (res) { + *opts = res+1; + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + char *opt; + + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(vec->name, ap, opt); + xfree(opt); + } + } + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(vec->name, vec->vec->args); + } + + xfree(v); + return vec->vec; + + } + xfree(v); + return NULL; } void -free_filter_vec( filter_vecs_t *fvec ) +free_filter_vec(filter_vecs_t *fvec) { - arglist_t *ap; - - if ( fvec->args ) { - for ( ap = fvec->args; ap->argstring; ap++) { - if (ap->argvalptr) { - xfree(ap->argvalptr); - ap->argvalptr = *ap->argval = NULL; - } - } - } + arglist_t *ap; + + if (fvec->args) { + for (ap = fvec->args; ap->argstring; ap++) { + if (ap->argvalptr) { + xfree(ap->argvalptr); + ap->argvalptr = *ap->argval = NULL; + } + } + } } -void +void init_filter_vecs(void) { - fl_vecs_t *vec = filter_vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - ap->argvalptr = NULL; - } - } - vec++; - } + fl_vecs_t *vec = filter_vec_list; + while (vec->vec) { + arglist_t *ap; + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + ap->argvalptr = NULL; + } + } + vec++; + } } -void -exit_filter_vecs( void ) +void +exit_filter_vecs(void) { - fl_vecs_t *vec = filter_vec_list; - while ( vec->vec ) { - if ( vec->vec->f_exit ) { - (vec->vec->f_exit)(); - } - vec++; - } + fl_vecs_t *vec = filter_vec_list; + while (vec->vec) { + if (vec->vec->f_exit) { + (vec->vec->f_exit)(); + } + vec++; + } } /* @@ -256,81 +261,81 @@ exit_filter_vecs( void ) void disp_filter_vecs(void) { - fl_vecs_t *vec; - arglist_t *ap; - - for (vec = filter_vec_list; vec->vec; vec++) { - printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN )) - printf(" %-18.18s %-.50s %s\n", - ap->argstring, ap->helpstring, - (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); - } - } + fl_vecs_t *vec; + arglist_t *ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } } void -disp_filter_vec( const char *vecname ) +disp_filter_vec(const char *vecname) { - fl_vecs_t *vec; - arglist_t *ap; - - for (vec = filter_vec_list; vec->vec; vec++) { - if ( case_ignore_strcmp( vec->name, vecname )) { - continue; - } - printf(" %-20.20s %-50.50s\n", - vec->name, vec->desc); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN )) - printf(" %-18.18s %-.50s %s\n", - ap->argstring, ap->helpstring, - (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); - } - } + fl_vecs_t *vec; + arglist_t *ap; + + for (vec = filter_vec_list; vec->vec; vec++) { + if (case_ignore_strcmp(vec->name, vecname)) { + continue; + } + printf(" %-20.20s %-50.50s\n", + vec->name, vec->desc); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %-.50s %s\n", + ap->argstring, ap->helpstring, + (ap->argtype&ARGTYPE_REQUIRED)?"(required)":""); + } + } } static signed int -alpha (const void *a, const void *b) +alpha(const void *a, const void *b) { - const fl_vecs_t *const ap = (const fl_vecs_t*) a; - const fl_vecs_t *const bp = (const fl_vecs_t*) b; + const fl_vecs_t *const ap = (const fl_vecs_t*) a; + const fl_vecs_t *const bp = (const fl_vecs_t*) b; - return case_ignore_strcmp(ap->desc , bp->desc); + return case_ignore_strcmp(ap->desc , bp->desc); } -static +static void disp_help_url(const fl_vecs_t *vec, arglist_t *arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); - if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); - } + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } } static void disp_v1(const fl_vecs_t *vec) { - arglist_t *ap; - - disp_help_url(vec, NULL); - printf("\n"); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) { - printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, - ap->argstring, - ap->helpstring, - name_option(ap->argtype), - ap->defaultvalue? ap->defaultvalue : "", - ap->minvalue? ap->minvalue : "", - ap->maxvalue? ap->maxvalue : ""); - disp_help_url(vec, ap); - printf("\n"); - } - } + arglist_t *ap; + + disp_help_url(vec, NULL); + printf("\n"); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + disp_help_url(vec, ap); + printf("\n"); + } + } } /* @@ -341,27 +346,27 @@ disp_v1(const fl_vecs_t *vec) void disp_filters(int version) { - fl_vecs_t *vec; - - qsort(filter_vec_list, - sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, - sizeof(filter_vec_list[0]), - alpha); - - - switch(version) { - case 0: - case 1: - for (vec = filter_vec_list; vec->vec; vec++) { - if (version == 0) { - printf("%s\t%s\n", vec->name, vec->desc); - } else { - printf("%s\t%s", vec->name, vec->desc); - disp_v1(vec); - } - } - break; - default: - ; - } + fl_vecs_t *vec; + + qsort(filter_vec_list, + sizeof(filter_vec_list) / sizeof(filter_vec_list[0]) - 1, + sizeof(filter_vec_list[0]), + alpha); + + + switch (version) { + case 0: + case 1: + for (vec = filter_vec_list; vec->vec; vec++) { + if (version == 0) { + printf("%s\t%s\n", vec->name, vec->desc); + } else { + printf("%s\t%s", vec->name, vec->desc); + disp_v1(vec); + } + } + break; + default: + ; + } } diff --git a/gpsbabel/filterdefs.h b/gpsbabel/filterdefs.h index a7005ed63..e5993222c 100644 --- a/gpsbabel/filterdefs.h +++ b/gpsbabel/filterdefs.h @@ -29,18 +29,18 @@ extern queue waypt_head; typedef struct filter_vecs { - filter_init f_init; - filter_process f_process; - filter_deinit f_deinit; - filter_exit f_exit; - arglist_t *args; + filter_init f_init; + filter_process f_process; + filter_deinit f_deinit; + filter_exit f_exit; + arglist_t *args; } filter_vecs_t; filter_vecs_t * find_filter_vec(char * const, char **); void free_filter_vec(filter_vecs_t *); void disp_filters(int version); -void disp_filter( const char *vecname ); -void disp_filter_vec( const char *vecname ); +void disp_filter(const char *vecname); +void disp_filter_vec(const char *vecname); void disp_filter_vecs(void); void init_filter_vecs(void); void exit_filter_vecs(void); diff --git a/gpsbabel/format_skeleton.c b/gpsbabel/format_skeleton.c index 82285d916..ffcaec373 100644 --- a/gpsbabel/format_skeleton.c +++ b/gpsbabel/format_skeleton.c @@ -4,16 +4,16 @@ Steps to create a new format. - 1) Copy this file to .c - 2) Rename all format_skeleton tokens to . + 1) Copy this file to .c + 2) Rename all format_skeleton tokens to . 3) Replace the fictional name and address in the Copyright section below. As your work is likely built on the work of others, please retain the original line. 4) Create a new section in vecs.c. 5) Add compilation instructions to Makefile. - 6) Add sample files (it's better when they're created by the "real" - application and not our own output) to reference/ along with - files in a well supported (preferably non-binary) format and + 6) Add sample files (it's better when they're created by the "real" + application and not our own output) to reference/ along with + files in a well supported (preferably non-binary) format and entries in our 'testo' program. This allows users of different OSes and hardware to exercise your module. @@ -42,15 +42,15 @@ #define MYNAME "format_skeleton" -// Any arg in this list will appear in command line help and will be +// Any arg in this list will appear in command line help and will be // populated for you. -// Values for ARGTYPE_xxx can be found in defs.h and are used to +// Values for ARGTYPE_xxx can be found in defs.h and are used to // select the type of option. static arglist_t format_skeleton_args[] = { -// {"foo", &fooopt, "The text of the foo option in help", -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR +// {"foo", &fooopt, "The text of the foo option in help", +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -63,7 +63,7 @@ format_skeleton_rd_init(const char *fname) // fin = gbfopen(fname, "r", MYNAME); } -static void +static void format_skeleton_rd_deinit(void) { // gbfclose(fin); @@ -88,18 +88,18 @@ format_skeleton_read(void) // populate waypoint // waypt_add(waypoint); // } -// +// // For routes: -// +// // route = route_head_alloc(); // populate struct route_hdr -// route_add_head(route); +// route_add_head(route); // while (have more routepoints) { // waypoint = waypt_new() // populate waypoint // route_add_wpt(route, waypoint) // } -// +// // Tracks are just like routes, except the word "track" replaces "routes". // } @@ -133,24 +133,24 @@ format_skeleton_exit(void) /* optional */ /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// please change this depending on your new module +// please change this depending on your new module ff_vecs_t format_skeleton_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - format_skeleton_rd_init, - format_skeleton_wr_init, - format_skeleton_rd_deinit, - format_skeleton_wr_deinit, - format_skeleton_read, - format_skeleton_write, - format_skeleton_exit, - format_skeleton_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + format_skeleton_rd_init, + format_skeleton_wr_init, + format_skeleton_rd_deinit, + format_skeleton_wr_deinit, + format_skeleton_read, + format_skeleton_write, + format_skeleton_exit, + format_skeleton_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/formspec.c b/gpsbabel/formspec.c index ce1dbf90b..6e73fe6bb 100644 --- a/gpsbabel/formspec.c +++ b/gpsbabel/formspec.c @@ -1,6 +1,6 @@ /* Functions to manage the format_specific_data chain - + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -25,43 +25,47 @@ #include "defs.h" -format_specific_data *fs_chain_copy( format_specific_data *source ) { - format_specific_data *result = NULL; - - format_specific_data **copy = &result; - while ( source ) { - source->copy( (void **)copy, (void *)source ); - /* prevent segfaults from badly-behaved copy functions */ - (*copy)->next = NULL; - copy = &((*copy)->next); - source = source->next; - } - return result; +format_specific_data *fs_chain_copy(format_specific_data *source) +{ + format_specific_data *result = NULL; + + format_specific_data **copy = &result; + while (source) { + source->copy((void **)copy, (void *)source); + /* prevent segfaults from badly-behaved copy functions */ + (*copy)->next = NULL; + copy = &((*copy)->next); + source = source->next; + } + return result; } -void fs_chain_destroy( format_specific_data *chain ) { - format_specific_data *cur = chain; - format_specific_data *next = NULL; - while ( cur ) { - next = cur->next; - cur->destroy( cur ); - cur = next; - } +void fs_chain_destroy(format_specific_data *chain) +{ + format_specific_data *cur = chain; + format_specific_data *next = NULL; + while (cur) { + next = cur->next; + cur->destroy(cur); + cur = next; + } } -format_specific_data *fs_chain_find( format_specific_data *chain, long type ) { - format_specific_data *cur = chain; - while ( cur ) { - if (cur->type == type ) { - return cur; - } - cur = cur->next; - } - return NULL; +format_specific_data *fs_chain_find(format_specific_data *chain, long type) +{ + format_specific_data *cur = chain; + while (cur) { + if (cur->type == type) { + return cur; + } + cur = cur->next; + } + return NULL; } -void fs_chain_add( format_specific_data **chain, format_specific_data *data ) { - data->next = *chain; - *chain = data; +void fs_chain_add(format_specific_data **chain, format_specific_data *data) +{ + data->next = *chain; + *chain = data; } diff --git a/gpsbabel/g7towin.c b/gpsbabel/g7towin.c index 628d5a303..3e6ba7016 100644 --- a/gpsbabel/g7towin.c +++ b/gpsbabel/g7towin.c @@ -49,7 +49,7 @@ static int event_ct; static arglist_t g7towin_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; #define WAYPT__OFS 0x00000 @@ -72,262 +72,290 @@ arglist_t g7towin_args[] = { static void parse_line(char *buff, int index, const char *delimiter, waypoint *wpt) { - char *cin; - garmin_fs_p gmsd = GMSD_FIND(wpt); - - while ((cin = csv_lineparse(buff, delimiter, "", index++))) { - - buff = NULL; - cin = lrtrim(cin); - - if ((*cin == '\0') || - (strcmp(cin, "INF") == 0) || - (strcmp(cin, "1e25") == 0) || - (strcmp(cin, "1.0e25") == 0)) continue; - - switch(index) { - - int categories, dyn; - struct tm tm; - char *cerr; - - case TRKPT__OFS + 1: - cin += parse_coordinates(cin, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - while (isspace(*cin)) cin++; - - memset(&tm, 0, sizeof(tm)); - cerr = strptime(cin, "%a %b %d %H:%M:%S %Y", &tm); - if (cerr == NULL) { - fatal(MYNAME ": Unable to convert date (%s)!\n", cin); - } - wpt->creation_time = mkgmtime(&tm); - break; - - case WAYPT__OFS + 1: - wpt->description = xstrdup(cin); - break; - - case WAYPT__OFS + 2: - wpt->icon_descr = gt_find_desc_from_icon_number( - atoi(cin), PCX, &dyn); - wpt->wpt_flags.icon_descr_is_dynamic = dyn; - break; - - case WAYPT__OFS + 4: - if (strcmp(cin, "S+C") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_comment); - } - else if (strcmp(cin, "S") == 0) { - GMSD_SET(display, gt_display_mode_symbol); - } - else if (strcmp(cin, "S+N") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_name); - } - break; - - case WPT_cA_OFS + 1: - case WPT_c1_OFS + 1: - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = xstrdup(cin); - break; - - case WPT_cA_OFS + 4: - case WPT_c4_OFS + 2: - GMSD_SETSTR(city, cin); - break; - - case WPT_cA_OFS + 5: - case WPT_c4_OFS + 3: - GMSD_SETSTR(state, cin); - break; - - case WPT_cA_OFS + 6: - case WPT_c4_OFS + 4: - GMSD_SETSTR(cc, cin); - break; - - case WPT_cB_OFS + 1: - case WPT_c6_OFS + 2: - GMSD_SETSTR(facility, cin); - break; - - case WPT_cB_OFS + 2: - case WPT_c6_OFS + 3: - GMSD_SETSTR(addr, cin); - break; - - case WPT_cB_OFS + 3: /*cross road */ - case WPT_c6_OFS + 4: - GMSD_SETSTR(cross_road, cin); - break; - - case TRKPT__OFS + 2: /* altitude */ - case WPT_cC_OFS + 1: - case WPT_c5_OFS + 1: - case WPT_c8_OFS + 1: - wpt->altitude = altf * atof(cin); - break; - - case TRKPT__OFS + 3: /* depth */ - case WPT_cC_OFS + 2: - case WPT_c5_OFS + 2: - case WPT_c8_OFS + 2: - WAYPT_SET(wpt, depth, altf * atof(cin)); - break; - - case TRKPT__OFS + 10: /* temperature */ - if (*cin == '|') cin++; /* in track points */ - if (strcmp(cin, "1e25") == 0) break; - if (strcmp(cin, "1.0e25") == 0) break; - /* !!! NO BREAK !!! */ - case WPT_cD_OFS + 1: - case WPT_cB_OFS + 6: - WAYPT_SET(wpt, temperature, atof(cin)); - break; - - case WAYPT__OFS + 6: /* proximity */ - case WPT_cD_OFS + 2: - WAYPT_SET(wpt, proximity, atof(cin)); - break; - - case WPT_cB_OFS + 5: - case WPT_cD_OFS + 3: - categories = atoi(cin); - if (categories != 0) - GMSD_SET(category, atoi(cin)); - break; - + char *cin; + garmin_fs_p gmsd = GMSD_FIND(wpt); + + while ((cin = csv_lineparse(buff, delimiter, "", index++))) { + + buff = NULL; + cin = lrtrim(cin); + + if ((*cin == '\0') || + (strcmp(cin, "INF") == 0) || + (strcmp(cin, "1e25") == 0) || + (strcmp(cin, "1.0e25") == 0)) { + continue; + } + + switch (index) { + + int categories, dyn; + struct tm tm; + char *cerr; + + case TRKPT__OFS + 1: + cin += parse_coordinates(cin, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*cin)) { + cin++; + } + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(cin, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) { + fatal(MYNAME ": Unable to convert date (%s)!\n", cin); + } + wpt->creation_time = mkgmtime(&tm); + break; + + case WAYPT__OFS + 1: + wpt->description = xstrdup(cin); + break; + + case WAYPT__OFS + 2: + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cin), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + break; + + case WAYPT__OFS + 4: + if (strcmp(cin, "S+C") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } else if (strcmp(cin, "S") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } else if (strcmp(cin, "S+N") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + + case WPT_cA_OFS + 1: + case WPT_c1_OFS + 1: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(cin); + break; + + case WPT_cA_OFS + 4: + case WPT_c4_OFS + 2: + GMSD_SETSTR(city, cin); + break; + + case WPT_cA_OFS + 5: + case WPT_c4_OFS + 3: + GMSD_SETSTR(state, cin); + break; + + case WPT_cA_OFS + 6: + case WPT_c4_OFS + 4: + GMSD_SETSTR(cc, cin); + break; + + case WPT_cB_OFS + 1: + case WPT_c6_OFS + 2: + GMSD_SETSTR(facility, cin); + break; + + case WPT_cB_OFS + 2: + case WPT_c6_OFS + 3: + GMSD_SETSTR(addr, cin); + break; + + case WPT_cB_OFS + 3: /*cross road */ + case WPT_c6_OFS + 4: + GMSD_SETSTR(cross_road, cin); + break; + + case TRKPT__OFS + 2: /* altitude */ + case WPT_cC_OFS + 1: + case WPT_c5_OFS + 1: + case WPT_c8_OFS + 1: + wpt->altitude = altf * atof(cin); + break; + + case TRKPT__OFS + 3: /* depth */ + case WPT_cC_OFS + 2: + case WPT_c5_OFS + 2: + case WPT_c8_OFS + 2: + WAYPT_SET(wpt, depth, altf * atof(cin)); + break; + + case TRKPT__OFS + 10: /* temperature */ + if (*cin == '|') { + cin++; /* in track points */ + } + if (strcmp(cin, "1e25") == 0) { + break; + } + if (strcmp(cin, "1.0e25") == 0) { + break; + } + /* !!! NO BREAK !!! */ + case WPT_cD_OFS + 1: + case WPT_cB_OFS + 6: + WAYPT_SET(wpt, temperature, atof(cin)); + break; + + case WAYPT__OFS + 6: /* proximity */ + case WPT_cD_OFS + 2: + WAYPT_SET(wpt, proximity, atof(cin)); + break; + + case WPT_cB_OFS + 5: + case WPT_cD_OFS + 3: + categories = atoi(cin); + if (categories != 0) { + GMSD_SET(category, atoi(cin)); + } + break; + #if 0 -/* currently unused */ - - case TRKPT__OFS + 5: /* distance from previous point */ - case TRKPT__OFS + 6: /* distance from segment start */ - case TRKPT__OFS + 7: /* distance from start */ - case TRKPT__OFS + 8: /* velocity from previous point */ - case TRKPT__OFS + 9: /* time (in seconds) from previous point */ - break; - - case WAYPT__OFS + 3: /* ignore color */ - break; - - case WAYPT__OFS + 5: /* always '0' */ - break; - - case TRKPT__OFS + 4: - if (case_ignore_strcmp(cin, "FT") == 0) ; - else if (case_ignore_strcmp(cin, "M") == 0) ; - else if (case_ignore_strcmp(cin, "SM") == 0) ; - else if (case_ignore_strcmp(cin, "NM") == 0) ; - else if (case_ignore_strcmp(cin, "KM") == 0) ; - break; - - case WPT_cB_OFS + 4: /* unknown (datatype) */ - break; - - case WPT_cC_OFS + 3: /* waypt_class (always FF) */ - break; - - case WPT_cC_OFS + 4: /* class & subclass */ - case WPT_cC_OFS + 5: - case WPT_cC_OFS + 6: - case WPT_cC_OFS + 7: - case WPT_cC_OFS + 8: - case WPT_cC_OFS + 9: - case WPT_cC_OFS + 10: - case WPT_cC_OFS + 11: - case WPT_cC_OFS + 12: - case WPT_cC_OFS + 13: - case WPT_cC_OFS + 14: - case WPT_cC_OFS + 15: - case WPT_cC_OFS + 16: - case WPT_cC_OFS + 17: - case WPT_cC_OFS + 18: - case WPT_cC_OFS + 19: - case WPT_cC_OFS + 20: - case WPT_cC_OFS + 21: - break; - - case WPT_cC_OFS + 22: - /* distance */ - break; + /* currently unused */ + + case TRKPT__OFS + 5: /* distance from previous point */ + case TRKPT__OFS + 6: /* distance from segment start */ + case TRKPT__OFS + 7: /* distance from start */ + case TRKPT__OFS + 8: /* velocity from previous point */ + case TRKPT__OFS + 9: /* time (in seconds) from previous point */ + break; + + case WAYPT__OFS + 3: /* ignore color */ + break; + + case WAYPT__OFS + 5: /* always '0' */ + break; + + case TRKPT__OFS + 4: + if (case_ignore_strcmp(cin, "FT") == 0) ; + else if (case_ignore_strcmp(cin, "M") == 0) ; + else if (case_ignore_strcmp(cin, "SM") == 0) ; + else if (case_ignore_strcmp(cin, "NM") == 0) ; + else if (case_ignore_strcmp(cin, "KM") == 0) ; + break; + + case WPT_cB_OFS + 4: /* unknown (datatype) */ + break; + + case WPT_cC_OFS + 3: /* waypt_class (always FF) */ + break; + + case WPT_cC_OFS + 4: /* class & subclass */ + case WPT_cC_OFS + 5: + case WPT_cC_OFS + 6: + case WPT_cC_OFS + 7: + case WPT_cC_OFS + 8: + case WPT_cC_OFS + 9: + case WPT_cC_OFS + 10: + case WPT_cC_OFS + 11: + case WPT_cC_OFS + 12: + case WPT_cC_OFS + 13: + case WPT_cC_OFS + 14: + case WPT_cC_OFS + 15: + case WPT_cC_OFS + 16: + case WPT_cC_OFS + 17: + case WPT_cC_OFS + 18: + case WPT_cC_OFS + 19: + case WPT_cC_OFS + 20: + case WPT_cC_OFS + 21: + break; + + case WPT_cC_OFS + 22: + /* distance */ + break; #endif - } - } + } + } } static waypoint * parse_waypt(char *buff) { - char *cin, *cerr; - int i; - struct tm tm; - waypoint *wpt; - garmin_fs_p gmsd; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - if (gardown) - cin = buff + 6; - else { - /* We've seen waypoints with length of 14 and 15 !!! */ - cin = buff + 15; - while ((cin > buff) && (! isspace(*cin))) cin--; - } - - while (isspace(*cin)) cin--; - if (cin >= buff) - wpt->shortname = xstrndup(buff, cin - buff + 1); - - if (gardown) - buff += 6; - else - buff += 15; - while (isspace(*buff)) buff++; - - buff += parse_coordinates(buff, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - while (isspace(*buff)) buff++; - - memset(&tm, 0, sizeof(tm)); - cerr = strptime(buff, "%a %b %d %H:%M:%S %Y", &tm); - if (cerr == NULL) - fatal(MYNAME ": Unable to convert date (%s)!\n", buff); - wpt->creation_time = mkgmtime(&tm); - - /* go over time stamp */ - i = 5; - while (buff && i) { - i--; - buff = strchr(buff, ' '); - if (buff) buff++; - } - if (gardown && (buff == NULL)) return wpt; - is_fatal((buff == NULL), MYNAME ": Incomplete waypoint line!"); - - while (isspace(*buff)) buff++; - - parse_line(buff, WAYPT__OFS, "^", wpt); - - return wpt; + char *cin, *cerr; + int i; + struct tm tm; + waypoint *wpt; + garmin_fs_p gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + if (gardown) { + cin = buff + 6; + } else { + /* We've seen waypoints with length of 14 and 15 !!! */ + cin = buff + 15; + while ((cin > buff) && (! isspace(*cin))) { + cin--; + } + } + + while (isspace(*cin)) { + cin--; + } + if (cin >= buff) { + wpt->shortname = xstrndup(buff, cin - buff + 1); + } + + if (gardown) { + buff += 6; + } else { + buff += 15; + } + while (isspace(*buff)) { + buff++; + } + + buff += parse_coordinates(buff, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + while (isspace(*buff)) { + buff++; + } + + memset(&tm, 0, sizeof(tm)); + cerr = strptime(buff, "%a %b %d %H:%M:%S %Y", &tm); + if (cerr == NULL) { + fatal(MYNAME ": Unable to convert date (%s)!\n", buff); + } + wpt->creation_time = mkgmtime(&tm); + + /* go over time stamp */ + i = 5; + while (buff && i) { + i--; + buff = strchr(buff, ' '); + if (buff) { + buff++; + } + } + if (gardown && (buff == NULL)) { + return wpt; + } + is_fatal((buff == NULL), MYNAME ": Incomplete waypoint line!"); + + while (isspace(*buff)) { + buff++; + } + + parse_line(buff, WAYPT__OFS, "^", wpt); + + return wpt; } static waypoint * parse_trkpt(char *buff) { - garmin_fs_p gmsd; - waypoint *wpt; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - parse_line(buff, TRKPT__OFS, ";", wpt); - - return wpt; + garmin_fs_p gmsd; + waypoint *wpt; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + parse_line(buff, TRKPT__OFS, ";", wpt); + + return wpt; } /* @@ -335,23 +363,25 @@ parse_trkpt(char *buff) * w'll need a central storage with binding to the module * which has established a list of category names. */ - + static void parse_categories(char *buff) { - char *cin; - int cat = 0; - - while ((cin = csv_lineparse(buff, ",", "", cat++))) { - gbuint16 cx; - - buff = NULL; - - cin = lrtrim(cin); - if (*cin == 0) continue; - - garmin_fs_convert_category(cin, &cx); - } + char *cin; + int cat = 0; + + while ((cin = csv_lineparse(buff, ",", "", cat++))) { + gbuint16 cx; + + buff = NULL; + + cin = lrtrim(cin); + if (*cin == 0) { + continue; + } + + garmin_fs_convert_category(cin, &cx); + } } @@ -360,187 +390,215 @@ parse_categories(char *buff) static void rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); - - gardown = 1; - mode = wptdata; - grid = grid_lat_lon_dmm; - datum = DATUM_WGS84; - altf = 1; - event_ct = 0; + fin = gbfopen(fname, "rb", MYNAME); + + gardown = 1; + mode = wptdata; + grid = grid_lat_lon_dmm; + datum = DATUM_WGS84; + altf = 1; + event_ct = 0; } static void rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void data_read(void) { - char *buff; - int line = 0; - waypoint *wpt = NULL; - waypoint *prev = NULL; - route_head *head = NULL; - - while ((buff = gbfgetstr(fin))) { - char *cin = buff; - char *cdata; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - cin = lrtrim(buff); - if (!*cin) continue; - - cdata = cin+1; - while (! isspace(*cdata)) cdata++; - while (isspace(*cdata)) cdata++; - if (! *cdata) continue; - - switch(*cin) { - - case '#': /* comment */ - break; - - case 'A': - if (case_ignore_strncmp(cdata, "Meter", 5) == 0) - altf = 1.0; - else if (case_ignore_strncmp(cdata, "Feet", 4) == 0) - altf = FEET_TO_METERS(1.0); - break; - - case 'C': /* categories */ - parse_categories(cdata); - break; - - case 'D': - datum = gt_lookup_datum_index(cdata, MYNAME); - break; - - case 'I': /* event point */ - wpt = waypt_new(); - cdata += parse_coordinates(cdata, datum, grid, - &wpt->latitude, &wpt->longitude, MYNAME); - xasprintf(&wpt->shortname, "Event%d", ++event_ct); - while (isspace(*cdata)) cdata++; - if (*cdata == ';') { - int dyn; - - cdata++; - wpt->icon_descr = gt_find_desc_from_icon_number( - atoi(cdata), PCX, &dyn); - wpt->wpt_flags.icon_descr_is_dynamic = dyn; - } - waypt_add(wpt); - break; - - case 'M': - grid = gt_lookup_grid_type(cdata, MYNAME); - break; - - case 'P': /* proximity waypoint */ - case 'W': /* normal waypoint */ - wpt = parse_waypt(cin + 3); - prev = wpt; - if (wpt) { - if (mode == rtedata) - route_add_wpt(head, wpt); - else - waypt_add(wpt); - } - break; - - case 'c': /* additional lines */ - switch(*(cin+1)) { - int index; - - case 'A': case 'B': - case 'C': case 'D': - - index = WPT_cA_OFS + ((*(cin+1) - 'A') * 256); - parse_line(cdata, index, "|", wpt); - break; - - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': - - index = WPT_c0_OFS + ((*(cin+1) - '0') * 256); - parse_line(cdata, index, ";", wpt); - break; - - case 'L': - waypt_add_url(wpt, xstrdup(cdata), NULL); - break; - - default: - break; - } - break; - - case 'N': /* track log header */ - mode = trkdata; - head = route_head_alloc(); - cdata = strchr(cdata, '-'); - if (cdata) { - while (isspace(*cdata)) cdata++; - if (*cdata) { - char *s; - s = strrchr(cdata, ','); - if (s) { - *s = '\0'; - s = strrchr(cdata, ','); - if (s) { - *s = '\0'; - head->rte_name = xstrdup(cdata); - } - } - } - } - track_add_head(head); - break; - - case 'R': /* route header */ - mode = rtedata; - head = route_head_alloc(); - cdata += 3; /*skip route number */ - if (*cdata) head->rte_name = xstrdup(cdata); - route_add_head(head); - break; - - case 'T': - wpt = parse_trkpt(cdata); - if (wpt) track_add_wpt(head, wpt); - break; - - case 'V': - if (strcmp(cin, G7T_HEADER) != 0) { - fatal(MYNAME ": Invalid version or invalid file!\n"); - } - gardown = 0; - break; - - default: - break; - } - } + char *buff; + int line = 0; + waypoint *wpt = NULL; + waypoint *prev = NULL; + route_head *head = NULL; + + while ((buff = gbfgetstr(fin))) { + char *cin = buff; + char *cdata; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + cin = lrtrim(buff); + if (!*cin) { + continue; + } + + cdata = cin+1; + while (! isspace(*cdata)) { + cdata++; + } + while (isspace(*cdata)) { + cdata++; + } + if (! *cdata) { + continue; + } + + switch (*cin) { + + case '#': /* comment */ + break; + + case 'A': + if (case_ignore_strncmp(cdata, "Meter", 5) == 0) { + altf = 1.0; + } else if (case_ignore_strncmp(cdata, "Feet", 4) == 0) { + altf = FEET_TO_METERS(1.0); + } + break; + + case 'C': /* categories */ + parse_categories(cdata); + break; + + case 'D': + datum = gt_lookup_datum_index(cdata, MYNAME); + break; + + case 'I': /* event point */ + wpt = waypt_new(); + cdata += parse_coordinates(cdata, datum, grid, + &wpt->latitude, &wpt->longitude, MYNAME); + xasprintf(&wpt->shortname, "Event%d", ++event_ct); + while (isspace(*cdata)) { + cdata++; + } + if (*cdata == ';') { + int dyn; + + cdata++; + wpt->icon_descr = gt_find_desc_from_icon_number( + atoi(cdata), PCX, &dyn); + wpt->wpt_flags.icon_descr_is_dynamic = dyn; + } + waypt_add(wpt); + break; + + case 'M': + grid = gt_lookup_grid_type(cdata, MYNAME); + break; + + case 'P': /* proximity waypoint */ + case 'W': /* normal waypoint */ + wpt = parse_waypt(cin + 3); + prev = wpt; + if (wpt) { + if (mode == rtedata) { + route_add_wpt(head, wpt); + } else { + waypt_add(wpt); + } + } + break; + + case 'c': /* additional lines */ + switch (*(cin+1)) { + int index; + + case 'A': + case 'B': + case 'C': + case 'D': + + index = WPT_cA_OFS + ((*(cin+1) - 'A') * 256); + parse_line(cdata, index, "|", wpt); + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + + index = WPT_c0_OFS + ((*(cin+1) - '0') * 256); + parse_line(cdata, index, ";", wpt); + break; + + case 'L': + waypt_add_url(wpt, xstrdup(cdata), NULL); + break; + + default: + break; + } + break; + + case 'N': /* track log header */ + mode = trkdata; + head = route_head_alloc(); + cdata = strchr(cdata, '-'); + if (cdata) { + while (isspace(*cdata)) { + cdata++; + } + if (*cdata) { + char *s; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + s = strrchr(cdata, ','); + if (s) { + *s = '\0'; + head->rte_name = xstrdup(cdata); + } + } + } + } + track_add_head(head); + break; + + case 'R': /* route header */ + mode = rtedata; + head = route_head_alloc(); + cdata += 3; /*skip route number */ + if (*cdata) { + head->rte_name = xstrdup(cdata); + } + route_add_head(head); + break; + + case 'T': + wpt = parse_trkpt(cdata); + if (wpt) { + track_add_wpt(head, wpt); + } + break; + + case 'V': + if (strcmp(cin, G7T_HEADER) != 0) { + fatal(MYNAME ": Invalid version or invalid file!\n"); + } + gardown = 0; + break; + + default: + break; + } + } } /* --------------------------------------------------------------------------- */ ff_vecs_t g7towin_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_read }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - g7towin_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_read }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + g7towin_args, + CET_CHARSET_MS_ANSI, 0 }; #endif /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/garmin.c b/gpsbabel/garmin.c index 73155d5f7..0f57f8b08 100644 --- a/gpsbabel/garmin.c +++ b/gpsbabel/garmin.c @@ -1,6 +1,6 @@ /* Jeeps wrapper for Garmin serial protocol. - + Copyright (C) 2002, 2003, 2004, 2005, 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ #define SOON 1 -#define MYNAME "GARMIN" +#define MYNAME "GARMIN" static const char *portname; static short_handle mkshort_handle; static GPS_PWay *tx_waylist; @@ -41,7 +41,7 @@ static GPS_PTrack *cur_tx_tracklist_entry; static int my_track_count = 0; static char *getposn = NULL; static char *poweroff = NULL; -static char *eraset = NULL; +static char *eraset = NULL; static char *resettime = NULL; static char *snlen = NULL; static char *snwhiteopt = NULL; @@ -60,24 +60,40 @@ static const char *valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " "; static arglist_t garmin_args[] = { - { "snlen", &snlen, "Length of generated shortnames", NULL, - ARGTYPE_INT, "1", NULL }, - { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "get_posn", &getposn, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "power_off", &poweroff, "Command unit to power itself down", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "erase_t", &eraset, "Erase existing courses when writing new ones", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "resettime", &resettime, "Sync GPS time to computer time", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "category", &category, "Category number to use for written waypoints", - NULL, ARGTYPE_INT, "1", "16"}, - { "bitscategory", &categorybitsopt, "Bitmap of categories", - NULL, ARGTYPE_INT, "1", "65535"}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "get_posn", &getposn, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_t", &eraset, "Erase existing courses when writing new ones", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "resettime", &resettime, "Sync GPS time to computer time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "category", &category, "Category number to use for written waypoints", + NULL, ARGTYPE_INT, "1", "16" + }, + { + "bitscategory", &categorybitsopt, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535" + }, + ARG_TERMINATOR }; static const char * d103_symbol_from_icon_number(unsigned int n); @@ -87,465 +103,479 @@ static int d103_icon_number_from_symbol(const char *s); static void rw_init(const char *fname) { - int receiver_short_length; - int receiver_must_upper = 1; - char * receiver_charset = NULL; - - if (!mkshort_handle) - mkshort_handle = mkshort_new_handle(); - - if (global_opts.debug_level > 0) { - GPS_Enable_Warning(); - GPS_Enable_User(); - } - if (global_opts.debug_level > 1) { - GPS_Enable_Diagnose(); - } - GPS_Enable_Error(); - - if (poweroff) { - GPS_Command_Off(fname); - return; - } - - /* - * THis is Gross. The B&W Vista sometimes sets its time decades into - * the future with no way to reset it. This apparently can "cure" - * an affected unit. - */ - if (resettime) { - GPS_Command_Send_Time(fname, current_time()); - return; - } - - if (categorybitsopt) { - categorybits = strtol(categorybitsopt, NULL, 0); - } - - if (GPS_Init(fname) < 0) { - fatal(MYNAME ":Can't init %s\n", fname); - } - portname = fname; - - /* - * Grope the unit we're talking to to set setshort_length to - * 20 for the V, - * 10 for Street Pilot, (old) Rhino, 76 - * 6 for the III, 12, emap, and etrex - * Fortunately, getting this "wrong" only results in ugly names - * when we're using the synthesize_shortname path. - */ - receiver_short_length = 10; - - switch ( gps_waypt_type ) /* waypoint type as defined by jeeps */ - { - case 0: - fatal("Garmin unit %d does not support waypoint xfer.", - gps_save_id); - - break; - case 100: /* The GARMIN GPS Interface Specification, */ - case 101: /* says these waypoint types use an ident */ - case 102: /* length of 6. Waypoint types 106, 108 */ - case 103: /* and 109 are all variable length */ - case 104: - case 105: - case 107: - case 150: - case 151: - case 152: - case 154: - case 155: - receiver_short_length = 6; - break; - case 106: /* Waypoint types with variable ident length */ - case 108: /* Need GPSr id to know the actual length */ - case 109: - case 110: - switch ( gps_save_id ) - { - case 130: /* Garmin Etrex (yellow) */ - receiver_short_length = 6; - break; - case 295: /* eTrex (yellow, fw v. 3.30) */ - case 696: /* eTrex HC */ - case 574: /* Geko 201 */ - receiver_short_length = 6; - valid_waypt_chars = - MILITANT_VALID_WAYPT_CHARS " +-"; - setshort_badchars(mkshort_handle, "\"$.,'!"); - break; - - case 155: /* Garmin V */ - case 404: /* SP2720 */ - case 520: /* SP2820 */ - receiver_short_length = 20; - break; - case 382: /* C320 */ - receiver_short_length = 30; - receiver_must_upper = 0; - break; - case 292: /* (60|76)C[S]x series */ - case 421: /* Vista|Legend Cx */ - case 694: /* Legend HCx */ - case 695: /* Vista HC */ - case 786: /* HC model */ - case 957: /* Legend HC */ - receiver_short_length = 14; - snwhiteopt = xstrdup("1"); - receiver_must_upper = 0; - /* This might be 8859-1 */ - receiver_charset = CET_CHARSET_MS_ANSI; - break; - case 291: /* GPSMAP 60CS, probably others */ - case 1095: /* GPS 72H */ - receiver_short_length = 10; - valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-"; - setshort_badchars(mkshort_handle, "\"$.,'!"); - break; - case 231: /* Quest */ - case 463: /* Quest 2 */ - receiver_must_upper = 0; - receiver_short_length = 30; - receiver_charset = CET_CHARSET_MS_ANSI; - break; - case 577: // Rino 530HCx Version 2.50 - receiver_must_upper = 0; - receiver_short_length = 14; - break; - case 429: // Streetpilot i3 - receiver_must_upper = 0; - receiver_charset = CET_CHARSET_MS_ANSI; - receiver_short_length = 30; - break; - case 484: // Forerunner 305 - receiver_short_length = 8; - break; - case 260: /* GPSMap 296 */ - default: - break; - } - break; - default: - break; - - } - - // If a user has specified a non-default character set, we'll trust - // them to sort our the wreckage of violating the Garmin protocol and - // ship characters to the device in that character set. - if (global_opts.charset != &cet_cs_vec_utf8) { - receiver_charset = global_opts.charset_name; - } - if (global_opts.debug_level > 0) { - fprintf(stderr, "Waypoint type: %d\n" - "Chosen waypoint length %d\n", - gps_waypt_type, receiver_short_length); - if (gps_category_type) { - fprintf(stderr, "Waypoint category type: %d\n", - gps_category_type); - } - } - - // Allow override of sent character set for internationalized GPSes. - if (global_opts.charset != &cet_cs_vec_utf8) - receiver_charset = xstrdup(global_opts.charset_name); - - /* - * If the user provided a short_length, override the calculated value. - */ - if (snlen) - setshort_length(mkshort_handle, atoi(snlen)); - else - setshort_length(mkshort_handle, receiver_short_length); - - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); - - /* - * Until Garmins documents how to determine valid character space - * for the new models, we just release this safety check manually. - */ - if (receiver_must_upper) { - setshort_goodchars(mkshort_handle, valid_waypt_chars); - } else { - setshort_badchars(mkshort_handle, ""); - } - - setshort_mustupper(mkshort_handle, receiver_must_upper); - - if (receiver_charset) - cet_convert_init(receiver_charset, 1); + int receiver_short_length; + int receiver_must_upper = 1; + char * receiver_charset = NULL; + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + if (global_opts.debug_level > 0) { + GPS_Enable_Warning(); + GPS_Enable_User(); + } + if (global_opts.debug_level > 1) { + GPS_Enable_Diagnose(); + } + GPS_Enable_Error(); + + if (poweroff) { + GPS_Command_Off(fname); + return; + } + + /* + * THis is Gross. The B&W Vista sometimes sets its time decades into + * the future with no way to reset it. This apparently can "cure" + * an affected unit. + */ + if (resettime) { + GPS_Command_Send_Time(fname, current_time()); + return; + } + + if (categorybitsopt) { + categorybits = strtol(categorybitsopt, NULL, 0); + } + + if (GPS_Init(fname) < 0) { + fatal(MYNAME ":Can't init %s\n", fname); + } + portname = fname; + + /* + * Grope the unit we're talking to to set setshort_length to + * 20 for the V, + * 10 for Street Pilot, (old) Rhino, 76 + * 6 for the III, 12, emap, and etrex + * Fortunately, getting this "wrong" only results in ugly names + * when we're using the synthesize_shortname path. + */ + receiver_short_length = 10; + + switch (gps_waypt_type) { /* waypoint type as defined by jeeps */ + case 0: + fatal("Garmin unit %d does not support waypoint xfer.", + gps_save_id); + + break; + case 100: /* The GARMIN GPS Interface Specification, */ + case 101: /* says these waypoint types use an ident */ + case 102: /* length of 6. Waypoint types 106, 108 */ + case 103: /* and 109 are all variable length */ + case 104: + case 105: + case 107: + case 150: + case 151: + case 152: + case 154: + case 155: + receiver_short_length = 6; + break; + case 106: /* Waypoint types with variable ident length */ + case 108: /* Need GPSr id to know the actual length */ + case 109: + case 110: + switch (gps_save_id) { + case 130: /* Garmin Etrex (yellow) */ + receiver_short_length = 6; + break; + case 295: /* eTrex (yellow, fw v. 3.30) */ + case 696: /* eTrex HC */ + case 574: /* Geko 201 */ + receiver_short_length = 6; + valid_waypt_chars = + MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + + case 155: /* Garmin V */ + case 404: /* SP2720 */ + case 520: /* SP2820 */ + receiver_short_length = 20; + break; + case 382: /* C320 */ + receiver_short_length = 30; + receiver_must_upper = 0; + break; + case 292: /* (60|76)C[S]x series */ + case 421: /* Vista|Legend Cx */ + case 694: /* Legend HCx */ + case 695: /* Vista HC */ + case 786: /* HC model */ + case 957: /* Legend HC */ + receiver_short_length = 14; + snwhiteopt = xstrdup("1"); + receiver_must_upper = 0; + /* This might be 8859-1 */ + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 291: /* GPSMAP 60CS, probably others */ + case 1095: /* GPS 72H */ + receiver_short_length = 10; + valid_waypt_chars = MILITANT_VALID_WAYPT_CHARS " +-"; + setshort_badchars(mkshort_handle, "\"$.,'!"); + break; + case 231: /* Quest */ + case 463: /* Quest 2 */ + receiver_must_upper = 0; + receiver_short_length = 30; + receiver_charset = CET_CHARSET_MS_ANSI; + break; + case 577: // Rino 530HCx Version 2.50 + receiver_must_upper = 0; + receiver_short_length = 14; + break; + case 429: // Streetpilot i3 + receiver_must_upper = 0; + receiver_charset = CET_CHARSET_MS_ANSI; + receiver_short_length = 30; + break; + case 484: // Forerunner 305 + receiver_short_length = 8; + break; + case 260: /* GPSMap 296 */ + default: + break; + } + break; + default: + break; + + } + + // If a user has specified a non-default character set, we'll trust + // them to sort our the wreckage of violating the Garmin protocol and + // ship characters to the device in that character set. + if (global_opts.charset != &cet_cs_vec_utf8) { + receiver_charset = global_opts.charset_name; + } + if (global_opts.debug_level > 0) { + fprintf(stderr, "Waypoint type: %d\n" + "Chosen waypoint length %d\n", + gps_waypt_type, receiver_short_length); + if (gps_category_type) { + fprintf(stderr, "Waypoint category type: %d\n", + gps_category_type); + } + } + + // Allow override of sent character set for internationalized GPSes. + if (global_opts.charset != &cet_cs_vec_utf8) { + receiver_charset = xstrdup(global_opts.charset_name); + } + + /* + * If the user provided a short_length, override the calculated value. + */ + if (snlen) { + setshort_length(mkshort_handle, atoi(snlen)); + } else { + setshort_length(mkshort_handle, receiver_short_length); + } + + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } + + /* + * Until Garmins documents how to determine valid character space + * for the new models, we just release this safety check manually. + */ + if (receiver_must_upper) { + setshort_goodchars(mkshort_handle, valid_waypt_chars); + } else { + setshort_badchars(mkshort_handle, ""); + } + + setshort_mustupper(mkshort_handle, receiver_must_upper); + + if (receiver_charset) { + cet_convert_init(receiver_charset, 1); + } } static void -rd_init(const char *fname) +rd_init(const char *fname) { - if (setjmp(gdx_jmp_buf)) { - char *vec_opts = NULL; - const gdx_info *gi = gdx_get_info(); - gpx_vec = find_vec("gpx", &vec_opts); - gpx_vec->rd_init(gi->from_device.canon); - } else { - gpx_vec = NULL; - rw_init(fname); - } + if (setjmp(gdx_jmp_buf)) { + char *vec_opts = NULL; + const gdx_info *gi = gdx_get_info(); + gpx_vec = find_vec("gpx", &vec_opts); + gpx_vec->rd_init(gi->from_device.canon); + } else { + gpx_vec = NULL; + rw_init(fname); + } } static void rw_deinit(void) { - if (mkshort_handle) { - mkshort_del_handle(&mkshort_handle); - } + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } } static int waypt_read_cb(int total_ct, GPS_PWay *way) { - static int i; + static int i; - if (global_opts.verbose_status) { - i++; - waypt_status_disp(total_ct, i); - } - return 0; + if (global_opts.verbose_status) { + i++; + waypt_status_disp(total_ct, i); + } + return 0; } static void waypt_read(void) { - int i,n; - GPS_PWay *way = NULL; - - if (getposn) { - waypoint *wpt = waypt_new(); - wpt->latitude = gps_save_lat; - wpt->longitude = gps_save_lon; - wpt->shortname = xstrdup("Position"); - if (gps_save_time) - wpt->creation_time = gps_save_time; - waypt_add(wpt); - return; - } - - if ((n = GPS_Command_Get_Waypoint(portname, &way, waypt_read_cb)) < 0) { - fatal(MYNAME ":Can't get waypoint from %s\n", portname); - } - - for (i = 0; i < n; i++) { - waypoint *wpt_tmp = waypt_new(); - - wpt_tmp->shortname = xstrdup(way[i]->ident); - wpt_tmp->description = xstrdup(way[i]->cmnt); - rtrim(wpt_tmp->shortname); - rtrim(wpt_tmp->description); - wpt_tmp->longitude = way[i]->lon; - wpt_tmp->latitude = way[i]->lat; - if (gps_waypt_type == 103) { - wpt_tmp->icon_descr = d103_symbol_from_icon_number( - way[i]->smbl); - } else { - int dyn = 0; - wpt_tmp->icon_descr = gt_find_desc_from_icon_number( - way[i]->smbl, PCX, &dyn); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; - } - /* - * If a unit doesn't store altitude info (i.e. a D103) - * gpsmem will default the alt to INT_MAX. Other units - * (I can't recall if it was the V (D109) hor the Vista (D108) - * return INT_MAX+1, contrary to the Garmin protocol doc which - * says they should report 1.0e25. So we'll try to trap - * all the cases here. Yes, libjeeps should probably - * do this and not us... - */ - if ((way[i]->alt == (float) (1U<<31)) || - (way[i]->alt == INT_MAX) || - (way[i]->alt >= (float) 1.0e20) - ) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = way[i]->alt; - } - if (way[i]->time_populated) { - wpt_tmp->creation_time = way[i]->time; - } + int i,n; + GPS_PWay *way = NULL; + + if (getposn) { + waypoint *wpt = waypt_new(); + wpt->latitude = gps_save_lat; + wpt->longitude = gps_save_lon; + wpt->shortname = xstrdup("Position"); + if (gps_save_time) { + wpt->creation_time = gps_save_time; + } + waypt_add(wpt); + return; + } + + if ((n = GPS_Command_Get_Waypoint(portname, &way, waypt_read_cb)) < 0) { + fatal(MYNAME ":Can't get waypoint from %s\n", portname); + } + + for (i = 0; i < n; i++) { + waypoint *wpt_tmp = waypt_new(); + + wpt_tmp->shortname = xstrdup(way[i]->ident); + wpt_tmp->description = xstrdup(way[i]->cmnt); + rtrim(wpt_tmp->shortname); + rtrim(wpt_tmp->description); + wpt_tmp->longitude = way[i]->lon; + wpt_tmp->latitude = way[i]->lat; + if (gps_waypt_type == 103) { + wpt_tmp->icon_descr = d103_symbol_from_icon_number( + way[i]->smbl); + } else { + int dyn = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number( + way[i]->smbl, PCX, &dyn); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = dyn; + } + /* + * If a unit doesn't store altitude info (i.e. a D103) + * gpsmem will default the alt to INT_MAX. Other units + * (I can't recall if it was the V (D109) hor the Vista (D108) + * return INT_MAX+1, contrary to the Garmin protocol doc which + * says they should report 1.0e25. So we'll try to trap + * all the cases here. Yes, libjeeps should probably + * do this and not us... + */ + if ((way[i]->alt == (float)(1U<<31)) || + (way[i]->alt == INT_MAX) || + (way[i]->alt >= (float) 1.0e20) + ) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = way[i]->alt; + } + if (way[i]->time_populated) { + wpt_tmp->creation_time = way[i]->time; + } #if SOON - garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); -#endif - waypt_add(wpt_tmp); - GPS_Way_Del(&way[i]); - } - if (way) { - xfree(way); - } + garmin_fs_garmin_after_read(way[i], wpt_tmp, gps_waypt_type); +#endif + waypt_add(wpt_tmp); + GPS_Way_Del(&way[i]); + } + if (way) { + xfree(way); + } } static int lap_read_nop_cb(int n, struct GPS_SWay** dp) { - return 0; + return 0; } // returns 1 if the waypoint's start_time can be found // in the laps array, 0 otherwise unsigned int checkWayPointIsAtSplit(waypoint *wpt, GPS_PLap *laps, int nlaps) { - int result = 0; - - if ((laps != NULL) && (nlaps > 0)) { - int i; - for (i=(nlaps-1); i >= 0; i--) { - GPS_PLap lap = laps[i]; - time_t delta = lap->start_time - wpt->creation_time; - if ((delta >= -1) && (delta <= 1)) { - result = 1; - break; - - // as an optimization this will stop going through - // the lap array when the negative delta gets too - // big. It assumes that laps is sorted by time in - // ascending order (which appears to be the case for - // Forerunners. Don't know about other devices. - } else if (delta < -1) { - break; - } - } + int result = 0; + + if ((laps != NULL) && (nlaps > 0)) { + int i; + for (i=(nlaps-1); i >= 0; i--) { + GPS_PLap lap = laps[i]; + time_t delta = lap->start_time - wpt->creation_time; + if ((delta >= -1) && (delta <= 1)) { + result = 1; + break; + + // as an optimization this will stop going through + // the lap array when the negative delta gets too + // big. It assumes that laps is sorted by time in + // ascending order (which appears to be the case for + // Forerunners. Don't know about other devices. + } else if (delta < -1) { + break; + } } + } - return result; + return result; } static void track_read(void) { - int32 ntracks; - GPS_PTrack *array; - route_head *trk_head = NULL; - int trk_num = 0; - int i; - char *trk_name = ""; - GPS_PLap* laps = NULL; - int nlaps = 0; - int next_is_new_trkseg = 0; - - if (gps_lap_type != -1) { - nlaps = GPS_Command_Get_Lap(portname, &laps, &lap_read_nop_cb); - } - - - ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); - - if ( ntracks <= 0 ) - return; - - for(i = 0; i < ntracks; i++) { - waypoint *wpt; - - /* - * This is probably always in slot zero, but the Garmin - * serial spec says these can appear anywhere. Toss them - * out so we don't treat it as an extraneous trackpoint. - */ - if (array[i]->ishdr) { - trk_name = array[i]->trk_ident; - if (!trk_name) - trk_name = ""; - } - - if (trk_head == NULL || array[i]->ishdr) { - trk_head = route_head_alloc(); - trk_head->rte_num = trk_num; - trk_head->rte_name = xstrdup(trk_name); - trk_num++; - track_add_head(trk_head); - } - - /* Need to do this here because fitness devices set tnew - * on a trackpoint without lat/lon. - */ - if (array[i]->tnew) - next_is_new_trkseg = 1; - - if (array[i]->no_latlon || array[i]->ishdr) { - continue; - } - wpt = waypt_new(); - - wpt->longitude = array[i]->lon; - wpt->latitude = array[i]->lat; - wpt->altitude = array[i]->alt; - wpt->heartrate = array[i]->heartrate; - wpt->cadence = array[i]->cadence; - wpt->shortname = xstrdup(array[i]->trk_ident); - wpt->creation_time = array[i]->Time; - wpt->wpt_flags.is_split = checkWayPointIsAtSplit(wpt, laps, - nlaps); - wpt->wpt_flags.new_trkseg = next_is_new_trkseg; - next_is_new_trkseg = 0; - - if (array[i]->dpth < 1.0e25f) - WAYPT_SET(wpt, depth, array[i]->dpth); - if (array[i]->temperature_populated) - WAYPT_SET(wpt, temperature, array[i]->temperature); - - track_add_wpt(trk_head, wpt); - } - - while(ntracks) { - GPS_Track_Del(&array[--ntracks]); - } - xfree(array); + int32 ntracks; + GPS_PTrack *array; + route_head *trk_head = NULL; + int trk_num = 0; + int i; + char *trk_name = ""; + GPS_PLap* laps = NULL; + int nlaps = 0; + int next_is_new_trkseg = 0; + + if (gps_lap_type != -1) { + nlaps = GPS_Command_Get_Lap(portname, &laps, &lap_read_nop_cb); + } + + + ntracks = GPS_Command_Get_Track(portname, &array, waypt_read_cb); + + if (ntracks <= 0) { + return; + } + + for (i = 0; i < ntracks; i++) { + waypoint *wpt; + + /* + * This is probably always in slot zero, but the Garmin + * serial spec says these can appear anywhere. Toss them + * out so we don't treat it as an extraneous trackpoint. + */ + if (array[i]->ishdr) { + trk_name = array[i]->trk_ident; + if (!trk_name) { + trk_name = ""; + } + } + + if (trk_head == NULL || array[i]->ishdr) { + trk_head = route_head_alloc(); + trk_head->rte_num = trk_num; + trk_head->rte_name = xstrdup(trk_name); + trk_num++; + track_add_head(trk_head); + } + + /* Need to do this here because fitness devices set tnew + * on a trackpoint without lat/lon. + */ + if (array[i]->tnew) { + next_is_new_trkseg = 1; + } + + if (array[i]->no_latlon || array[i]->ishdr) { + continue; + } + wpt = waypt_new(); + + wpt->longitude = array[i]->lon; + wpt->latitude = array[i]->lat; + wpt->altitude = array[i]->alt; + wpt->heartrate = array[i]->heartrate; + wpt->cadence = array[i]->cadence; + wpt->shortname = xstrdup(array[i]->trk_ident); + wpt->creation_time = array[i]->Time; + wpt->wpt_flags.is_split = checkWayPointIsAtSplit(wpt, laps, + nlaps); + wpt->wpt_flags.new_trkseg = next_is_new_trkseg; + next_is_new_trkseg = 0; + + if (array[i]->dpth < 1.0e25f) { + WAYPT_SET(wpt, depth, array[i]->dpth); + } + if (array[i]->temperature_populated) { + WAYPT_SET(wpt, temperature, array[i]->temperature); + } + + track_add_wpt(trk_head, wpt); + } + + while (ntracks) { + GPS_Track_Del(&array[--ntracks]); + } + xfree(array); } static void route_read(void) { - int32 nroutepts; - int i; - GPS_PWay *array; - /* TODO: Fixes warning but is it right? - * RJL: No, the warning isn't right; GCC's flow analysis is broken. - * still, it's good taste... - */ - route_head *rte_head = NULL; + int32 nroutepts; + int i; + GPS_PWay *array; + /* TODO: Fixes warning but is it right? + * RJL: No, the warning isn't right; GCC's flow analysis is broken. + * still, it's good taste... + */ + route_head *rte_head = NULL; - nroutepts = GPS_Command_Get_Route(portname, &array); + nroutepts = GPS_Command_Get_Route(portname, &array); // fprintf(stderr, "Routes %d\n", (int) nroutepts); #if 1 - for (i = 0; i < nroutepts; i++) { - if (array[i]->isrte) { - char *csrc = NULL; - /* What a horrible API has libjeeps for making this - * my problem. - */ - switch (array[i]->rte_prot) { - case 201: csrc = array[i]->rte_cmnt; break; - case 202: csrc = array[i]->rte_ident; break; - default: break; - } - rte_head = route_head_alloc(); - route_add_head(rte_head); - if (csrc) { - rte_head->rte_name = xstrdup(csrc); - } - } else { - if (array[i]->islink) { - continue; - } else { - waypoint *wpt_tmp = waypt_new(); - wpt_tmp->latitude = array[i]->lat; - wpt_tmp->longitude = array[i]->lon; - wpt_tmp->shortname = array[i]->ident; - route_add_wpt(rte_head, wpt_tmp); - } - } - } + for (i = 0; i < nroutepts; i++) { + if (array[i]->isrte) { + char *csrc = NULL; + /* What a horrible API has libjeeps for making this + * my problem. + */ + switch (array[i]->rte_prot) { + case 201: + csrc = array[i]->rte_cmnt; + break; + case 202: + csrc = array[i]->rte_ident; + break; + default: + break; + } + rte_head = route_head_alloc(); + route_add_head(rte_head); + if (csrc) { + rte_head->rte_name = xstrdup(csrc); + } + } else { + if (array[i]->islink) { + continue; + } else { + waypoint *wpt_tmp = waypt_new(); + wpt_tmp->latitude = array[i]->lat; + wpt_tmp->longitude = array[i]->lon; + wpt_tmp->shortname = array[i]->ident; + route_add_wpt(rte_head, wpt_tmp); + } + } + } #else - GPS_Fmt_Print_Route(array, nroutepts, stderr); + GPS_Fmt_Print_Route(array, nroutepts, stderr); #endif } @@ -555,88 +585,89 @@ static void lap_read_as_track(void) { - int32 ntracks; - GPS_PLap *array; - route_head *trk_head = NULL; - int trk_num = 0; - int index; - int i; - - ntracks = GPS_Command_Get_Lap(portname, &array, waypt_read_cb); - if ( ntracks <= 0 ) - return; - for (i = 0; i < ntracks; i++) { - waypoint *wpt; - if (array[i]->index == -1){ - index=i; - } else { - index=array[i]->index; - index=i; - } - - if ((trk_head == NULL) || (i == 0) || - /* D906 - last track:index is the track index */ - (array[i]->index == -1 && array[i]->track_index != 255) || - /* D10xx - no real separator, use begin/end time to guess */ - (abs(array[i-1]->start_time + array[i]->total_time/100-array[i]->start_time) > 2) - ) { - static struct tm * stmp; - stmp = gmtime(&array[i]->start_time); - trk_head = route_head_alloc(); - /*For D906, we would like to use the track_index in the last packet instead...*/ - trk_head->rte_num = ++trk_num; - trk_head->rte_name = xmalloc(32); - strftime(trk_head->rte_name, 32, "%Y-%m-%dT%H:%M:%SZ", stmp); - track_add_head(trk_head); - - wpt = waypt_new(); - - wpt->longitude = array[i]->begin_lon; - wpt->latitude = array[i]->begin_lat; - wpt->heartrate = array[i]->avg_heart_rate; - wpt->cadence = array[i]->avg_cadence; - wpt->speed = array[i]->max_speed; - wpt->creation_time = array[i]->start_time; - wpt->microseconds = 0; - - wpt->shortname = xmalloc(8); - sprintf(wpt->shortname, "#%d-0", index); - wpt->description = xmalloc(128); - sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d", - array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, - array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method); - - track_add_wpt(trk_head, wpt); - } -/*Allow even if no correct location, no skip if invalid */ -/* if (array[i]->no_latlon) { -* continue; -* } -*/ - wpt = waypt_new(); - - wpt->longitude = array[i]->end_lon; - wpt->latitude = array[i]->end_lat; - wpt->heartrate = array[i]->avg_heart_rate; - wpt->cadence = array[i]->avg_cadence; - wpt->speed = array[i]->max_speed; - wpt->creation_time = array[i]->start_time + array[i]->total_time/100; - wpt->microseconds = 10000*(array[i]->total_time % 100); - /*Add fields with no mapping in the description */ - wpt->shortname = xmalloc(8); - sprintf(wpt->shortname, "#%d", index); - wpt->description = xmalloc(128); - sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d (%f,%f)", - array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, - array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method, - array[i]->begin_lon, array[i]->begin_lat); - - track_add_wpt(trk_head, wpt); - } - while(ntracks) { - GPS_Lap_Del(&array[--ntracks]); - } - xfree(array); + int32 ntracks; + GPS_PLap *array; + route_head *trk_head = NULL; + int trk_num = 0; + int index; + int i; + + ntracks = GPS_Command_Get_Lap(portname, &array, waypt_read_cb); + if (ntracks <= 0) { + return; + } + for (i = 0; i < ntracks; i++) { + waypoint *wpt; + if (array[i]->index == -1) { + index=i; + } else { + index=array[i]->index; + index=i; + } + + if ((trk_head == NULL) || (i == 0) || + /* D906 - last track:index is the track index */ + (array[i]->index == -1 && array[i]->track_index != 255) || + /* D10xx - no real separator, use begin/end time to guess */ + (abs(array[i-1]->start_time + array[i]->total_time/100-array[i]->start_time) > 2) + ) { + static struct tm * stmp; + stmp = gmtime(&array[i]->start_time); + trk_head = route_head_alloc(); + /*For D906, we would like to use the track_index in the last packet instead...*/ + trk_head->rte_num = ++trk_num; + trk_head->rte_name = xmalloc(32); + strftime(trk_head->rte_name, 32, "%Y-%m-%dT%H:%M:%SZ", stmp); + track_add_head(trk_head); + + wpt = waypt_new(); + + wpt->longitude = array[i]->begin_lon; + wpt->latitude = array[i]->begin_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time; + wpt->microseconds = 0; + + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d-0", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method); + + track_add_wpt(trk_head, wpt); + } + /*Allow even if no correct location, no skip if invalid */ + /* if (array[i]->no_latlon) { + * continue; + * } + */ + wpt = waypt_new(); + + wpt->longitude = array[i]->end_lon; + wpt->latitude = array[i]->end_lat; + wpt->heartrate = array[i]->avg_heart_rate; + wpt->cadence = array[i]->avg_cadence; + wpt->speed = array[i]->max_speed; + wpt->creation_time = array[i]->start_time + array[i]->total_time/100; + wpt->microseconds = 10000*(array[i]->total_time % 100); + /*Add fields with no mapping in the description */ + wpt->shortname = xmalloc(8); + sprintf(wpt->shortname, "#%d", index); + wpt->description = xmalloc(128); + sprintf(wpt->description, "D:%f Cal:%d MS:%f AH:%d MH:%d AC:%d I:%d T:%d (%f,%f)", + array[i]->total_distance, array[i]->calories, array[i]->max_speed, array[i]->avg_heart_rate, + array[i]->max_heart_rate, array[i]->avg_cadence, array[i]->intensity, array[i]->trigger_method, + array[i]->begin_lon, array[i]->begin_lat); + + track_add_wpt(trk_head, wpt); + } + while (ntracks) { + GPS_Lap_Del(&array[--ntracks]); + } + xfree(array); } #endif @@ -648,54 +679,66 @@ lap_read_as_track(void) static void pvt2wpt(GPS_PPvt_Data pvt, waypoint *wpt) { - double wptime, wptimes; - - wpt->altitude = pvt->alt; - wpt->latitude = pvt->lat; - wpt->longitude = pvt->lon; - WAYPT_SET(wpt,course,1); - WAYPT_SET(wpt,speed,1); - - wpt->course = 180 + DEG(atan2(-pvt->east, -pvt->north)); - - /* velocity in m/s */ - WAYPT_SET(wpt,speed, sqrt(pvt->north*pvt->north + pvt->east*pvt->east)); - // wpt->vs = pvt->up; - - /* - * The unit reports time in three fields: - * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. - * 2) The number of seconds (fractions allowed) since that Sunday. - * 3) The number of leap seconds that offset the current UTC and GPS - * reference clocks. - */ - wptime = 631065600.0 + pvt->wn_days * 86400.0 + - pvt->tow - - pvt->leap_scnds; - wptimes = floor(wptime); - wpt->creation_time = wptimes; - wpt->microseconds = 1000000.0 * (wptime - wptimes); - - /* - * The Garmin spec fifteen different models that use a different - * table for 'fix' without a really good way to tell if the model - * we're talking to happens to be one of those...By inspection, - * it looks like even though the models (Summit, Legend, etc.) may - * be popular, it's older (2001 and earlier or so) versions that - * are affected and I think there are relatively few readers of - * the fix field anyway. Time will tell if this is a good plan. - */ - switch (pvt->fix) { - case 0: wpt->fix = fix_unknown;break; - case 1: wpt->fix = fix_none;break; - case 2: wpt->fix = fix_2d;break; - case 3: wpt->fix = fix_3d;break; - case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ - case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ - default: - /* undocumented type. */ - break; - } + double wptime, wptimes; + + wpt->altitude = pvt->alt; + wpt->latitude = pvt->lat; + wpt->longitude = pvt->lon; + WAYPT_SET(wpt,course,1); + WAYPT_SET(wpt,speed,1); + + wpt->course = 180 + DEG(atan2(-pvt->east, -pvt->north)); + + /* velocity in m/s */ + WAYPT_SET(wpt,speed, sqrt(pvt->north*pvt->north + pvt->east*pvt->east)); + // wpt->vs = pvt->up; + + /* + * The unit reports time in three fields: + * 1) The # of days to most recent Sun. since 1989-12-31 midnight UTC. + * 2) The number of seconds (fractions allowed) since that Sunday. + * 3) The number of leap seconds that offset the current UTC and GPS + * reference clocks. + */ + wptime = 631065600.0 + pvt->wn_days * 86400.0 + + pvt->tow + - pvt->leap_scnds; + wptimes = floor(wptime); + wpt->creation_time = wptimes; + wpt->microseconds = 1000000.0 * (wptime - wptimes); + + /* + * The Garmin spec fifteen different models that use a different + * table for 'fix' without a really good way to tell if the model + * we're talking to happens to be one of those...By inspection, + * it looks like even though the models (Summit, Legend, etc.) may + * be popular, it's older (2001 and earlier or so) versions that + * are affected and I think there are relatively few readers of + * the fix field anyway. Time will tell if this is a good plan. + */ + switch (pvt->fix) { + case 0: + wpt->fix = fix_unknown; + break; + case 1: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + case 3: + wpt->fix = fix_3d; + break; + case 4: + wpt->fix = fix_dgps; + break; /* 2D_diff */ + case 5: + wpt->fix = fix_dgps; + break; /* 3D_diff */ + default: + /* undocumented type. */ + break; + } } static gpsdevh *pvt_fd; @@ -703,327 +746,351 @@ static gpsdevh *pvt_fd; static void pvt_init(const char *fname) { - rw_init(fname); - GPS_Command_Pvt_On(fname, &pvt_fd); + rw_init(fname); + GPS_Command_Pvt_On(fname, &pvt_fd); } static waypoint * pvt_read(posn_status *posn_status) { - waypoint *wpt = waypt_new(); - GPS_PPvt_Data pvt = GPS_Pvt_New(); - - if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { - pvt2wpt(pvt, wpt); - GPS_Pvt_Del(&pvt); - - wpt->shortname = xstrdup("Position"); - - if (gps_errno && posn_status) { - posn_status->request_terminate = 1; - } - - return wpt; - } - - /* - * If the caller has not given us a better way to return the - * error, do it now. - */ - if (gps_errno) { - fatal(MYNAME ": Fatal error reading position.\n"); - } - - waypt_free(wpt); - GPS_Pvt_Del(&pvt); - - return NULL; + waypoint *wpt = waypt_new(); + GPS_PPvt_Data pvt = GPS_Pvt_New(); + + if (GPS_Command_Pvt_Get(&pvt_fd, &pvt)) { + pvt2wpt(pvt, wpt); + GPS_Pvt_Del(&pvt); + + wpt->shortname = xstrdup("Position"); + + if (gps_errno && posn_status) { + posn_status->request_terminate = 1; + } + + return wpt; + } + + /* + * If the caller has not given us a better way to return the + * error, do it now. + */ + if (gps_errno) { + fatal(MYNAME ": Fatal error reading position.\n"); + } + + waypt_free(wpt); + GPS_Pvt_Del(&pvt); + + return NULL; } static void data_read(void) { - if (gpx_vec) { - gpx_vec->read(); - return; - } - - if (poweroff) { - return; - } - - if (global_opts.masked_objective & WPTDATAMASK) - waypt_read(); - if (global_opts.masked_objective & TRKDATAMASK) - track_read(); - if (global_opts.masked_objective & RTEDATAMASK) - route_read(); - if (!(global_opts.masked_objective & - (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) - fatal(MYNAME ": Nothing to do.\n"); + if (gpx_vec) { + gpx_vec->read(); + return; + } + + if (poweroff) { + return; + } + + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_read(); + } + if (global_opts.masked_objective & TRKDATAMASK) { + track_read(); + } + if (global_opts.masked_objective & RTEDATAMASK) { + route_read(); + } + if (!(global_opts.masked_objective & + (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))) { + fatal(MYNAME ": Nothing to do.\n"); + } } static GPS_PWay sane_GPS_Way_New(void) { - GPS_PWay way; - way = GPS_Way_New(); - if (!way) { - fatal(MYNAME ":not enough memory\n"); - } - - /* - * Undo less than helpful defaults from Way_New. - */ - way->rte_ident[0] = 0; - way->rte_cmnt[0] = 0; - way->rte_link_subclass[0] = 0; - way->rte_link_ident[0] = 0; - way->city[0] = 0; - way->state[0] = 0; - way->facility[0] = 0; - way->addr[0] = 0; - way->cross_road[0] = 0; - way->cross_road[0] = 0; - way->dpth = 1.0e25f; - way->wpt_class = 0; // user waypoint by default. - - return way; + GPS_PWay way; + way = GPS_Way_New(); + if (!way) { + fatal(MYNAME ":not enough memory\n"); + } + + /* + * Undo less than helpful defaults from Way_New. + */ + way->rte_ident[0] = 0; + way->rte_cmnt[0] = 0; + way->rte_link_subclass[0] = 0; + way->rte_link_ident[0] = 0; + way->city[0] = 0; + way->state[0] = 0; + way->facility[0] = 0; + way->addr[0] = 0; + way->cross_road[0] = 0; + way->cross_road[0] = 0; + way->dpth = 1.0e25f; + way->wpt_class = 0; // user waypoint by default. + + return way; } -static int +static int waypt_write_cb(GPS_PWay *way) { - static int i; - int n = waypt_count(); - - if (global_opts.verbose_status) { - i++; - waypt_status_disp(n, i); - } - return 0; + static int i; + int n = waypt_count(); + + if (global_opts.verbose_status) { + i++; + waypt_status_disp(n, i); + } + return 0; } -/* +/* * If we're using smart names, try to put the cache info in the * description. */ const char * get_gc_info(waypoint *wpt) { - if (global_opts.smart_names) { - if (wpt->gc_data->type == gt_virtual) return "V "; - if (wpt->gc_data->type == gt_unknown) return "? "; - if (wpt->gc_data->type == gt_multi) return "Mlt "; - if (wpt->gc_data->type == gt_earth) return "EC "; - if (wpt->gc_data->type == gt_event) return "Ev "; - if (wpt->gc_data->container == gc_micro) return "M "; - if (wpt->gc_data->container == gc_small) return "S "; - } - return ""; + if (global_opts.smart_names) { + if (wpt->gc_data->type == gt_virtual) { + return "V "; + } + if (wpt->gc_data->type == gt_unknown) { + return "? "; + } + if (wpt->gc_data->type == gt_multi) { + return "Mlt "; + } + if (wpt->gc_data->type == gt_earth) { + return "EC "; + } + if (wpt->gc_data->type == gt_event) { + return "Ev "; + } + if (wpt->gc_data->container == gc_micro) { + return "M "; + } + if (wpt->gc_data->container == gc_small) { + return "S "; + } + } + return ""; } static int waypoint_prepare(void) { - int i; - int n = waypt_count(); - queue *elem, *tmp; - extern queue waypt_head; - int icon; - - tx_waylist = xcalloc(n,sizeof(*tx_waylist)); - - for (i = 0; i < n; i++) { - tx_waylist[i] = sane_GPS_Way_New(); - } - - i = 0; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wpt; - char *ident; - char *src = NULL; - char obuf[256]; - - wpt = (waypoint *) elem; - - if(wpt->description) src = wpt->description; - if(wpt->notes) src = wpt->notes; - - /* - * mkshort will do collision detection and namespace - * cleaning - */ - ident = mkshort(mkshort_handle, - global_opts.synthesize_shortnames ? src : - wpt->shortname); - /* Should not be a strcpy as 'ident' isn't really a C string, - * but rather a garmin "fixed length" buffer that's padded - * to the end with spaces. So this is NOT (strlen+1). - */ - memcpy(tx_waylist[i]->ident, ident, strlen(ident)); - - if (global_opts.synthesize_shortnames) { - xfree(ident); - } - tx_waylist[i]->ident[sizeof(tx_waylist[i]->ident)-1] = 0; - - // If we were explictly given a comment from GPX, use that. - // This logic really is horrible and needs to be untangled. - if (wpt->description && - global_opts.smart_names && !wpt->gc_data->diff) { - memcpy(tx_waylist[i]->cmnt, wpt->description, strlen(wpt->description)); - } else { - if (global_opts.smart_names && - wpt->gc_data->diff && wpt->gc_data->terr) { + int i; + int n = waypt_count(); + queue *elem, *tmp; + extern queue waypt_head; + int icon; + + tx_waylist = xcalloc(n,sizeof(*tx_waylist)); + + for (i = 0; i < n; i++) { + tx_waylist[i] = sane_GPS_Way_New(); + } + + i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wpt; + char *ident; + char *src = NULL; + char obuf[256]; + + wpt = (waypoint *) elem; + + if (wpt->description) { + src = wpt->description; + } + if (wpt->notes) { + src = wpt->notes; + } + + /* + * mkshort will do collision detection and namespace + * cleaning + */ + ident = mkshort(mkshort_handle, + global_opts.synthesize_shortnames ? src : + wpt->shortname); + /* Should not be a strcpy as 'ident' isn't really a C string, + * but rather a garmin "fixed length" buffer that's padded + * to the end with spaces. So this is NOT (strlen+1). + */ + memcpy(tx_waylist[i]->ident, ident, strlen(ident)); + + if (global_opts.synthesize_shortnames) { + xfree(ident); + } + tx_waylist[i]->ident[sizeof(tx_waylist[i]->ident)-1] = 0; + + // If we were explictly given a comment from GPX, use that. + // This logic really is horrible and needs to be untangled. + if (wpt->description && + global_opts.smart_names && !wpt->gc_data->diff) { + memcpy(tx_waylist[i]->cmnt, wpt->description, strlen(wpt->description)); + } else { + if (global_opts.smart_names && + wpt->gc_data->diff && wpt->gc_data->terr) { #if 0 -xasprintf(&src, "%s %s", &wpt->shortname[2], src); + xasprintf(&src, "%s %s", &wpt->shortname[2], src); #endif - snprintf(obuf, sizeof(obuf), "%s%d/%d %s", - get_gc_info(wpt), - wpt->gc_data->diff, wpt->gc_data->terr, - src); - memcpy(tx_waylist[i]->cmnt, obuf, strlen(obuf)); - } else { - memcpy(tx_waylist[i]->cmnt, src, strlen(src)); - } - } - - - - tx_waylist[i]->lon = wpt->longitude; - tx_waylist[i]->lat = wpt->latitude; - - if (deficon) { - icon = gt_find_icon_number_from_desc(deficon, PCX); - } else { - if (get_cache_icon(wpt)) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } else { - icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - } - } - - /* For units that support tiny numbers of waypoints, just - * overwrite that and go very literal. - */ - if (gps_waypt_type == 103) { - icon = d103_icon_number_from_symbol(wpt->icon_descr); - } - tx_waylist[i]->smbl = icon; - if (wpt->altitude == unknown_alt) { - tx_waylist[i]->alt_is_unknown = 1; - tx_waylist[i]->alt = 0; - } else { - tx_waylist[i]->alt = wpt->altitude; - } - if (wpt->creation_time) { - tx_waylist[i]->time = wpt->creation_time; - tx_waylist[i]->time_populated = 1; - } - if (category) { - tx_waylist[i]->category = 1 << (atoi(category) - 1); - } - if (categorybits) { - tx_waylist[i]->category = categorybits; - } + snprintf(obuf, sizeof(obuf), "%s%d/%d %s", + get_gc_info(wpt), + wpt->gc_data->diff, wpt->gc_data->terr, + src); + memcpy(tx_waylist[i]->cmnt, obuf, strlen(obuf)); + } else { + memcpy(tx_waylist[i]->cmnt, src, strlen(src)); + } + } + + + + tx_waylist[i]->lon = wpt->longitude; + tx_waylist[i]->lat = wpt->latitude; + + if (deficon) { + icon = gt_find_icon_number_from_desc(deficon, PCX); + } else { + if (get_cache_icon(wpt)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } else { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + } + } + + /* For units that support tiny numbers of waypoints, just + * overwrite that and go very literal. + */ + if (gps_waypt_type == 103) { + icon = d103_icon_number_from_symbol(wpt->icon_descr); + } + tx_waylist[i]->smbl = icon; + if (wpt->altitude == unknown_alt) { + tx_waylist[i]->alt_is_unknown = 1; + tx_waylist[i]->alt = 0; + } else { + tx_waylist[i]->alt = wpt->altitude; + } + if (wpt->creation_time) { + tx_waylist[i]->time = wpt->creation_time; + tx_waylist[i]->time_populated = 1; + } + if (category) { + tx_waylist[i]->category = 1 << (atoi(category) - 1); + } + if (categorybits) { + tx_waylist[i]->category = categorybits; + } #if SOON - garmin_fs_garmin_before_write(wpt, tx_waylist[i], gps_waypt_type); + garmin_fs_garmin_before_write(wpt, tx_waylist[i], gps_waypt_type); #endif - i++; - } + i++; + } - return n; + return n; } static void waypoint_write(void) { - int i, n; - int32 ret; - - n = waypoint_prepare(); - - if ((ret = GPS_Command_Send_Waypoint(portname, tx_waylist, n, waypt_write_cb)) < 0) { - fatal(MYNAME ":communication error sending wayoints..\n"); - } - - for (i = 0; i < n; ++i) { - GPS_Way_Del(&tx_waylist[i]); - } - if (global_opts.verbose_status) { - fprintf(stdout, "\r\n"); - fflush(stdout); - } - xfree(tx_waylist); + int i, n; + int32 ret; + + n = waypoint_prepare(); + + if ((ret = GPS_Command_Send_Waypoint(portname, tx_waylist, n, waypt_write_cb)) < 0) { + fatal(MYNAME ":communication error sending wayoints..\n"); + } + + for (i = 0; i < n; ++i) { + GPS_Way_Del(&tx_waylist[i]); + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + fflush(stdout); + } + xfree(tx_waylist); } static void route_hdr_pr(const route_head *rte) { - (*cur_tx_routelist_entry)->rte_num = rte->rte_num; - (*cur_tx_routelist_entry)->isrte = 1; - if (rte->rte_name) { - strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, - sizeof ((*cur_tx_routelist_entry)->rte_ident)); - } + (*cur_tx_routelist_entry)->rte_num = rte->rte_num; + (*cur_tx_routelist_entry)->isrte = 1; + if (rte->rte_name) { + strncpy((*cur_tx_routelist_entry)->rte_ident, rte->rte_name, + sizeof((*cur_tx_routelist_entry)->rte_ident)); + } } static void route_waypt_pr(const waypoint *wpt) { - GPS_PWay rte = *cur_tx_routelist_entry; - char *s, *d; - - /* - * As stupid as this is, libjeeps seems to want an empty - * waypoint between every link in a route that has nothing - * but the 'islink' member set. Rather than "fixing" libjeeps, - * we just double them up (sigh) and do that here. - */ - rte->islink = 1; - rte->lon = wpt->longitude; - rte->lat = wpt->latitude; - cur_tx_routelist_entry++; - rte = *cur_tx_routelist_entry; - - rte->lon = wpt->longitude; - rte->lat = wpt->latitude; - rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - - // map class so unit doesn't duplicate routepoints as a waypoint. - rte->wpt_class = 0x80; - - if (wpt->altitude != unknown_alt) { - rte->alt = wpt->altitude; - } else { - rte->alt_is_unknown = 1; - rte->alt = 0; - } - - // Garmin protocol spec says no spaces, no lowercase, etc. in a route. - // enforce that here, since jeeps doesn't. - // - // This was strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); - d = rte->ident; - for (s = wpt->shortname; *s; s++) { - int c = *s; - if (receiver_must_upper && isalpha(c)) c = toupper(c); - if (strchr(valid_waypt_chars, c)) { - *d++ = c; - } - } - - rte->ident[sizeof(rte->ident)-1] = 0; - - if (wpt->description) { - strncpy(rte->cmnt, wpt->description, sizeof(rte->cmnt)); - rte->cmnt[sizeof(rte->cmnt)-1] = 0; - } else { - rte->cmnt[0] = 0; - } - cur_tx_routelist_entry++; + GPS_PWay rte = *cur_tx_routelist_entry; + char *s, *d; + + /* + * As stupid as this is, libjeeps seems to want an empty + * waypoint between every link in a route that has nothing + * but the 'islink' member set. Rather than "fixing" libjeeps, + * we just double them up (sigh) and do that here. + */ + rte->islink = 1; + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + cur_tx_routelist_entry++; + rte = *cur_tx_routelist_entry; + + rte->lon = wpt->longitude; + rte->lat = wpt->latitude; + rte->smbl = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + // map class so unit doesn't duplicate routepoints as a waypoint. + rte->wpt_class = 0x80; + + if (wpt->altitude != unknown_alt) { + rte->alt = wpt->altitude; + } else { + rte->alt_is_unknown = 1; + rte->alt = 0; + } + + // Garmin protocol spec says no spaces, no lowercase, etc. in a route. + // enforce that here, since jeeps doesn't. + // + // This was strncpy(rte->ident, wpt->shortname, sizeof(rte->ident)); + d = rte->ident; + for (s = wpt->shortname; *s; s++) { + int c = *s; + if (receiver_must_upper && isalpha(c)) { + c = toupper(c); + } + if (strchr(valid_waypt_chars, c)) { + *d++ = c; + } + } + + rte->ident[sizeof(rte->ident)-1] = 0; + + if (wpt->description) { + strncpy(rte->cmnt, wpt->description, sizeof(rte->cmnt)); + rte->cmnt[sizeof(rte->cmnt)-1] = 0; + } else { + rte->cmnt[0] = 0; + } + cur_tx_routelist_entry++; } static void @@ -1034,188 +1101,190 @@ route_noop(const route_head *wp) static void route_write(void) { - int i; - int n = 2 * route_waypt_count(); /* Doubled for the islink crap. */ + int i; + int n = 2 * route_waypt_count(); /* Doubled for the islink crap. */ - tx_routelist = xcalloc(n,sizeof(GPS_PWay)); - cur_tx_routelist_entry = tx_routelist; + tx_routelist = xcalloc(n,sizeof(GPS_PWay)); + cur_tx_routelist_entry = tx_routelist; - for (i = 0; i < n; i++) { - tx_routelist[i] = sane_GPS_Way_New(); - } + for (i = 0; i < n; i++) { + tx_routelist[i] = sane_GPS_Way_New(); + } - route_disp_all(route_hdr_pr, route_noop, route_waypt_pr); - GPS_Command_Send_Route(portname, tx_routelist, n); + route_disp_all(route_hdr_pr, route_noop, route_waypt_pr); + GPS_Command_Send_Route(portname, tx_routelist, n); } static void track_hdr_pr(const route_head *trk_head) { - (*cur_tx_tracklist_entry)->ishdr = gpsTrue; - if ( trk_head->rte_name ) { - strncpy((*cur_tx_tracklist_entry)->trk_ident, trk_head->rte_name, sizeof((*cur_tx_tracklist_entry)->trk_ident)); - (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; - } else { - sprintf((*cur_tx_tracklist_entry)->trk_ident, "TRACK%02d", my_track_count); - } - cur_tx_tracklist_entry++; - my_track_count++; + (*cur_tx_tracklist_entry)->ishdr = gpsTrue; + if (trk_head->rte_name) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, trk_head->rte_name, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } else { + sprintf((*cur_tx_tracklist_entry)->trk_ident, "TRACK%02d", my_track_count); + } + cur_tx_tracklist_entry++; + my_track_count++; } static void track_waypt_pr(const waypoint *wpt) { - (*cur_tx_tracklist_entry)->lat = wpt->latitude; - (*cur_tx_tracklist_entry)->lon = wpt->longitude; - (*cur_tx_tracklist_entry)->alt = (wpt->altitude != unknown_alt) ? wpt->altitude : 1e25; - (*cur_tx_tracklist_entry)->Time = wpt->creation_time; - if ( wpt->shortname ) { - strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); - (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; - } - (*cur_tx_tracklist_entry)->tnew = wpt->wpt_flags.new_trkseg; - cur_tx_tracklist_entry++; + (*cur_tx_tracklist_entry)->lat = wpt->latitude; + (*cur_tx_tracklist_entry)->lon = wpt->longitude; + (*cur_tx_tracklist_entry)->alt = (wpt->altitude != unknown_alt) ? wpt->altitude : 1e25; + (*cur_tx_tracklist_entry)->Time = wpt->creation_time; + if (wpt->shortname) { + strncpy((*cur_tx_tracklist_entry)->trk_ident, wpt->shortname, sizeof((*cur_tx_tracklist_entry)->trk_ident)); + (*cur_tx_tracklist_entry)->trk_ident[sizeof((*cur_tx_tracklist_entry)->trk_ident)-1] = 0; + } + (*cur_tx_tracklist_entry)->tnew = wpt->wpt_flags.new_trkseg; + cur_tx_tracklist_entry++; } static int track_prepare(void) { - int i; - int32 n = track_waypt_count() + track_count(); + int i; + int32 n = track_waypt_count() + track_count(); - tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); - cur_tx_tracklist_entry = tx_tracklist; - for (i = 0; i < n; i++) { - tx_tracklist[i] = GPS_Track_New(); - } - my_track_count = 0; - track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); + tx_tracklist = xcalloc(n, sizeof(GPS_PTrack)); + cur_tx_tracklist_entry = tx_tracklist; + for (i = 0; i < n; i++) { + tx_tracklist[i] = GPS_Track_New(); + } + my_track_count = 0; + track_disp_all(track_hdr_pr, route_noop, track_waypt_pr); - GPS_Prepare_Track_For_Device(&tx_tracklist, &n); + GPS_Prepare_Track_For_Device(&tx_tracklist, &n); - return n; + return n; } static void track_write(void) { - int i, n; - - n = track_prepare(); - GPS_Command_Send_Track(portname, tx_tracklist, n, (eraset)? 1 : 0); - - for (i = 0; i < n; i++) { - GPS_Track_Del(&tx_tracklist[i]); - } - xfree(tx_tracklist); + int i, n; + + n = track_prepare(); + GPS_Command_Send_Track(portname, tx_tracklist, n, (eraset)? 1 : 0); + + for (i = 0; i < n; i++) { + GPS_Track_Del(&tx_tracklist[i]); + } + xfree(tx_tracklist); } static void course_write(void) { - int i, n_trk, n_wpt; + int i, n_trk, n_wpt; - n_wpt = waypoint_prepare(); - n_trk = track_prepare(); + n_wpt = waypoint_prepare(); + n_trk = track_prepare(); - GPS_Command_Send_Track_As_Course(portname, tx_tracklist, n_trk, - tx_waylist, n_wpt, (eraset)? 1 : 0); + GPS_Command_Send_Track_As_Course(portname, tx_tracklist, n_trk, + tx_waylist, n_wpt, (eraset)? 1 : 0); - for (i = 0; i < n_wpt; ++i) { - GPS_Way_Del(&tx_waylist[i]); - } - xfree(tx_waylist); + for (i = 0; i < n_wpt; ++i) { + GPS_Way_Del(&tx_waylist[i]); + } + xfree(tx_waylist); - for (i = 0; i < n_trk; i++) { - GPS_Track_Del(&tx_tracklist[i]); - } - xfree(tx_tracklist); + for (i = 0; i < n_trk; i++) { + GPS_Track_Del(&tx_tracklist[i]); + } + xfree(tx_tracklist); } static void data_write(void) { - if (poweroff) { - return; - } - - /* If we have both trackpoints and waypoints and the device - * supports courses, combine them to a course. Otherwise, - * send tracks & waypoints separately. - */ - if ((global_opts.masked_objective & WPTDATAMASK) && - (global_opts.masked_objective & TRKDATAMASK) && - gps_course_transfer != -1) - { - course_write(); - } - else - { - if (global_opts.masked_objective & WPTDATAMASK) - waypoint_write(); - if (global_opts.masked_objective & TRKDATAMASK) - track_write(); - } - if (global_opts.masked_objective & RTEDATAMASK) - route_write(); + if (poweroff) { + return; + } + + /* If we have both trackpoints and waypoints and the device + * supports courses, combine them to a course. Otherwise, + * send tracks & waypoints separately. + */ + if ((global_opts.masked_objective & WPTDATAMASK) && + (global_opts.masked_objective & TRKDATAMASK) && + gps_course_transfer != -1) { + course_write(); + } else { + if (global_opts.masked_objective & WPTDATAMASK) { + waypoint_write(); + } + if (global_opts.masked_objective & TRKDATAMASK) { + track_write(); + } + } + if (global_opts.masked_objective & RTEDATAMASK) { + route_write(); + } } ff_vecs_t garmin_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - rd_init, - rw_init, - rw_deinit, - rw_deinit, - data_read, - data_write, - NULL, - garmin_args, - CET_CHARSET_ASCII, 0, - { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } + ff_type_serial, + FF_CAP_RW_ALL, + rd_init, + rw_init, + rw_deinit, + rw_deinit, + data_read, + data_write, + NULL, + garmin_args, + CET_CHARSET_ASCII, 0, + { pvt_init, pvt_read, rw_deinit, NULL, NULL, NULL } }; static const char *d103_icons[16] = { - "dot", - "house", - "gas", - "car", - "fish", - "boat", - "anchor", - "wreck", - "exit", - "skull", - "flag", - "camp", - "circle_x", - "deer", - "1st_aid", - "back-track" + "dot", + "house", + "gas", + "car", + "fish", + "boat", + "anchor", + "wreck", + "exit", + "skull", + "flag", + "camp", + "circle_x", + "deer", + "1st_aid", + "back-track" }; static const char * d103_symbol_from_icon_number(unsigned int n) { - if (n <= 15) - return d103_icons[n]; - else - return "unknown"; + if (n <= 15) { + return d103_icons[n]; + } else { + return "unknown"; + } } -static int +static int d103_icon_number_from_symbol(const char *s) { - unsigned int i; + unsigned int i; - if (NULL == s) { - return 0; - } + if (NULL == s) { + return 0; + } - for (i = 0; i < sizeof(d103_icons) / sizeof(d103_icons[0]); i++) { - if (0 == case_ignore_strcmp(s, d103_icons[i])) - return i; - } - return 0; + for (i = 0; i < sizeof(d103_icons) / sizeof(d103_icons[0]); i++) { + if (0 == case_ignore_strcmp(s, d103_icons[i])) { + return i; + } + } + return 0; } diff --git a/gpsbabel/garmin_device_xml.c b/gpsbabel/garmin_device_xml.c index 981883b2a..6f55ce9ce 100644 --- a/gpsbabel/garmin_device_xml.c +++ b/gpsbabel/garmin_device_xml.c @@ -1,5 +1,5 @@ /* - Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, + Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, Nuvi, Colorado, etc. and return key device info. Copyright (C) 2008 Robert Lipe, robertlipe@gpsbabel.org @@ -20,7 +20,7 @@ */ -// References: +// References: // http://developer.garmin.com/web-device/garmin-mass-storage-mode-devices/ // http://developer.garmin.com/schemas/device/v2/ @@ -35,11 +35,13 @@ static int type; static char *mountpoint, *base, *path, *ext; static xg_callback device_s, id_s, path_s, ext_s, base_s, dir_s; -void type_s(const char *args, const char **unused) { +void type_s(const char *args, const char **unused) +{ type = strcmp(args, "GPSData"); } -void device_s(const char *args, const char **unused) { +void device_s(const char *args, const char **unused) +{ if (my_gdx_info) { fatal(MYNAME ": More than one device type found in file.\n"); } @@ -47,50 +49,62 @@ void device_s(const char *args, const char **unused) { my_gdx_info->device_desc = xstrdup(args); } -void id_s(const char *args, const char **unused) { +void id_s(const char *args, const char **unused) +{ my_gdx_info->device_id = xstrdup(args); } -void path_s(const char *args, const char **unused) { +void path_s(const char *args, const char **unused) +{ path = xstrdup(args); } -void ext_s(const char *args, const char **unused) { +void ext_s(const char *args, const char **unused) +{ ext = xstrdup(args); } -void base_s(const char *args, const char **unused) { +void base_s(const char *args, const char **unused) +{ base = xstrdup(args); } -void dir_s(const char *args, const char **unused) { - if (type) +void dir_s(const char *args, const char **unused) +{ + if (type) { return; + } if (0 == strcmp(args, "OutputFromUnit")) { xasprintf(&my_gdx_info->from_device.path, "%s%c%s", - mountpoint, GB_PATHSEP, path); - my_gdx_info->from_device.basename = xstrdup(base); - my_gdx_info->from_device.extension = xstrdup(ext); - xasprintf(&my_gdx_info->from_device.canon, "%s/%s.%s", - my_gdx_info->from_device.path, - my_gdx_info->from_device.basename, - my_gdx_info->from_device.extension); - } else - if (0 == strcmp(args, "InputToUnit")) { - xasprintf(&my_gdx_info->to_device.path, "%s%c%s", - mountpoint, GB_PATHSEP, path); + mountpoint, GB_PATHSEP, path); + my_gdx_info->from_device.basename = xstrdup(base); + my_gdx_info->from_device.extension = xstrdup(ext); + xasprintf(&my_gdx_info->from_device.canon, "%s/%s.%s", + my_gdx_info->from_device.path, + my_gdx_info->from_device.basename, + my_gdx_info->from_device.extension); + } else if (0 == strcmp(args, "InputToUnit")) { + xasprintf(&my_gdx_info->to_device.path, "%s%c%s", + mountpoint, GB_PATHSEP, path); my_gdx_info->to_device.basename = xstrdup(base); my_gdx_info->to_device.extension = xstrdup(ext); - } else - fatal(MYNAME ":Unknown direction '%s'\n", args); + } else { + fatal(MYNAME ":Unknown direction '%s'\n", args); + } - if (base) xfree(base) ; + if (base) { + xfree(base) ; + } base = NULL; - if (ext) xfree(ext) ; + if (ext) { + xfree(ext) ; + } ext = NULL; - if (path) xfree(path) ; + if (path) { + xfree(path) ; + } path = NULL; } @@ -106,7 +120,8 @@ static xg_tag_mapping gdx_map[] = { }; const gdx_info * -gdx_read(const char *fname) { +gdx_read(const char *fname) +{ // Test file open-able before gb_open gets a chance to fatal(). FILE *fin = fopen(fname, "r"); @@ -123,7 +138,8 @@ gdx_read(const char *fname) { // Look for the Device in the incoming NULL-terminated list of directories const gdx_info * -gdx_find_file(char **dirlist) { +gdx_find_file(char **dirlist) +{ const gdx_info *gdx; while (dirlist && *dirlist) { char *tbuf; @@ -132,7 +148,7 @@ gdx_find_file(char **dirlist) { gdx = gdx_read(tbuf); xfree(tbuf); if (gdx) { - longjmp(gdx_jmp_buf, 1); + longjmp(gdx_jmp_buf, 1); } dirlist++; } @@ -140,6 +156,7 @@ gdx_find_file(char **dirlist) { } const gdx_info * -gdx_get_info() { +gdx_get_info() +{ return my_gdx_info; } diff --git a/gpsbabel/garmin_device_xml.h b/gpsbabel/garmin_device_xml.h index ffc6b31af..cc8474152 100644 --- a/gpsbabel/garmin_device_xml.h +++ b/gpsbabel/garmin_device_xml.h @@ -1,5 +1,5 @@ /* - Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, + Parse 'GarminDevice.xml' on a Garmin mass storage device (e.g. Zumo, Nuvi, Colorado, etc. and return key device info. Copyright (C) 2008 Robert Lipe, robertlipe@gpsbabel.org @@ -24,21 +24,21 @@ * Describes a file on the unit. */ typedef struct { - char *path; - char *basename; - char *extension; - char *canon; // full name, when applicable. + char *path; + char *basename; + char *extension; + char *canon; // full name, when applicable. } gdx_file; /* * The interesting traits of this device. */ typedef struct { - const char *device_desc; - const char *device_id; - const char *device_mounted_path; // Not from the file; about the file. - gdx_file from_device; - gdx_file to_device; + const char *device_desc; + const char *device_id; + const char *device_mounted_path; // Not from the file; about the file. + gdx_file from_device; + gdx_file to_device; // gdx_file geocache_logs; } gdx_info; @@ -48,7 +48,7 @@ const gdx_info * gdx_find_file(char **dirlist); // This is so gross. By the time we know it's not a USB device // and could be one of our devices, we're so deep into the callstack -// that can't back out tracefully without bludgeoning most of the +// that can't back out tracefully without bludgeoning most of the // (Mac|Lin|Win) x (USB|Serial) matrix. Since we don't *really* want // to progress any further, we just longjump back to the caller... #include @@ -59,78 +59,79 @@ jmp_buf gdx_jmp_buf; /* * The file-level information. */ -static +static struct gpx_global { - gpx_global_entry name; - gpx_global_entry desc; - gpx_global_entry author; - gpx_global_entry email; - gpx_global_entry url; - gpx_global_entry urlname; - gpx_global_entry keywords; - /* time and bounds aren't here; they're recomputed. */ + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ } *gpx_global ; static void -gpx_add_to_global(gpx_global_entry *ge, char *cdata) +gpx_add_to_global(gpx_global_entry *ge, char *cdata) { - queue *elem, *tmp; - gpx_global_entry * gep; - - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - if (0 == strcmp(cdata, gep->tagdata)) - return; - } - - gep = xcalloc(sizeof(*gep), 1); - QUEUE_INIT(&gep->queue); - gep->tagdata = xstrdup(cdata); - ENQUEUE_TAIL(&ge->queue, &gep->queue); + queue *elem, *tmp; + gpx_global_entry * gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) { + return; + } + } + + gep = xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); } static void gpx_rm_from_global(gpx_global_entry *ge) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); - xfree(g->tagdata); - xfree(g); - } + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } } static void gpx_write_gdata(gpx_global_entry *ge, char *tag) { - queue *elem, *tmp; - gpx_global_entry * gep; - - if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { - return; - } - - gbfprintf(ofd, "<%s>", tag); - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - gbfprintf(ofd, "%s", gep->tagdata); - /* Some tags we just output once. */ - if ((0 == strcmp(tag, "url")) || - (0 == strcmp(tag, "email"))) { - break; - } - gbfprintf(ofd, " "); - } - gbfprintf(ofd, "\n", tag); + queue *elem, *tmp; + gpx_global_entry * gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + gbfprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + gbfprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + gbfprintf(ofd, " "); + } + gbfprintf(ofd, "\n", tag); } typedef struct tag_mapping { - tag_type tag_type; /* enum from above for this tag */ - int tag_passthrough; /* true if we don't generate this */ - const char *tag_name; /* xpath-ish tag name */ - unsigned long crc; /* Crc32 of tag_name */ + tag_type tag_type; /* enum from above for this tag */ + int tag_passthrough; /* true if we don't generate this */ + const char *tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ } tag_mapping; /* @@ -140,29 +141,29 @@ typedef struct tag_mapping { */ tag_mapping tag_path_map[] = { - { tt_gpx, 0, "/gpx", 0UL }, - { tt_name, 0, "/gpx/name", 0UL }, - { tt_desc, 0, "/gpx/desc", 0UL }, - { tt_author, 0, "/gpx/author", 0UL }, - { tt_email, 0, "/gpx/email", 0UL }, - { tt_url, 0, "/gpx/url", 0UL }, - { tt_urlname, 0, "/gpx/urlname", 0UL }, - { tt_keywords, 0, "/gpx/keywords", 0UL }, - - { tt_wpt, 0, "/gpx/wpt", 0UL }, - { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, - { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, - { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, - { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, - { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, - { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, - { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, - { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ - { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ - { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, - { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, - - /* Double up the GPX 1.0 and GPX 1.1 styles */ + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ #define GEOTAG(type,name) \ {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL }, \ @@ -171,850 +172,849 @@ tag_mapping tag_path_map[] = { #define GARMIN_WPT_EXT "/gpx/wpt/extensions/gpxx:WaypointExtension" // GEOTAG( tt_cache, "cache"), - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - - GEOTAG( tt_cache_name, "name"), - GEOTAG( tt_cache_container, "container"), - GEOTAG( tt_cache_type, "type"), - GEOTAG( tt_cache_difficulty, "difficulty"), - GEOTAG( tt_cache_terrain, "terrain"), - GEOTAG( tt_cache_hint, "encoded_hints"), - GEOTAG( tt_cache_hint, "hints"), /* opencaching.de */ - GEOTAG( tt_cache_desc_short, "short_description"), - GEOTAG( tt_cache_desc_long, "long_description"), - GEOTAG( tt_cache_placer, "owner"), - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, - { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, - { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, - { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, - - { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, - - { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, - { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, - { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, - { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, - { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, - { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, - { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, - { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, - { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, - { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, - { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, - { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, - - { tt_rte, 0, "/gpx/rte", 0UL }, - { tt_rte_name, 0, "/gpx/rte/name", 0UL }, - { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, - { tt_rte_number, 0, "/gpx/rte/number", 0UL }, - { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, - { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, - { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, - { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, - { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, - { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, - { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, - { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, - { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, - - { tt_trk, 0, "/gpx/trk", 0UL }, - { tt_trk_name, 0, "/gpx/trk/name", 0UL }, - { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, - { tt_trk_number, 0, "/gpx/trk/number", 0UL }, - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, - { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, - { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, - { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, - { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, - { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, - { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, - { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, - { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, - - /* Common to tracks, routes, and waypts */ - { tt_fix, 0, "/gpx/wpt/fix", 0UL }, - { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, - { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, - { tt_sat, 0, "/gpx/wpt/sat", 0UL }, - { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, - { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, - { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, - { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - {0, 0, NULL, 0UL} + { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, + + GEOTAG(tt_cache_name, "name"), + GEOTAG(tt_cache_container, "container"), + GEOTAG(tt_cache_type, "type"), + GEOTAG(tt_cache_difficulty, "difficulty"), + GEOTAG(tt_cache_terrain, "terrain"), + GEOTAG(tt_cache_hint, "encoded_hints"), + GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG(tt_cache_desc_short, "short_description"), + GEOTAG(tt_cache_desc_long, "long_description"), + GEOTAG(tt_cache_placer, "owner"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, + + { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, + + { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, + { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, + { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, + { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, + { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, + { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, + { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, + { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, + { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, + { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, + { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, + { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, + + /* Common to tracks, routes, and waypts */ + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {0, 0, NULL, 0UL} }; static tag_type get_tag(const char *t, int *passthrough) { - tag_mapping *tm; - unsigned long tcrc = get_crc32_s(t); - - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { - *passthrough = tm->tag_passthrough; - return tm->tag_type; - } - } - *passthrough = 1; - return tt_unknown; + tag_mapping *tm; + unsigned long tcrc = get_crc32_s(t); + + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { + *passthrough = tm->tag_passthrough; + return tm->tag_type; + } + } + *passthrough = 1; + return tt_unknown; } static void prescan_tags(void) { - tag_mapping *tm; - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - tm->crc = get_crc32_s(tm->tag_name); - } + tag_mapping *tm; + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } } static void tag_gpx(const char **attrv) { - const char **avp; - for (avp = &attrv[0]; *avp; avp += 2) { - if (strcmp(avp[0], "version") == 0) { - gpx_version = avp[1]; - } - else if (strcmp(avp[0], "src") == 0) { - gpx_creator = avp[1]; - } - /* - * Our handling of schemaLocation really is weird. - * If we see we have a "normal" GPX 1.1 header, on read, - * flip our default on write to use that and don't append - * it to the rest... - */ - else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { - if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { - if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) - xfree(xsi_schema_loc); - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); - continue; - } - if (0 == strstr(xsi_schema_loc, avp[1])) { - xsi_schema_loc = xstrappend(xsi_schema_loc, " "); - xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); - } - } - } + const char **avp; + for (avp = &attrv[0]; *avp; avp += 2) { + if (strcmp(avp[0], "version") == 0) { + gpx_version = avp[1]; + } else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + /* + * Our handling of schemaLocation really is weird. + * If we see we have a "normal" GPX 1.1 header, on read, + * flip our default on write to use that and don't append + * it to the rest... + */ + else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { + if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { + if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { + xfree(xsi_schema_loc); + } + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); + continue; + } + if (0 == strstr(xsi_schema_loc, avp[1])) { + xsi_schema_loc = xstrappend(xsi_schema_loc, " "); + xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); + } + } + } } static void tag_wpt(const char **attrv) { - const char **avp = &attrv[0]; - - wpt_tmp = waypt_new(); - - cur_tag = NULL; - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } - fs_ptr = &wpt_tmp->fs; + const char **avp = &attrv[0]; + + wpt_tmp = waypt_new(); + + cur_tag = NULL; + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } + fs_ptr = &wpt_tmp->fs; } static void tag_cache_desc(const char ** attrv) { - const char **avp; - - cache_descr_is_html = 0; - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "html") == 0) { - if (strcmp(avp[1], "True") == 0) { - cache_descr_is_html = 1; - } - } - } + const char **avp; + + cache_descr_is_html = 0; + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "html") == 0) { + if (strcmp(avp[1], "True") == 0) { + cache_descr_is_html = 1; + } + } + } } static void tag_gs_cache(const char **attrv) { - const char **avp; - - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "id") == 0) { - wpt_tmp->gc_data.id = atoi(avp[1]); - } else if (strcmp(avp[0], "available") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - wpt_tmp->gc_data.is_available = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - wpt_tmp->gc_data.is_available = status_false; - } - } else if (strcmp(avp[0], "archived") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - wpt_tmp->gc_data.is_archived = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - wpt_tmp->gc_data.is_archived = status_false; - } - } - } + const char **avp; + + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "id") == 0) { + wpt_tmp->gc_data.id = atoi(avp[1]); + } else if (strcmp(avp[0], "available") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_available = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_available = status_false; + } + } else if (strcmp(avp[0], "archived") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + wpt_tmp->gc_data.is_archived = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + wpt_tmp->gc_data.is_archived = status_false; + } + } + } } static void start_something_else(const char *el, const char **attrv) { - const char **avp = attrv; - char **avcp = NULL; - int attr_count = 0; - xml_tag *new_tag; - fs_xml *fs_gpx; - - if ( !fs_ptr ) { - return; - } - - new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); - new_tag->tagname = xstrdup(el); - - /* count attributes */ - while (*avp) { - attr_count++; - avp++; - } - - /* copy attributes */ - avp = attrv; - new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); - avcp = new_tag->attributes; - while (*avp) { - *avcp = xstrdup(*avp); - avcp++; - avp++; - } - *avcp = NULL; - - if ( cur_tag ) { - if ( cur_tag->child ) { - cur_tag = cur_tag->child; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = cur_tag->parent; - } - else { - cur_tag->child = new_tag; - new_tag->parent = cur_tag; - } - } - else { - fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); - - if ( fs_gpx && fs_gpx->tag ) { - cur_tag = fs_gpx->tag; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = NULL; - } - else { - fs_gpx = fs_xml_alloc(FS_GPX); - fs_gpx->tag = new_tag; - fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); - new_tag->parent = NULL; - } - } - cur_tag = new_tag; + const char **avp = attrv; + char **avcp = NULL; + int attr_count = 0; + xml_tag *new_tag; + fs_xml *fs_gpx; + + if (!fs_ptr) { + return; + } + + new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); + + /* count attributes */ + while (*avp) { + attr_count++; + avp++; + } + + /* copy attributes */ + avp = attrv; + new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); + avcp = new_tag->attributes; + while (*avp) { + *avcp = xstrdup(*avp); + avcp++; + avp++; + } + *avcp = NULL; + + if (cur_tag) { + if (cur_tag->child) { + cur_tag = cur_tag->child; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = cur_tag->parent; + } else { + cur_tag->child = new_tag; + new_tag->parent = cur_tag; + } + } else { + fs_gpx = (fs_xml *)fs_chain_find(*fs_ptr, FS_GPX); + + if (fs_gpx && fs_gpx->tag) { + cur_tag = fs_gpx->tag; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = NULL; + } else { + fs_gpx = fs_xml_alloc(FS_GPX); + fs_gpx->tag = new_tag; + fs_chain_add(fs_ptr, (format_specific_data *)fs_gpx); + new_tag->parent = NULL; + } + } + cur_tag = new_tag; } static void end_something_else() { - if ( cur_tag ) { - cur_tag = cur_tag->parent; - } + if (cur_tag) { + cur_tag = cur_tag->parent; + } } static void tag_log_wpt(const char **attrv) { - waypoint * lwp_tmp; - const char **avp = &attrv[0]; - - /* create a new waypoint */ - lwp_tmp = waypt_new(); - - /* extract the lat/lon attributes */ - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->longitude); - } - avp+=2; - } - /* Make a new shortname. Since this is a groundspeak extension, - we assume that GCBLAH is the current shortname format and that - wpt_tmp refers to the currently parsed waypoint. Unfortunatley, - we need to keep track of log_wpt counts so we don't collide with - dupe shortnames. - */ - - if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { - /* copy of the shortname */ - lwp_tmp->shortname = xcalloc(7, 1); - sprintf(lwp_tmp->shortname, "%-4.4s%02d", - &wpt_tmp->shortname[2], logpoint_ct++); - - waypt_add(lwp_tmp); - } + waypoint * lwp_tmp; + const char **avp = &attrv[0]; + + /* create a new waypoint */ + lwp_tmp = waypt_new(); + + /* extract the lat/lon attributes */ + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->longitude); + } + avp+=2; + } + /* Make a new shortname. Since this is a groundspeak extension, + we assume that GCBLAH is the current shortname format and that + wpt_tmp refers to the currently parsed waypoint. Unfortunatley, + we need to keep track of log_wpt counts so we don't collide with + dupe shortnames. + */ + + if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { + /* copy of the shortname */ + lwp_tmp->shortname = xcalloc(7, 1); + sprintf(lwp_tmp->shortname, "%-4.4s%02d", + &wpt_tmp->shortname[2], logpoint_ct++); + + waypt_add(lwp_tmp); + } } static void gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - char *e; - char *ep; - int passthrough; - const char *el = xml_convert_to_char_string(xml_el); - const char **attr = xml_convert_attrs_to_char_string(xml_attr); - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - - /* - * FIXME: Find out why a cdatastr[0] doesn't adequately reset the - * cdata handler. - */ - memset(cdatastr.mem, 0, cdatastr.size); - - switch (get_tag(current_tag.mem, &passthrough)) { - case tt_gpx: - tag_gpx(attr); - break; - case tt_wpt: - tag_wpt(attr); - break; - case tt_wpt_link: - if (0 == strcmp(attr[0], "href")) { - link_url = attr[1]; - } - break; - case tt_wpt_link_text: - link_text = cdatastr.mem; - break; - case tt_rte: - rte_head = route_head_alloc(); - route_add_head(rte_head); - fs_ptr = &rte_head->fs; - break; - case tt_rte_rtept: - tag_wpt(attr); - break; - case tt_trk: - trk_head = route_head_alloc(); - track_add_head(trk_head); - fs_ptr = &trk_head->fs; - break; - case tt_trk_trkseg_trkpt: - tag_wpt(attr); - break; - case tt_unknown: - start_something_else(el, attr); - return; - case tt_cache: - tag_gs_cache(attr); - break; - case tt_cache_log_wpt: - if (opt_logpoint) - tag_log_wpt(attr); - break; - case tt_cache_desc_long: - case tt_cache_desc_short: - tag_cache_desc(attr); - break; - case tt_cache_placer: - if (*attr && (0 == strcmp(attr[0], "id"))) { - wpt_tmp->gc_data.placer_id = atoi(attr[1]); - } - default: - break; - } - if (passthrough) { - start_something_else(el, attr); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); + char *e; + char *ep; + int passthrough; + const char *el = xml_convert_to_char_string(xml_el); + const char **attr = xml_convert_attrs_to_char_string(xml_attr); + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + + /* + * FIXME: Find out why a cdatastr[0] doesn't adequately reset the + * cdata handler. + */ + memset(cdatastr.mem, 0, cdatastr.size); + + switch (get_tag(current_tag.mem, &passthrough)) { + case tt_gpx: + tag_gpx(attr); + break; + case tt_wpt: + tag_wpt(attr); + break; + case tt_wpt_link: + if (0 == strcmp(attr[0], "href")) { + link_url = attr[1]; + } + break; + case tt_wpt_link_text: + link_text = cdatastr.mem; + break; + case tt_rte: + rte_head = route_head_alloc(); + route_add_head(rte_head); + fs_ptr = &rte_head->fs; + break; + case tt_rte_rtept: + tag_wpt(attr); + break; + case tt_trk: + trk_head = route_head_alloc(); + track_add_head(trk_head); + fs_ptr = &trk_head->fs; + break; + case tt_trk_trkseg_trkpt: + tag_wpt(attr); + break; + case tt_unknown: + start_something_else(el, attr); + return; + case tt_cache: + tag_gs_cache(attr); + break; + case tt_cache_log_wpt: + if (opt_logpoint) { + tag_log_wpt(attr); + } + break; + case tt_cache_desc_long: + case tt_cache_desc_short: + tag_cache_desc(attr); + break; + case tt_cache_placer: + if (*attr && (0 == strcmp(attr[0], "id"))) { + wpt_tmp->gc_data.placer_id = atoi(attr[1]); + } + default: + break; + } + if (passthrough) { + start_something_else(el, attr); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } struct -gs_type_mapping{ - geocache_type type; - const char *name; + gs_type_mapping { + geocache_type type; + const char *name; } gs_type_map[] = { - { gt_traditional, "Traditional Cache" }, - { gt_traditional, "Traditional" }, /* opencaching.de */ - { gt_multi, "Multi-cache" }, - { gt_multi, "Multi" }, /* opencaching.de */ - { gt_virtual, "Virtual Cache" }, - { gt_virtual, "Virtual" }, /* opencaching.de */ - { gt_event, "Event Cache" }, - { gt_event, "Event" }, /* opencaching.de */ - { gt_webcam, "Webcam Cache" }, - { gt_webcam, "Webcam" }, /* opencaching.de */ - { gt_suprise, "Unknown Cache" }, - { gt_earth, "Earthcache" }, - { gt_earth, "Earth" }, /* opencaching.de */ - { gt_cito, "Cache In Trash Out Event" }, - { gt_letterbox, "Letterbox Hybrid" }, - { gt_locationless, "Locationless (Reverse) Cache" }, - { gt_ape, "Project APE Cache" }, - { gt_mega, "Mega-Event Cache" }, - - { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ + { gt_traditional, "Traditional Cache" }, + { gt_traditional, "Traditional" }, /* opencaching.de */ + { gt_multi, "Multi-cache" }, + { gt_multi, "Multi" }, /* opencaching.de */ + { gt_virtual, "Virtual Cache" }, + { gt_virtual, "Virtual" }, /* opencaching.de */ + { gt_event, "Event Cache" }, + { gt_event, "Event" }, /* opencaching.de */ + { gt_webcam, "Webcam Cache" }, + { gt_webcam, "Webcam" }, /* opencaching.de */ + { gt_suprise, "Unknown Cache" }, + { gt_earth, "Earthcache" }, + { gt_earth, "Earth" }, /* opencaching.de */ + { gt_cito, "Cache In Trash Out Event" }, + { gt_letterbox, "Letterbox Hybrid" }, + { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, + + { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ }; struct -gs_container_mapping{ - geocache_container type; - const char *name; + gs_container_mapping { + geocache_container type; + const char *name; } gs_container_map[] = { - { gc_other, "Unknown" }, - { gc_other, "Other" }, /* Synonym on read. */ - { gc_micro, "Micro" }, - { gc_regular, "Regular" }, - { gc_large, "Large" }, - { gc_small, "Small" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ + { gc_micro, "Micro" }, + { gc_regular, "Regular" }, + { gc_large, "Large" }, + { gc_small, "Small" }, + { gc_virtual, "Virtual" } }; geocache_type gs_mktype(const char *t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { - return gs_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { + return gs_type_map[i].type; + } + } + return gt_unknown; } const char * gs_get_cachetype(geocache_type t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_type_map[i].type) { - return gs_type_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_type_map[i].type) { + return gs_type_map[i].name; + } + } + return "Unknown"; } geocache_container gs_mkcont(const char *t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { - return gs_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { + return gs_container_map[i].type; + } + } + return gc_unknown; } const char * gs_get_container(geocache_container t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_container_map[i].type) { - return gs_container_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_container_map[i].type) { + return gs_container_map[i].name; + } + } + return "Unknown"; } -time_t -xml_parse_time( const char *cdatastr, int *microsecs ) +time_t +xml_parse_time(const char *cdatastr, int *microsecs) { - int off_hr = 0; - int off_min = 0; - int off_sign = 1; - char *offsetstr = NULL; - char *pointstr = NULL; - struct tm tm; - time_t rv = 0; - char *timestr = xstrdup( cdatastr ); - - memset(&tm, 0, sizeof(tm)); - - offsetstr = strchr( timestr, 'Z' ); - if ( offsetstr ) { - /* zulu time; offsets stay at defaults */ - *offsetstr = '\0'; - } else { - offsetstr = strchr( timestr, '+' ); - if ( offsetstr ) { - /* positive offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min ); - } else { - offsetstr = strchr( timestr, 'T' ); - if ( offsetstr ) { - offsetstr = strchr( offsetstr, '-' ); - if ( offsetstr ) { - /* negative offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", - &off_hr, &off_min ); - off_sign = -1; - } - } - } - } - - pointstr = strchr( timestr, '.' ); - if ( pointstr ) { - if (microsecs) { - double fsec; - sscanf(pointstr, "%le", &fsec); - /* Round to avoid FP jitter */ - *microsecs = .5 + (fsec * 1000000.0) ; - } - *pointstr = '\0'; - } - - sscanf(timestr, "%d-%d-%dT%d:%d:%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday, - &tm.tm_hour, - &tm.tm_min, - &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - - rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; - - xfree(timestr); - - return rv; + int off_hr = 0; + int off_min = 0; + int off_sign = 1; + char *offsetstr = NULL; + char *pointstr = NULL; + struct tm tm; + time_t rv = 0; + char *timestr = xstrdup(cdatastr); + + memset(&tm, 0, sizeof(tm)); + + offsetstr = strchr(timestr, 'Z'); + if (offsetstr) { + /* zulu time; offsets stay at defaults */ + *offsetstr = '\0'; + } else { + offsetstr = strchr(timestr, '+'); + if (offsetstr) { + /* positive offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", &off_hr, &off_min); + } else { + offsetstr = strchr(timestr, 'T'); + if (offsetstr) { + offsetstr = strchr(offsetstr, '-'); + if (offsetstr) { + /* negative offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", + &off_hr, &off_min); + off_sign = -1; + } + } + } + } + + pointstr = strchr(timestr, '.'); + if (pointstr) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } + *pointstr = '\0'; + } + + sscanf(timestr, "%d-%d-%dT%d:%d:%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; + + xfree(timestr); + + return rv; } static void gpx_end(void *data, const XML_Char *xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - char *s = strrchr(current_tag.mem, '/'); - float x; - char *cdatastrp = cdatastr.mem; - int passthrough; - static time_t gc_log_date; - tag_type tag; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - - tag = get_tag(current_tag.mem, &passthrough); - switch(tag) { - /* - * First, the tags that are file-global. - */ - case tt_name: - gpx_add_to_global(&gpx_global->name, cdatastrp); - break; - case tt_desc: - gpx_add_to_global(&gpx_global->desc, cdatastrp); - break; - case tt_author: - gpx_add_to_global(&gpx_global->author, cdatastrp); - break; - case tt_email: - gpx_add_to_global(&gpx_global->email, cdatastrp); - if (gpx_email == NULL) { - gpx_email = xstrdup(cdatastrp); - } - break; - case tt_url: - gpx_add_to_global(&gpx_global->url, cdatastrp); - break; - case tt_urlname: - gpx_add_to_global(&gpx_global->urlname, cdatastrp); - break; - case tt_keywords: - gpx_add_to_global(&gpx_global->keywords, cdatastrp); - break; - - /* - * Waypoint-specific tags. - */ - case tt_wpt: - waypt_add(wpt_tmp); - logpoint_ct = 0; - cur_tag = NULL; - wpt_tmp = NULL; - break; - case tt_cache_name: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_cache_container: - wpt_tmp->gc_data.container = gs_mkcont(cdatastrp); - break; - case tt_cache_type: - wpt_tmp->gc_data.type = gs_mktype(cdatastrp); - break; - case tt_cache_difficulty: - sscanf(cdatastrp, "%f", &x); - wpt_tmp->gc_data.diff = x * 10; - break; - case tt_cache_hint: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.hint = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_long: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.desc_long.is_html = cache_descr_is_html; - wpt_tmp->gc_data.desc_long.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_short: - rtrim(cdatastrp); - if (cdatastrp[0]) { - wpt_tmp->gc_data.desc_short.is_html = cache_descr_is_html; - wpt_tmp->gc_data.desc_short.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_terrain: - sscanf(cdatastrp, "%f", &x); - wpt_tmp->gc_data.terr = x * 10; - break; - case tt_cache_placer: - wpt_tmp->gc_data.placer = xstrdup(cdatastrp); - break; - case tt_cache_log_date: - gc_log_date = xml_parse_time( cdatastrp, NULL ); - break; - /* - * "Found it" logs follow the date according to the schema, - * if this is the first "found it" for this waypt, just use the - * last date we saw in this log. - */ - case tt_cache_log_type: - if ((0 == strcmp(cdatastrp, "Found it")) && - (0 == wpt_tmp->gc_data.last_found)) { - wpt_tmp->gc_data.last_found = gc_log_date; - } - gc_log_date = 0; - break; - - /* - * Garmin-waypoint-specific tags. - */ - case tt_garmin_wpt_proximity: - case tt_garmin_wpt_temperature: - case tt_garmin_wpt_depth: - case tt_garmin_wpt_display_mode: - case tt_garmin_wpt_category: - case tt_garmin_wpt_addr: - case tt_garmin_wpt_city: - case tt_garmin_wpt_state: - case tt_garmin_wpt_country: - case tt_garmin_wpt_postal_code: - case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); - break; - - /* - * Route-specific tags. - */ - case tt_rte_name: - rte_head->rte_name = xstrdup(cdatastrp); - break; - case tt_rte: - break; - case tt_rte_rtept: - route_add_wpt(rte_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_rte_desc: - rte_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_rte_number: - rte_head->rte_num = atoi(cdatastrp); - break; - /* - * Track-specific tags. - */ - case tt_trk_name: - trk_head->rte_name = xstrdup(cdatastrp); - break; - case tt_trk: - break; - case tt_trk_trkseg_trkpt: - track_add_wpt(trk_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_trk_desc: - trk_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_trk_number: - trk_head->rte_num = atoi(cdatastrp); - break; - case tt_trk_trkseg_trkpt_course: - WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_speed: - WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); - break; - - /* - * Items that are actually in multiple categories. - */ - case tt_wpt_ele: - case tt_rte_rtept_ele: - case tt_trk_trkseg_trkpt_ele: - sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); - break; - case tt_wpt_name: - case tt_rte_rtept_name: - case tt_trk_trkseg_trkpt_name: - wpt_tmp->shortname = xstrdup(cdatastrp); - break; - case tt_wpt_sym: - case tt_rte_rtept_sym: - case tt_trk_trkseg_trkpt_sym: - wpt_tmp->icon_descr = xstrdup(cdatastrp); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case tt_wpt_time: - case tt_trk_trkseg_trkpt_time: - case tt_rte_rtept_time: - wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); - break; - case tt_wpt_cmt: - case tt_rte_rtept_cmt: - case tt_trk_trkseg_trkpt_cmt: - wpt_tmp->description = xstrdup(cdatastrp); - break; - case tt_wpt_desc: - case tt_trk_trkseg_trkpt_desc: - case tt_rte_rtept_desc: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_pdop: - wpt_tmp->pdop = atof(cdatastrp); - break; - case tt_hdop: - wpt_tmp->hdop = atof(cdatastrp); - break; - case tt_vdop: - wpt_tmp->vdop = atof(cdatastrp); - break; - case tt_sat: - wpt_tmp->sat = atof(cdatastrp); - break; - case tt_fix: - wpt_tmp->fix = atoi(cdatastrp)-1; - if ( wpt_tmp->fix < fix_2d) { - if (!case_ignore_strcmp(cdatastrp, "none")) - wpt_tmp->fix = fix_none; - else if (!case_ignore_strcmp(cdatastrp, "dgps")) - wpt_tmp->fix = fix_dgps; - else if (!case_ignore_strcmp(cdatastrp, "pps")) - wpt_tmp->fix = fix_pps; - else - wpt_tmp->fix = fix_unknown; - } - break; - case tt_wpt_url: - case tt_trk_trkseg_trkpt_url: - case tt_rte_rtept_url: - wpt_tmp->url = xstrdup(cdatastrp); - break; - case tt_wpt_urlname: - case tt_trk_trkseg_trkpt_urlname: - case tt_rte_rtept_urlname: - wpt_tmp->url_link_text = xstrdup(cdatastrp); - break; - case tt_wpt_link: -//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: -//TODO: implement GPX 1.1 case tt_rte_rtept_link: - { - char *lt = link_text; - if (lt) { - lt = xstrdup(lrtrim(link_text)); - } - - waypt_add_url(wpt_tmp, xstrdup(link_url), lt); - link_text = NULL; - } - break; - case tt_unknown: - end_something_else(); - *s = 0; - return; - default: - break; - } - - if (passthrough) { - end_something_else(); - } - - *s = 0; - xml_free_converted_string(el); + const char *el = xml_convert_to_char_string(xml_el); + char *s = strrchr(current_tag.mem, '/'); + float x; + char *cdatastrp = cdatastr.mem; + int passthrough; + static time_t gc_log_date; + tag_type tag; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + /* + * First, the tags that are file-global. + */ + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); + break; + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); + break; + case tt_author: + gpx_add_to_global(&gpx_global->author, cdatastrp); + break; + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); + break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + + /* + * Waypoint-specific tags. + */ + case tt_wpt: + waypt_add(wpt_tmp); + logpoint_ct = 0; + cur_tag = NULL; + wpt_tmp = NULL; + break; + case tt_cache_name: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_cache_container: + wpt_tmp->gc_data.container = gs_mkcont(cdatastrp); + break; + case tt_cache_type: + wpt_tmp->gc_data.type = gs_mktype(cdatastrp); + break; + case tt_cache_difficulty: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.diff = x * 10; + break; + case tt_cache_hint: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.hint = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_long: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_long.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_long.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_short: + rtrim(cdatastrp); + if (cdatastrp[0]) { + wpt_tmp->gc_data.desc_short.is_html = cache_descr_is_html; + wpt_tmp->gc_data.desc_short.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_terrain: + sscanf(cdatastrp, "%f", &x); + wpt_tmp->gc_data.terr = x * 10; + break; + case tt_cache_placer: + wpt_tmp->gc_data.placer = xstrdup(cdatastrp); + break; + case tt_cache_log_date: + gc_log_date = xml_parse_time(cdatastrp, NULL); + break; + /* + * "Found it" logs follow the date according to the schema, + * if this is the first "found it" for this waypt, just use the + * last date we saw in this log. + */ + case tt_cache_log_type: + if ((0 == strcmp(cdatastrp, "Found it")) && + (0 == wpt_tmp->gc_data.last_found)) { + wpt_tmp->gc_data.last_found = gc_log_date; + } + gc_log_date = 0; + break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_wpt_proximity: + case tt_garmin_wpt_temperature: + case tt_garmin_wpt_depth: + case tt_garmin_wpt_display_mode: + case tt_garmin_wpt_category: + case tt_garmin_wpt_addr: + case tt_garmin_wpt_city: + case tt_garmin_wpt_state: + case tt_garmin_wpt_country: + case tt_garmin_wpt_postal_code: + case tt_garmin_wpt_phone_nr: + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); + break; + + /* + * Route-specific tags. + */ + case tt_rte_name: + rte_head->rte_name = xstrdup(cdatastrp); + break; + case tt_rte: + break; + case tt_rte_rtept: + route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_rte_desc: + rte_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_rte_number: + rte_head->rte_num = atoi(cdatastrp); + break; + /* + * Track-specific tags. + */ + case tt_trk_name: + trk_head->rte_name = xstrdup(cdatastrp); + break; + case tt_trk: + break; + case tt_trk_trkseg_trkpt: + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_trk_desc: + trk_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_trk_number: + trk_head->rte_num = atoi(cdatastrp); + break; + case tt_trk_trkseg_trkpt_course: + WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_speed: + WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); + break; + + /* + * Items that are actually in multiple categories. + */ + case tt_wpt_ele: + case tt_rte_rtept_ele: + case tt_trk_trkseg_trkpt_ele: + sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); + break; + case tt_wpt_name: + case tt_rte_rtept_name: + case tt_trk_trkseg_trkpt_name: + wpt_tmp->shortname = xstrdup(cdatastrp); + break; + case tt_wpt_sym: + case tt_rte_rtept_sym: + case tt_trk_trkseg_trkpt_sym: + wpt_tmp->icon_descr = xstrdup(cdatastrp); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case tt_wpt_time: + case tt_trk_trkseg_trkpt_time: + case tt_rte_rtept_time: + wpt_tmp->creation_time = xml_parse_time(cdatastrp, &wpt_tmp->microseconds); + break; + case tt_wpt_cmt: + case tt_rte_rtept_cmt: + case tt_trk_trkseg_trkpt_cmt: + wpt_tmp->description = xstrdup(cdatastrp); + break; + case tt_wpt_desc: + case tt_trk_trkseg_trkpt_desc: + case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_pdop: + wpt_tmp->pdop = atof(cdatastrp); + break; + case tt_hdop: + wpt_tmp->hdop = atof(cdatastrp); + break; + case tt_vdop: + wpt_tmp->vdop = atof(cdatastrp); + break; + case tt_sat: + wpt_tmp->sat = atof(cdatastrp); + break; + case tt_fix: + wpt_tmp->fix = atoi(cdatastrp)-1; + if (wpt_tmp->fix < fix_2d) { + if (!case_ignore_strcmp(cdatastrp, "none")) { + wpt_tmp->fix = fix_none; + } else if (!case_ignore_strcmp(cdatastrp, "dgps")) { + wpt_tmp->fix = fix_dgps; + } else if (!case_ignore_strcmp(cdatastrp, "pps")) { + wpt_tmp->fix = fix_pps; + } else { + wpt_tmp->fix = fix_unknown; + } + } + break; + case tt_wpt_url: + case tt_trk_trkseg_trkpt_url: + case tt_rte_rtept_url: + wpt_tmp->url = xstrdup(cdatastrp); + break; + case tt_wpt_urlname: + case tt_trk_trkseg_trkpt_urlname: + case tt_rte_rtept_urlname: + wpt_tmp->url_link_text = xstrdup(cdatastrp); + break; + case tt_wpt_link: +//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: +//TODO: implement GPX 1.1 case tt_rte_rtept_link: + { + char *lt = link_text; + if (lt) { + lt = xstrdup(lrtrim(link_text)); + } + + waypt_add_url(wpt_tmp, xstrdup(link_url), lt); + link_text = NULL; + } + break; + case tt_unknown: + end_something_else(); + *s = 0; + return; + default: + break; + } + + if (passthrough) { + end_something_else(); + } + + *s = 0; + xml_free_converted_string(el); } #if ! HAVE_LIBEXPAT static void gpx_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } -static void -gpx_rd_deinit(void) +static void +gpx_rd_deinit(void) { } @@ -1023,331 +1023,329 @@ gpx_rd_deinit(void) static void gpx_cdata(void *dta, const XML_Char *xml_el, int len) { - char *estr; - int *cdatalen; - char **cdata; - xml_tag *tmp_tag; - size_t slen = strlen(cdatastr.mem); - const char *s = xml_convert_to_char_string_n(xml_el, &len); - - vmem_realloc(&cdatastr, 1 + len + slen); - estr = ((char *) cdatastr.mem) + slen; - memcpy(estr, s, len); - estr[len] = 0; - - if (!cur_tag) - return; - - if ( cur_tag->child ) { - tmp_tag = cur_tag->child; - while ( tmp_tag->sibling ) { - tmp_tag = tmp_tag->sibling; - } - cdata = &(tmp_tag->parentcdata); - cdatalen = &(tmp_tag->parentcdatalen); - } - else { - cdata = &(cur_tag->cdata); - cdatalen = &(cur_tag->cdatalen); - } - estr = *cdata; - *cdata = xcalloc( *cdatalen + len + 1, 1); - if ( estr ) { - memcpy( *cdata, estr, *cdatalen); - xfree( estr ); - } - estr = *cdata + *cdatalen; - memcpy( estr, s, len ); - *(estr+len) = '\0'; - *cdatalen += len; - - xml_free_converted_string(s); + char *estr; + int *cdatalen; + char **cdata; + xml_tag *tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char *s = xml_convert_to_char_string_n(xml_el, &len); + + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char *) cdatastr.mem) + slen; + memcpy(estr, s, len); + estr[len] = 0; + + if (!cur_tag) { + return; + } + + if (cur_tag->child) { + tmp_tag = cur_tag->child; + while (tmp_tag->sibling) { + tmp_tag = tmp_tag->sibling; + } + cdata = &(tmp_tag->parentcdata); + cdatalen = &(tmp_tag->parentcdatalen); + } else { + cdata = &(cur_tag->cdata); + cdatalen = &(cur_tag->cdatalen); + } + estr = *cdata; + *cdata = xcalloc(*cdatalen + len + 1, 1); + if (estr) { + memcpy(*cdata, estr, *cdatalen); + xfree(estr); + } + estr = *cdata + *cdatalen; + memcpy(estr, s, len); + *(estr+len) = '\0'; + *cdatalen += len; + + xml_free_converted_string(s); } static void gpx_rd_init(const char *fname) { - if ( fname[0] ) { - fd = gbfopen(fname, "r", MYNAME); - input_fname = fname; - } - else { - fd = NULL; - input_string = fname+1; - input_string_len = strlen(input_string); - input_fname = NULL; - } - - - file_time = 0; - current_tag = vmem_alloc(1, 0); - *((char *)current_tag.mem) = '\0'; - - prescan_tags(); - - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; - - if (!xsi_schema_loc) { - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); - } - if (!xsi_schema_loc) { - fatal("gpx: Unable to allocate %ld bytes of memory.\n", - (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); - } - - if (NULL == gpx_global) { - gpx_global = xcalloc(sizeof(*gpx_global), 1); - QUEUE_INIT(&gpx_global->name.queue); - QUEUE_INIT(&gpx_global->desc.queue); - QUEUE_INIT(&gpx_global->author.queue); - QUEUE_INIT(&gpx_global->email.queue); - QUEUE_INIT(&gpx_global->url.queue); - QUEUE_INIT(&gpx_global->urlname.queue); - QUEUE_INIT(&gpx_global->keywords.queue); - } - - XML_SetElementHandler(psr, gpx_start, gpx_end); - XML_SetCharacterDataHandler(psr, gpx_cdata); - fs_ptr = NULL; + if (fname[0]) { + fd = gbfopen(fname, "r", MYNAME); + input_fname = fname; + } else { + fd = NULL; + input_string = fname+1; + input_string_len = strlen(input_string); + input_fname = NULL; + } + + + file_time = 0; + current_tag = vmem_alloc(1, 0); + *((char *)current_tag.mem) = '\0'; + + prescan_tags(); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; + + if (!xsi_schema_loc) { + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); + } + if (!xsi_schema_loc) { + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); + } + + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; } -static -void -gpx_rd_deinit(void) +static +void +gpx_rd_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - /* - * Don't free schema_loc. It really is important that we preserve - * this across reads or else merges/copies of files with different - * schemas won't retain the headers. - * - * moved to gpx_exit - - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - */ - - if ( gpx_email ) { - xfree(gpx_email); - gpx_email = NULL; - } - if ( gpx_author ) { - xfree(gpx_author); - gpx_author = NULL; - } - if (fd) { - gbfclose(fd); - } - XML_ParserFree(psr); - psr = NULL; - wpt_tmp = NULL; - cur_tag = NULL; - input_fname = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + /* + * Don't free schema_loc. It really is important that we preserve + * this across reads or else merges/copies of files with different + * schemas won't retain the headers. + * + * moved to gpx_exit + + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + */ + + if (gpx_email) { + xfree(gpx_email); + gpx_email = NULL; + } + if (gpx_author) { + xfree(gpx_author); + gpx_author = NULL; + } + if (fd) { + gbfclose(fd); + } + XML_ParserFree(psr); + psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; + input_fname = NULL; } #endif static void gpx_wr_init(const char *fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void gpx_wr_deinit(void) { - gbfclose(ofd); - mkshort_del_handle(&mkshort_handle); + gbfclose(ofd); + mkshort_del_handle(&mkshort_handle); } void gpx_read(void) { #if HAVE_LIBEXPAT - int len; - int done = 0; - char *buf = xmalloc(MY_CBUF_SZ); - int result = 0; - int extra; - - while (!done) { - if ( fd ) { - /* - * The majority of this block (in fact, all but the - * call to XML_Parse) are a disgusting hack to - * correct defective GPX files that Geocaching.com - * issues as pocket queries. They contain escape - * characters as entities (�-) which makes - * them not validate which croaks expat and torments - * users. - * - * Look for '&' in the last maxentlength chars. If - * we find it, strip it, then read byte-at-a-time - * until we find a non-entity. - */ - char *badchar; - char *semi; - int maxentlength = 8; - len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); - done = gbfeof(fd) || !len; - buf[len] = '\0'; - if (len < maxentlength) { - maxentlength = len; - } - badchar = buf+len-maxentlength; - badchar = strchr( badchar, '&' ); - extra = maxentlength - 1; /* for terminator */ - while ( badchar && len < MY_CBUF_SZ-1) { - semi = strchr( badchar, ';'); - while ( extra && !semi ) { - len += gbfread( buf+len, 1, 1, fd); - buf[len]='\0'; - extra--; - if ( buf[len-1] == ';') - semi= buf+len-1; - } - badchar = strchr( badchar+1, '&' ); - } - { - char *hex="0123456789abcdef"; - badchar = strstr( buf, "&#x" ); - while ( badchar ) { - int val = 0; - char *hexit = badchar+3; - semi = strchr( badchar, ';' ); - if ( semi ) { - while (*hexit && *hexit != ';') { - char hc = isalpha(*hexit) ? tolower (*hexit) : *hexit; - val *= 16; - val += strchr( hex, hc)-hex; - hexit++; - } - - if ( val < 32 ) { - warning( MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)" ); - memmove( badchar, semi+1, strlen(semi+1)+1 ); - len -= (semi-badchar)+1; - badchar--; - } - } - badchar = strstr( badchar+1, "&#x" ); - } - } - result = XML_Parse(psr, buf, len, done); - } - else if (input_string) { - done = 0; - result = XML_Parse(psr, input_string, - input_string_len, done ); - done = 1; - } - else { - done = 1; - result = -1; - } - if (!result) { - fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", - (int) XML_GetCurrentLineNumber(psr), - input_fname ? input_fname : "unknown file", - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - xfree(buf); + int len; + int done = 0; + char *buf = xmalloc(MY_CBUF_SZ); + int result = 0; + int extra; + + while (!done) { + if (fd) { + /* + * The majority of this block (in fact, all but the + * call to XML_Parse) are a disgusting hack to + * correct defective GPX files that Geocaching.com + * issues as pocket queries. They contain escape + * characters as entities (�-) which makes + * them not validate which croaks expat and torments + * users. + * + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. + */ + char *badchar; + char *semi; + int maxentlength = 8; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; + buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } + badchar = buf+len-maxentlength; + badchar = strchr(badchar, '&'); + extra = maxentlength - 1; /* for terminator */ + while (badchar && len < MY_CBUF_SZ-1) { + semi = strchr(badchar, ';'); + while (extra && !semi) { + len += gbfread(buf+len, 1, 1, fd); + buf[len]='\0'; + extra--; + if (buf[len-1] == ';') { + semi= buf+len-1; + } + } + badchar = strchr(badchar+1, '&'); + } + { + char *hex="0123456789abcdef"; + badchar = strstr(buf, "&#x"); + while (badchar) { + int val = 0; + char *hexit = badchar+3; + semi = strchr(badchar, ';'); + if (semi) { + while (*hexit && *hexit != ';') { + char hc = isalpha(*hexit) ? tolower(*hexit) : *hexit; + val *= 16; + val += strchr(hex, hc)-hex; + hexit++; + } + + if (val < 32) { + warning(MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)"); + memmove(badchar, semi+1, strlen(semi+1)+1); + len -= (semi-badchar)+1; + badchar--; + } + } + badchar = strstr(badchar+1, "&#x"); + } + } + result = XML_Parse(psr, buf, len, done); + } else if (input_string) { + done = 0; + result = XML_Parse(psr, input_string, + input_string_len, done); + done = 1; + } else { + done = 1; + result = -1; + } + if (!result) { + fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", + (int) XML_GetCurrentLineNumber(psr), + input_fname ? input_fname : "unknown file", + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + xfree(buf); #endif /* HAVE_LIBEXPAT */ } static void -fprint_tag_and_attrs( char *prefix, char *suffix, xml_tag *tag ) +fprint_tag_and_attrs(char *prefix, char *suffix, xml_tag *tag) { - char **pa; - gbfprintf( ofd, "%s%s", prefix, tag->tagname ); - pa = tag->attributes; - if ( pa ) { - while ( *pa ) { - gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); - pa += 2; - } - } - gbfprintf( ofd, "%s", suffix ); + char **pa; + gbfprintf(ofd, "%s%s", prefix, tag->tagname); + pa = tag->attributes; + if (pa) { + while (*pa) { + gbfprintf(ofd, " %s=\"%s\"", pa[0], pa[1]); + pa += 2; + } + } + gbfprintf(ofd, "%s", suffix); } static void -fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) +fprint_xml_chain(xml_tag *tag, const waypoint *wpt) { - char *tmp_ent; - while ( tag ) { - if ( !tag->cdata && !tag->child ) { - fprint_tag_and_attrs( "<", " />", tag ); - } - else { - fprint_tag_and_attrs( "<", ">", tag ); - - if ( tag->cdata ) { - tmp_ent = xml_entitize( tag->cdata ); - gbfprintf( ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - if ( tag->child ) { - fprint_xml_chain(tag->child, wpt); - } - if ( wpt && wpt->gc_data.exported && - strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { - xml_write_time( ofd, wpt->gc_data.exported, 0, - "groundspeak:exported" ); - } - gbfprintf( ofd, "\n", tag->tagname); - } - if ( tag->parentcdata ) { - tmp_ent = xml_entitize(tag->parentcdata); - gbfprintf(ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - tag = tag->sibling; - } -} - -void free_gpx_extras( xml_tag *tag ) + char *tmp_ent; + while (tag) { + if (!tag->cdata && !tag->child) { + fprint_tag_and_attrs("<", " />", tag); + } else { + fprint_tag_and_attrs("<", ">", tag); + + if (tag->cdata) { + tmp_ent = xml_entitize(tag->cdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + if (tag->child) { + fprint_xml_chain(tag->child, wpt); + } + if (wpt && wpt->gc_data.exported && + strcmp(tag->tagname, "groundspeak:cache") == 0) { + xml_write_time(ofd, wpt->gc_data.exported, 0, + "groundspeak:exported"); + } + gbfprintf(ofd, "\n", tag->tagname); + } + if (tag->parentcdata) { + tmp_ent = xml_entitize(tag->parentcdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + tag = tag->sibling; + } +} + +void free_gpx_extras(xml_tag *tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag *next = NULL; + char **ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } /* @@ -1356,31 +1354,31 @@ void free_gpx_extras( xml_tag *tag ) static void write_gpx_url(const waypoint *waypointp) { - char *tmp_ent; - - if (waypointp->url == NULL) { - return; - } - - if (gpx_wversion_num > 10) { - url_link *tail; - for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { - tmp_ent = xml_entitize(tail->url); - gbfprintf(ofd, " \n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "text", - tail->url_link_text); - gbfprintf(ofd, " \n"); - xfree(tmp_ent); - } - } else { - tmp_ent = xml_entitize(waypointp->url); - gbfprintf(ofd, " %s%s\n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "urlname", - waypointp->url_link_text); - xfree(tmp_ent); - } + char *tmp_ent; + + if (waypointp->url == NULL) { + return; + } + + if (gpx_wversion_num > 10) { + url_link *tail; + for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { + tmp_ent = xml_entitize(tail->url); + gbfprintf(ofd, " \n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "text", + tail->url_link_text); + gbfprintf(ofd, " \n"); + xfree(tmp_ent); + } + } else { + tmp_ent = xml_entitize(waypointp->url); + gbfprintf(ofd, " %s%s\n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "urlname", + waypointp->url_link_text); + xfree(tmp_ent); + } } /* @@ -1391,383 +1389,396 @@ write_gpx_url(const waypoint *waypointp) static void gpx_write_common_acc(const waypoint *waypointp, const char *indent) { - char *fix = NULL; - - switch (waypointp->fix) { - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - case fix_none: - fix = "none"; - break; - /* GPX spec says omit if we don't know. */ - case fix_unknown: - default: - break; - } - if (fix) { - gbfprintf(ofd, "%s%s\n", indent, fix); - } - if (waypointp->sat > 0) { - gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); - } - if (waypointp->hdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); - } - if (waypointp->vdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); - } - if (waypointp->pdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); - } + char *fix = NULL; + + switch (waypointp->fix) { + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; + } + if (fix) { + gbfprintf(ofd, "%s%s\n", indent, fix); + } + if (waypointp->sat > 0) { + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); + } + if (waypointp->hdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); + } + if (waypointp->vdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); + } + if (waypointp->pdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); + } } static void gpx_write_common_position(const waypoint *waypointp, const char *indent) { - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, "%s%f\n", - indent, waypointp->altitude); - } - if (waypointp->creation_time) { - xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); - } + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, "%s%f\n", + indent, waypointp->altitude); + } + if (waypointp->creation_time) { + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); + } } static void gpx_write_common_description(const waypoint *waypointp, const char *indent, - const char *oname) + const char *oname) { - write_optional_xml_entity(ofd, indent, "name", oname); - write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); - if (waypointp->notes && waypointp->notes[0]) - write_xml_entity(ofd, indent, "desc", waypointp->notes); - else - write_optional_xml_entity(ofd, indent, "desc", waypointp->description); - write_gpx_url(waypointp); - write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); + write_optional_xml_entity(ofd, indent, "name", oname); + write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); + if (waypointp->notes && waypointp->notes[0]) { + write_xml_entity(ofd, indent, "desc", waypointp->notes); + } else { + write_optional_xml_entity(ofd, indent, "desc", waypointp->description); + } + write_gpx_url(waypointp); + write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); } static void gpx_waypt_pr(const waypoint *waypointp) { - const char *oname; - char *odesc; - fs_xml *fs_gpx; - garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = waypointp->notes; - if (!odesc) { - odesc = waypointp->description; - } - if (!odesc) { - odesc = waypointp->shortname; - } - - oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", oname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - gmsd = GMSD_FIND(waypointp); - if ( fs_gpx ) { - if (! gmsd) fprint_xml_chain( fs_gpx->tag, waypointp ); - } - if (gmsd && (gpx_wversion_num > 10)) { - /* MapSource doesn't accepts extensions from 1.0 */ - garmin_fs_xml_fprint(ofd, waypointp); - } - gbfprintf(ofd, "\n"); + const char *oname; + char *odesc; + fs_xml *fs_gpx; + garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", oname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + gmsd = GMSD_FIND(waypointp); + if (fs_gpx) { + if (! gmsd) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + } + if (gmsd && (gpx_wversion_num > 10)) { + /* MapSource doesn't accepts extensions from 1.0 */ + garmin_fs_xml_fprint(ofd, waypointp); + } + gbfprintf(ofd, "\n"); } static void gpx_track_hdr(const route_head *rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, "%d\n", rte->rte_num); - } - gbfprintf(ofd, "\n"); - - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, "%d\n", rte->rte_num); + } + gbfprintf(ofd, "\n"); + + fs_gpx = (fs_xml *)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } } static void gpx_track_disp(const waypoint *waypointp) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - - /* These were accidentally removed from 1.1 */ - if (gpx_wversion_num == 10) { - if WAYPT_HAS(waypointp, course) { - gbfprintf(ofd, " %f\n", - waypointp->course); - } - if WAYPT_HAS(waypointp, speed) { - gbfprintf(ofd, " %f\n", - waypointp->speed); - } - } - - /* GPX doesn't require a name on output, so if we made one up - * on input, we might as well say nothing. - */ - gpx_write_common_description(waypointp, " ", - waypointp->wpt_flags.shortname_is_synthetic ? - NULL : waypointp->shortname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } - - gbfprintf(ofd, "\n"); + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + + /* These were accidentally removed from 1.1 */ + if (gpx_wversion_num == 10) { + if WAYPT_HAS(waypointp, course) { + gbfprintf(ofd, " %f\n", + waypointp->course); + } + if WAYPT_HAS(waypointp, speed) { + gbfprintf(ofd, " %f\n", + waypointp->speed); + } + } + + /* GPX doesn't require a name on output, so if we made one up + * on input, we might as well say nothing. + */ + gpx_write_common_description(waypointp, " ", + waypointp->wpt_flags.shortname_is_synthetic ? + NULL : waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + + gbfprintf(ofd, "\n"); } static void gpx_track_tlr(const route_head *rte) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_track_pr() { - track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); + track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); } static void gpx_route_hdr(const route_head *rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, " %d\n", rte->rte_num); - } - - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, " %d\n", rte->rte_num); + } + + fs_gpx = (fs_xml *)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } } static void gpx_route_disp(const waypoint *waypointp) { - fs_xml *fs_gpx; + fs_xml *fs_gpx; - gbfprintf(ofd, " \n", - waypointp->latitude, - waypointp->longitude); + gbfprintf(ofd, " \n", + waypointp->latitude, + waypointp->longitude); - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", waypointp->shortname); - gpx_write_common_acc(waypointp, " "); + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", waypointp->shortname); + gpx_write_common_acc(waypointp, " "); - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void gpx_route_tlr(const route_head *rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_route_pr() { - /* output routes */ - route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); + /* output routes */ + route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); } static void gpx_waypt_bound_calc(const waypoint *waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void gpx_write_bounds(void) { - waypt_init_bounds(&all_bounds); - - waypt_disp_all(gpx_waypt_bound_calc); - route_disp_all(NULL, NULL, gpx_waypt_bound_calc); - track_disp_all(NULL, NULL, gpx_waypt_bound_calc); - - if (waypt_bounds_valid(&all_bounds)) { - gbfprintf(ofd, "\n", - all_bounds.min_lat, all_bounds.min_lon, - all_bounds.max_lat, all_bounds.max_lon); - } + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + gbfprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } } static void gpx_write(void) { - time_t now = 0; - int short_length; - - gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; - - if (gpx_wversion_num <= 0) { - fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); - } - - now = current_time(); - - short_length = atoi(snlen); - - if (suppresswhite) { - setshort_whitespace_ok(mkshort_handle, 0); - } - - setshort_length(mkshort_handle, short_length); - - gbfprintf(ofd, "\n", global_opts.charset_name); - gbfprintf(ofd, "\n", xsi_schema_loc); - } else { - gbfprintf(ofd, - "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", - gpx_wversion[0], gpx_wversion[2], - gpx_wversion[0], gpx_wversion[2]); - } - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - gpx_write_gdata(&gpx_global->name, "name"); - gpx_write_gdata(&gpx_global->desc, "desc"); - /* In GPX 1.1, author changed from a string to a PersonType. - * since it's optional, we just drop it instead of rewriting it. - */ - if (gpx_wversion_num < 11) { - gpx_write_gdata(&gpx_global->author, "author"); - } - gpx_write_gdata(&gpx_global->email, "email"); - gpx_write_gdata(&gpx_global->url, "url"); - gpx_write_gdata(&gpx_global->urlname, "urlname"); - xml_write_time( ofd, now, 0, "time" ); - gpx_write_gdata(&gpx_global->keywords, "keywords"); - - gpx_write_bounds(); - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - - waypt_disp_all(gpx_waypt_pr); - gpx_route_pr(); - gpx_track_pr(); - - gbfprintf(ofd, "\n"); + time_t now = 0; + int short_length; + + gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; + + if (gpx_wversion_num <= 0) { + fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); + } + + now = current_time(); + + short_length = atoi(snlen); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_handle, 0); + } + + setshort_length(mkshort_handle, short_length); + + gbfprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + } else { + gbfprintf(ofd, + "xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", + gpx_wversion[0], gpx_wversion[2], + gpx_wversion[0], gpx_wversion[2]); + } + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); + } + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + xml_write_time(ofd, now, 0, "time"); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + + waypt_disp_all(gpx_waypt_pr); + gpx_route_pr(); + gpx_track_pr(); + + gbfprintf(ofd, "\n"); } static void gpx_free_gpx_global(void) { - gpx_rm_from_global(&gpx_global->name); - gpx_rm_from_global(&gpx_global->desc); - gpx_rm_from_global(&gpx_global->author); - gpx_rm_from_global(&gpx_global->email); - gpx_rm_from_global(&gpx_global->url); - gpx_rm_from_global(&gpx_global->urlname); - gpx_rm_from_global(&gpx_global->keywords); - xfree(gpx_global); + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); } static void gpx_exit(void) { - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - - if (gpx_global) { - gpx_free_gpx_global(); - gpx_global = NULL; - } + if (xsi_schema_loc) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } } static arglist_t gpx_args[] = { - { "snlen", &snlen, "Length of generated shortnames", - "32", ARGTYPE_INT, "1", NULL }, - { "suppresswhite", &suppresswhite, - "No whitespace in generated shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logpoint", &opt_logpoint, - "Create waypoints from geocache log entries", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "urlbase", &urlbase, "Base URL for link tag in output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - { "gpxver", &gpx_wversion, "Target GPX version for output", - "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", + "32", ARGTYPE_INT, "1", NULL + }, + { + "suppresswhite", &suppresswhite, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logpoint", &opt_logpoint, + "Create waypoints from geocache log entries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &urlbase, "Base URL for link tag in output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "gpxver", &gpx_wversion, "Target GPX version for output", + "1.0", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t gpx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gpx_rd_init, - gpx_wr_init, - gpx_rd_deinit, - gpx_wr_deinit, - gpx_read, - gpx_write, - gpx_exit, - gpx_args, - CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, + gpx_exit, + gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ }; #endif diff --git a/gpsbabel/garmin_fs.c b/gpsbabel/garmin_fs.c index 04727478e..a893d7413 100644 --- a/gpsbabel/garmin_fs.c +++ b/gpsbabel/garmin_fs.c @@ -1,7 +1,7 @@ /* - + Implementation of special data used by Garmin products. - + Copyright (C) 2006, 2007, 2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -33,391 +33,461 @@ "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \ "xsi:schemaLocation=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3 " \ "http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd" - + garmin_fs_t * garmin_fs_alloc(const int protocol) { - garmin_fs_t *result = NULL; - - result = (garmin_fs_t *)xcalloc(1, sizeof(*result)); - result->fs.type = FS_GMSD; - result->fs.copy = (fs_copy) garmin_fs_copy; - result->fs.destroy = garmin_fs_destroy; - result->fs.convert = garmin_fs_convert; - result->fs.next = NULL; - - result->protocol = protocol; - - return result; + garmin_fs_t *result = NULL; + + result = (garmin_fs_t *)xcalloc(1, sizeof(*result)); + result->fs.type = FS_GMSD; + result->fs.copy = (fs_copy) garmin_fs_copy; + result->fs.destroy = garmin_fs_destroy; + result->fs.convert = garmin_fs_convert; + result->fs.next = NULL; + + result->protocol = protocol; + + return result; } -void +void garmin_fs_destroy(void *fs) { - garmin_fs_t *data = (garmin_fs_t *) fs; - if (data != NULL) - { - garmin_ilink_t *ilinks; - - if (data->addr != NULL) xfree(data->addr); - if (data->cc != NULL) xfree(data->cc); - if (data->city != NULL) xfree(data->city); - if (data->country != NULL) xfree(data->country); - if (data->cross_road != NULL) xfree(data->cross_road); - if (data->facility != NULL) xfree(data->facility); - if (data->phone_nr != NULL) xfree(data->phone_nr); - if (data->phone_nr2 != NULL) xfree(data->phone_nr2); - if (data->fax_nr != NULL) xfree(data->fax_nr); - if (data->email != NULL) xfree(data->email); - if (data->postal_code != NULL) xfree(data->postal_code); - if (data->state != NULL) xfree(data->state); - - if ((ilinks = data->ilinks) != NULL) { - ilinks->ref_count--; - if (ilinks->ref_count <= 0) { - while (ilinks != NULL) { - garmin_ilink_t *tmp = ilinks; - ilinks = ilinks->next; - xfree(tmp); - } - } - } - xfree(data); - } + garmin_fs_t *data = (garmin_fs_t *) fs; + if (data != NULL) { + garmin_ilink_t *ilinks; + + if (data->addr != NULL) { + xfree(data->addr); + } + if (data->cc != NULL) { + xfree(data->cc); + } + if (data->city != NULL) { + xfree(data->city); + } + if (data->country != NULL) { + xfree(data->country); + } + if (data->cross_road != NULL) { + xfree(data->cross_road); + } + if (data->facility != NULL) { + xfree(data->facility); + } + if (data->phone_nr != NULL) { + xfree(data->phone_nr); + } + if (data->phone_nr2 != NULL) { + xfree(data->phone_nr2); + } + if (data->fax_nr != NULL) { + xfree(data->fax_nr); + } + if (data->email != NULL) { + xfree(data->email); + } + if (data->postal_code != NULL) { + xfree(data->postal_code); + } + if (data->state != NULL) { + xfree(data->state); + } + + if ((ilinks = data->ilinks) != NULL) { + ilinks->ref_count--; + if (ilinks->ref_count <= 0) { + while (ilinks != NULL) { + garmin_ilink_t *tmp = ilinks; + ilinks = ilinks->next; + xfree(tmp); + } + } + } + xfree(data); + } } void garmin_fs_copy(garmin_fs_t **dest, garmin_fs_t *src) { - if (src == NULL) - { - *dest = NULL; - return; - } - *dest = (garmin_fs_t *) xmalloc(sizeof(*src)); - - /* do not copy interlinks, only increment the refrence counter */ - if (src->ilinks != NULL) src->ilinks->ref_count++; - - memcpy(*dest, src, sizeof(*src)); - - (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; - (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; - (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; - (*dest)->country = (src->country != NULL) ? xstrdup(src->country) : NULL; - (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; - (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; - (*dest)->phone_nr = (src->phone_nr != NULL) ? xstrdup(src->phone_nr) : NULL; - (*dest)->phone_nr2 = (src->phone_nr2 != NULL) ? xstrdup(src->phone_nr2) : NULL; - (*dest)->fax_nr = (src->fax_nr != NULL) ? xstrdup(src->fax_nr) : NULL; - (*dest)->email = (src->email != NULL) ? xstrdup(src->email) : NULL; - (*dest)->postal_code = (src->postal_code != NULL) ? xstrdup(src->postal_code) : NULL; - (*dest)->state = (src->state != NULL) ? xstrdup(src->state) : NULL; + if (src == NULL) { + *dest = NULL; + return; + } + *dest = (garmin_fs_t *) xmalloc(sizeof(*src)); + + /* do not copy interlinks, only increment the refrence counter */ + if (src->ilinks != NULL) { + src->ilinks->ref_count++; + } + + memcpy(*dest, src, sizeof(*src)); + + (*dest)->addr = (src->addr != NULL) ? xstrdup(src->addr) : NULL; + (*dest)->cc = (src->cc != NULL) ? xstrdup(src->cc) : NULL; + (*dest)->city = (src->city != NULL) ? xstrdup(src->city) : NULL; + (*dest)->country = (src->country != NULL) ? xstrdup(src->country) : NULL; + (*dest)->cross_road = (src->cross_road != NULL) ? xstrdup(src->cross_road) : NULL; + (*dest)->facility = (src->facility != NULL) ? xstrdup(src->facility) : NULL; + (*dest)->phone_nr = (src->phone_nr != NULL) ? xstrdup(src->phone_nr) : NULL; + (*dest)->phone_nr2 = (src->phone_nr2 != NULL) ? xstrdup(src->phone_nr2) : NULL; + (*dest)->fax_nr = (src->fax_nr != NULL) ? xstrdup(src->fax_nr) : NULL; + (*dest)->email = (src->email != NULL) ? xstrdup(src->email) : NULL; + (*dest)->postal_code = (src->postal_code != NULL) ? xstrdup(src->postal_code) : NULL; + (*dest)->state = (src->state != NULL) ? xstrdup(src->state) : NULL; } void garmin_fs_convert(void *fs) { - garmin_fs_t *gmsd = (garmin_fs_t *) fs; - - if (gmsd->addr) gmsd->addr = cet_convert_string(gmsd->addr); - if (gmsd->cc) gmsd->cc = cet_convert_string(gmsd->cc); - if (gmsd->city) gmsd->city = cet_convert_string(gmsd->city); - if (gmsd->country) gmsd->country = cet_convert_string(gmsd->country); - if (gmsd->cross_road) gmsd->cross_road = cet_convert_string(gmsd->cross_road); - if (gmsd->facility) gmsd->facility = cet_convert_string(gmsd->facility); - if (gmsd->phone_nr) gmsd->phone_nr = cet_convert_string(gmsd->phone_nr); - if (gmsd->phone_nr2) gmsd->phone_nr2 = cet_convert_string(gmsd->phone_nr2); - if (gmsd->fax_nr) gmsd->fax_nr = cet_convert_string(gmsd->fax_nr); - if (gmsd->email) gmsd->email = cet_convert_string(gmsd->email); - if (gmsd->postal_code) gmsd->postal_code = cet_convert_string(gmsd->postal_code); - if (gmsd->state) gmsd->state = cet_convert_string(gmsd->state); + garmin_fs_t *gmsd = (garmin_fs_t *) fs; + + if (gmsd->addr) { + gmsd->addr = cet_convert_string(gmsd->addr); + } + if (gmsd->cc) { + gmsd->cc = cet_convert_string(gmsd->cc); + } + if (gmsd->city) { + gmsd->city = cet_convert_string(gmsd->city); + } + if (gmsd->country) { + gmsd->country = cet_convert_string(gmsd->country); + } + if (gmsd->cross_road) { + gmsd->cross_road = cet_convert_string(gmsd->cross_road); + } + if (gmsd->facility) { + gmsd->facility = cet_convert_string(gmsd->facility); + } + if (gmsd->phone_nr) { + gmsd->phone_nr = cet_convert_string(gmsd->phone_nr); + } + if (gmsd->phone_nr2) { + gmsd->phone_nr2 = cet_convert_string(gmsd->phone_nr2); + } + if (gmsd->fax_nr) { + gmsd->fax_nr = cet_convert_string(gmsd->fax_nr); + } + if (gmsd->email) { + gmsd->email = cet_convert_string(gmsd->email); + } + if (gmsd->postal_code) { + gmsd->postal_code = cet_convert_string(gmsd->postal_code); + } + if (gmsd->state) { + gmsd->state = cet_convert_string(gmsd->state); + } } /* GPX - out */ -void +void garmin_fs_xml_fprint(gbfile *ofd, const waypoint *waypt) { - const char *phone, *addr; - garmin_fs_t *gmsd = GMSD_FIND(waypt); - - if (gmsd == NULL) return; - - /* Find out if there is at least one field set */ - addr = GMSD_GET(addr, ""); - if (! *addr) addr = GMSD_GET(city, ""); - if (! *addr) addr = GMSD_GET(country, ""); - if (! *addr) addr = GMSD_GET(postal_code, ""); - if (! *addr) addr = GMSD_GET(state, ""); - - phone = GMSD_GET(phone_nr, ""); - - if (*addr || *phone || - (gmsd->flags.category && gmsd->category) || - WAYPT_HAS(waypt, depth) || - WAYPT_HAS(waypt, proximity) || - WAYPT_HAS(waypt, temperature) || - gmsd->flags.display) - { - int space = 1; - - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - gbfprintf(ofd, "%*s\n", space++ * 2, "", GARMIN_GPX_EXT_REFERENCE); - if WAYPT_HAS(waypt, proximity) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->proximity); - if WAYPT_HAS(waypt, temperature) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->temperature); - if WAYPT_HAS(waypt, depth) - gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->depth); - if (gmsd->flags.display) - { - char *cx; - switch(gmsd->display) - { - case gt_display_mode_symbol: - cx = "SymbolOnly"; - break; - case gt_display_mode_symbol_and_comment: - cx = "SymbolAndDescription"; - break; - default: - cx = "SymbolAndName"; - break; - } - gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); - } - if (gmsd->flags.category && gmsd->category) - { - int i; - gbuint16 cx = gmsd->category; - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - for (i = 0; i < 16; i++) - { - if (cx & 1) - gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); - cx = cx >> 1; - } - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - if (*addr) { - char *str, *tmp; - gbfprintf(ofd, "%*s\n", space++ * 2, ""); - - if ((str = GMSD_GET(addr, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(city, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(state, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(country, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - if ((str = GMSD_GET(postal_code, NULL))) { - tmp = xml_entitize(str); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - - if (*phone) { - char *tmp = xml_entitize(phone); - gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); - xfree(tmp); - } - - gbfprintf(ofd, "%*s\n", --space * 2, ""); - gbfprintf(ofd, "%*s\n", --space * 2, ""); - } - + const char *phone, *addr; + garmin_fs_t *gmsd = GMSD_FIND(waypt); + + if (gmsd == NULL) { + return; + } + + /* Find out if there is at least one field set */ + addr = GMSD_GET(addr, ""); + if (! *addr) { + addr = GMSD_GET(city, ""); + } + if (! *addr) { + addr = GMSD_GET(country, ""); + } + if (! *addr) { + addr = GMSD_GET(postal_code, ""); + } + if (! *addr) { + addr = GMSD_GET(state, ""); + } + + phone = GMSD_GET(phone_nr, ""); + + if (*addr || *phone || + (gmsd->flags.category && gmsd->category) || + WAYPT_HAS(waypt, depth) || + WAYPT_HAS(waypt, proximity) || + WAYPT_HAS(waypt, temperature) || + gmsd->flags.display) { + int space = 1; + + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + gbfprintf(ofd, "%*s\n", space++ * 2, "", GARMIN_GPX_EXT_REFERENCE); + if WAYPT_HAS(waypt, proximity) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->proximity); + } + if WAYPT_HAS(waypt, temperature) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->temperature); + } + if WAYPT_HAS(waypt, depth) { + gbfprintf(ofd, "%*s%.6f\n", space * 2, "", waypt->depth); + } + if (gmsd->flags.display) { + char *cx; + switch (gmsd->display) { + case gt_display_mode_symbol: + cx = "SymbolOnly"; + break; + case gt_display_mode_symbol_and_comment: + cx = "SymbolAndDescription"; + break; + default: + cx = "SymbolAndName"; + break; + } + gbfprintf(ofd, "%*s%s\n", space * 2, "", cx); + } + if (gmsd->flags.category && gmsd->category) { + int i; + gbuint16 cx = gmsd->category; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + for (i = 0; i < 16; i++) { + if (cx & 1) { + gbfprintf(ofd, "%*sCategory %d\n", space*2, "", i+1); + } + cx = cx >> 1; + } + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + if (*addr) { + char *str, *tmp; + gbfprintf(ofd, "%*s\n", space++ * 2, ""); + + if ((str = GMSD_GET(addr, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(city, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(state, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(country, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + if ((str = GMSD_GET(postal_code, NULL))) { + tmp = xml_entitize(str); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + + if (*phone) { + char *tmp = xml_entitize(phone); + gbfprintf(ofd, "%*s%s\n", space * 2, "", tmp); + xfree(tmp); + } + + gbfprintf(ofd, "%*s\n", --space * 2, ""); + gbfprintf(ofd, "%*s\n", --space * 2, ""); + } + } void garmin_fs_xml_convert(const int base_tag, int tag, const char *cdatastr, waypoint *waypt) { - garmin_fs_t *gmsd; - - gmsd = GMSD_FIND(waypt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); - } - - tag -= base_tag; -/* - tt_garmin_waypt_extension, -> 0 - tt_garmin_proximity, -> 1 - tt_garmin_temperature,-> 2 - tt_garmin_depth, -> 3 - tt_garmin_display_mode, -> 4 - tt_garmin_categories, -> 5 - tt_garmin_category, -> 6 - tt_garmin_addr, -> 7 - tt_garmin_city, -> 8 - tt_garmin_state, -> 9 - tt_garmin_country, -> 10 - tt_garmin_postal_code, -> 11 - tt_garmin_phone_nr, -> 12 -*/ - switch(tag) { - case 1: - if (*cdatastr) WAYPT_SET(waypt, proximity, atof(cdatastr)); - break; - case 2: - if (*cdatastr) WAYPT_SET(waypt, temperature, atof(cdatastr)); - break; - case 3: - if (*cdatastr) WAYPT_SET(waypt, depth, atof(cdatastr)); - break; - case 4: - if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { - GMSD_SET(display, gt_display_mode_symbol); - } - else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { - GMSD_SET(display, gt_display_mode_symbol_and_comment); - } - else { - GMSD_SET(display, gt_display_mode_symbol_and_name); - } - break; - case 6: - if ( ! garmin_fs_merge_category(cdatastr, waypt)) - warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); - break; - case 7: - GMSD_SETSTR(addr, cdatastr); - break; - case 8: - GMSD_SETSTR(city, cdatastr); - break; - case 9: - GMSD_SETSTR(state, cdatastr); - break; - case 10: - GMSD_SETSTR(country, cdatastr); - break; - case 11: - GMSD_SETSTR(postal_code, cdatastr); - break; - case 12: - GMSD_SETSTR(phone_nr, cdatastr); - break; - } + garmin_fs_t *gmsd; + + gmsd = GMSD_FIND(waypt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + + tag -= base_tag; + /* + tt_garmin_waypt_extension, -> 0 + tt_garmin_proximity, -> 1 + tt_garmin_temperature,-> 2 + tt_garmin_depth, -> 3 + tt_garmin_display_mode, -> 4 + tt_garmin_categories, -> 5 + tt_garmin_category, -> 6 + tt_garmin_addr, -> 7 + tt_garmin_city, -> 8 + tt_garmin_state, -> 9 + tt_garmin_country, -> 10 + tt_garmin_postal_code, -> 11 + tt_garmin_phone_nr, -> 12 + */ + switch (tag) { + case 1: + if (*cdatastr) { + WAYPT_SET(waypt, proximity, atof(cdatastr)); + } + break; + case 2: + if (*cdatastr) { + WAYPT_SET(waypt, temperature, atof(cdatastr)); + } + break; + case 3: + if (*cdatastr) { + WAYPT_SET(waypt, depth, atof(cdatastr)); + } + break; + case 4: + if (case_ignore_strcmp(cdatastr, "SymbolOnly") == 0) { + GMSD_SET(display, gt_display_mode_symbol); + } else if (case_ignore_strcmp(cdatastr, "SymbolAndDescription") == 0) { + GMSD_SET(display, gt_display_mode_symbol_and_comment); + } else { + GMSD_SET(display, gt_display_mode_symbol_and_name); + } + break; + case 6: + if (! garmin_fs_merge_category(cdatastr, waypt)) { + warning(MYNAME ": Unable to convert category \"%s \"!\n", cdatastr); + } + break; + case 7: + GMSD_SETSTR(addr, cdatastr); + break; + case 8: + GMSD_SETSTR(city, cdatastr); + break; + case 9: + GMSD_SETSTR(state, cdatastr); + break; + case 10: + GMSD_SETSTR(country, cdatastr); + break; + case 11: + GMSD_SETSTR(postal_code, cdatastr); + break; + case 12: + GMSD_SETSTR(phone_nr, cdatastr); + break; + } } -unsigned char +unsigned char garmin_fs_convert_category(const char *category_name, gbuint16 *category) { - int i; - int cat = 0; - - if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && - (1 == sscanf(category_name + 9, "%d", &i)) && - (i >= 1) && (i <= 16)) { - cat = (1 << --i); - } - else if (global_opts.inifile != NULL) { - for (i = 0; i < 16; i++) { - char *c; - char key[3]; - - snprintf(key, sizeof(key), "%d", i + 1); - c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); - if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { - cat = (1 << i); - break; - } - } - } - if (cat == 0) { - return 0; - } - else { - *category = cat; - return 1; - } + int i; + int cat = 0; + + if ((case_ignore_strncmp(category_name, "Category ", 9) == 0) && + (1 == sscanf(category_name + 9, "%d", &i)) && + (i >= 1) && (i <= 16)) { + cat = (1 << --i); + } else if (global_opts.inifile != NULL) { + for (i = 0; i < 16; i++) { + char *c; + char key[3]; + + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + if ((c != NULL) && (case_ignore_strcmp(c, category_name) == 0)) { + cat = (1 << i); + break; + } + } + } + if (cat == 0) { + return 0; + } else { + *category = cat; + return 1; + } } unsigned char garmin_fs_merge_category(const char *category_name, waypoint *waypt) { - gbuint16 cat; - garmin_fs_t *gmsd; - - if (!garmin_fs_convert_category(category_name, &cat)) { - return 0; - } - - gmsd = GMSD_FIND(waypt); - cat = cat | ( GMSD_GET(category, 0) ); - - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); - } - GMSD_SET(category, cat); - return 1; + gbuint16 cat; + garmin_fs_t *gmsd; + + if (!garmin_fs_convert_category(category_name, &cat)) { + return 0; + } + + gmsd = GMSD_FIND(waypt); + cat = cat | (GMSD_GET(category, 0)); + + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&waypt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(category, cat); + return 1; } -void +void garmin_fs_garmin_after_read(const GPS_PWay way, waypoint *wpt, const int protoid) { - garmin_fs_t *gmsd = NULL; - - gmsd = garmin_fs_alloc(protoid); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - /* nothing happens until gmsd is allocated some lines above */ - - /* !!! class needs protocol specific conversion !!! (ToDo) - GMSD_SET(wpt_class, way[i]->wpt_class); - */ - /* flagged data fields */ - GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); - if (way->category != 0) GMSD_SET(category, way->category); - if (way->dst < 1.0e25f) WAYPT_SET(wpt, proximity, way->dst); - if (way->temperature_populated) WAYPT_SET(wpt, temperature, way->temperature); - if (way->dpth < 1.0e25f) WAYPT_SET(wpt, depth, way->dpth); - GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); - GMSD_SETNSTR(state, way->state, sizeof(way->state)); - GMSD_SETSTR(city, way->city); - GMSD_SETSTR(facility, way->facility); - GMSD_SETSTR(cross_road, way->cross_road); - GMSD_SETSTR(addr, way->addr); + garmin_fs_t *gmsd = NULL; + + gmsd = garmin_fs_alloc(protoid); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + /* nothing happens until gmsd is allocated some lines above */ + + /* !!! class needs protocol specific conversion !!! (ToDo) + GMSD_SET(wpt_class, way[i]->wpt_class); + */ + /* flagged data fields */ + GMSD_SET(display, gt_switch_display_mode_value(way->dspl, gps_waypt_type, 1)); + if (way->category != 0) { + GMSD_SET(category, way->category); + } + if (way->dst < 1.0e25f) { + WAYPT_SET(wpt, proximity, way->dst); + } + if (way->temperature_populated) { + WAYPT_SET(wpt, temperature, way->temperature); + } + if (way->dpth < 1.0e25f) { + WAYPT_SET(wpt, depth, way->dpth); + } + GMSD_SETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_SETNSTR(state, way->state, sizeof(way->state)); + GMSD_SETSTR(city, way->city); + GMSD_SETSTR(facility, way->facility); + GMSD_SETSTR(cross_road, way->cross_road); + GMSD_SETSTR(addr, way->addr); } -void +void garmin_fs_garmin_before_write(const waypoint *wpt, GPS_PWay way, const int protoid) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - - if (gmsd == NULL) return; - - /* ToDo: protocol specific conversion of class - way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); - */ - way->dspl = gt_switch_display_mode_value( - GMSD_GET(display, way->dspl), gps_waypt_type, 0); - way->category = GMSD_GET(category, way->category); - way->dpth = WAYPT_GET(wpt, depth, way->dpth); - way->dst = WAYPT_GET(wpt, proximity, way->dpth); - way->temperature = WAYPT_GET(wpt, temperature, way->temperature); - - GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); - GMSD_GETNSTR(city, way->city, sizeof(way->city)); - GMSD_GETNSTR(state, way->state, sizeof(way->state)); - GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); - GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); - GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); + garmin_fs_t *gmsd = GMSD_FIND(wpt); + + if (gmsd == NULL) { + return; + } + + /* ToDo: protocol specific conversion of class + way[i]->wpt_class = GMSD_GET(wpt_class, way[i]->wpt_class); + */ + way->dspl = gt_switch_display_mode_value( + GMSD_GET(display, way->dspl), gps_waypt_type, 0); + way->category = GMSD_GET(category, way->category); + way->dpth = WAYPT_GET(wpt, depth, way->dpth); + way->dst = WAYPT_GET(wpt, proximity, way->dpth); + way->temperature = WAYPT_GET(wpt, temperature, way->temperature); + + GMSD_GETNSTR(cc, way->cc, sizeof(way->cc)); + GMSD_GETNSTR(city, way->city, sizeof(way->city)); + GMSD_GETNSTR(state, way->state, sizeof(way->state)); + GMSD_GETNSTR(facility, way->facility, sizeof(way->facility)); + GMSD_GETNSTR(cross_road, way->cross_road, sizeof(way->cross_road)); + GMSD_GETNSTR(addr, way->addr, sizeof(way->addr)); } diff --git a/gpsbabel/garmin_fs.h b/gpsbabel/garmin_fs.h index 568faa849..1f9b87484 100644 --- a/gpsbabel/garmin_fs.h +++ b/gpsbabel/garmin_fs.h @@ -1,7 +1,7 @@ /* - + Implementation of special data used by Garmin products. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -59,59 +59,58 @@ #define GMSD_GETNSTR(a,b,c) if (gmsd && gmsd->flags.a) strncpy((b),gmsd->a,(c)) typedef struct garmin_ilink_s { - int ref_count; - double lat, lon, alt; - struct garmin_ilink_s *next; + int ref_count; + double lat, lon, alt; + struct garmin_ilink_s *next; } garmin_ilink_t; typedef struct { - unsigned int icon:1; - unsigned int wpt_class:1; - unsigned int display:1; - unsigned int category:1; - unsigned int city:1; - unsigned int state:1; - unsigned int facility:1; - unsigned int cc:1; - unsigned int cross_road:1; - unsigned int addr:1; - unsigned int country:1; - unsigned int phone_nr:1; - unsigned int phone_nr2:1; - unsigned int fax_nr:1; - unsigned int postal_code:1; - unsigned int email:1; + unsigned int icon:1; + unsigned int wpt_class:1; + unsigned int display:1; + unsigned int category:1; + unsigned int city:1; + unsigned int state:1; + unsigned int facility:1; + unsigned int cc:1; + unsigned int cross_road:1; + unsigned int addr:1; + unsigned int country:1; + unsigned int phone_nr:1; + unsigned int phone_nr2:1; + unsigned int fax_nr:1; + unsigned int postal_code:1; + unsigned int email:1; #ifdef GMSD_EXPERIMENTAL - unsigned int subclass:1; + unsigned int subclass:1; #endif } garmin_fs_flags_t; -typedef struct garmin_fs_s -{ - format_specific_data fs; - garmin_fs_flags_t flags; - - int protocol; /* ... used by device (-1 is MapSource) */ - - gbint32 icon; - int wpt_class; - gbint32 display; - gbint16 category; - char *city; /* city name */ - char *facility; /* facility name */ - char *state; /* state */ - char *cc; /* country code */ - char *cross_road; /* Intersection road label */ - char *addr; /* address + number */ - char *country; /* country */ - char *phone_nr; /* phone number */ - char *phone_nr2; /* phone number (2) */ - char *fax_nr; /* fax number */ - char *postal_code; /* postal code */ - char *email; /* email address */ - garmin_ilink_t *ilinks; +typedef struct garmin_fs_s { + format_specific_data fs; + garmin_fs_flags_t flags; + + int protocol; /* ... used by device (-1 is MapSource) */ + + gbint32 icon; + int wpt_class; + gbint32 display; + gbint16 category; + char *city; /* city name */ + char *facility; /* facility name */ + char *state; /* state */ + char *cc; /* country code */ + char *cross_road; /* Intersection road label */ + char *addr; /* address + number */ + char *country; /* country */ + char *phone_nr; /* phone number */ + char *phone_nr2; /* phone number (2) */ + char *fax_nr; /* fax number */ + char *postal_code; /* postal code */ + char *email; /* email address */ + garmin_ilink_t *ilinks; #ifdef GMSD_EXPERIMENTAL - char subclass[22]; + char subclass[22]; #endif } garmin_fs_t, *garmin_fs_p; diff --git a/gpsbabel/garmin_gpi.c b/gpsbabel/garmin_gpi.c index 9c12c9c96..308be6e82 100644 --- a/gpsbabel/garmin_gpi.c +++ b/gpsbabel/garmin_gpi.c @@ -1,7 +1,7 @@ /* Support for Garmin Points of Interest (.gpi files) - + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + /* History: @@ -38,7 +38,7 @@ * 2008/03/22: add options "speed" and "proximity" (default values) and "sleep" ToDo: - + * Display mode ("Symbol & Name") ??? not in gpi ??? * support category from GMSD "Garmin Special Data" */ @@ -74,105 +74,129 @@ static double defspeed, defproximity; static int alerts; static arglist_t garmin_gpi_args[] = { - {"alerts", &opt_alerts, "Enable alerts on speed or proximity distance", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"bitmap", &opt_bitmap, "Use specified bitmap on output", - NULL, ARGTYPE_FILE, ARG_NOMINMAX}, - {"category", &opt_cat, "Default category on output", - "My points", ARGTYPE_STRING, ARG_NOMINMAX}, - {"hide", &opt_hide_bitmap, "Don't show gpi bitmap on device", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"descr", &opt_descr, "Write description to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"notes", &opt_notes, "Write notes to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"position", &opt_pos, "Write position to address field", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"proximity", &opt_proximity, "Default proximity", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"sleep", &opt_sleep, "After output job done sleep n second(s)", - NULL, ARGTYPE_INT, "1", NULL}, - {"speed", &opt_speed, "Default speed", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"unique", &opt_unique, "Create unique waypoint names (default = yes)", - "Y", ARGTYPE_BOOL, ARG_NOMINMAX}, - {"units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", - "m", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "alerts", &opt_alerts, "Enable alerts on speed or proximity distance", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "bitmap", &opt_bitmap, "Use specified bitmap on output", + NULL, ARGTYPE_FILE, ARG_NOMINMAX + }, + { + "category", &opt_cat, "Default category on output", + "My points", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "hide", &opt_hide_bitmap, "Don't show gpi bitmap on device", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "descr", &opt_descr, "Write description to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "notes", &opt_notes, "Write notes to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "position", &opt_pos, "Write position to address field", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "proximity", &opt_proximity, "Default proximity", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "sleep", &opt_sleep, "After output job done sleep n second(s)", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "speed", &opt_speed, "Default speed", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "unique", &opt_unique, "Create unique waypoint names (default = yes)", + "Y", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "units", &opt_units, "Units used for names with @speed ('s'tatute or 'm'etric)", + "m", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; typedef struct { - int D2; - char S3[9]; /* "GRMRECnn" */ - time_t crdate; /* creation date and time */ - char POI[4]; /* "POI" */ - char S8[3]; - char *group; - char *category; + int D2; + char S3[9]; /* "GRMRECnn" */ + time_t crdate; /* creation date and time */ + char POI[4]; /* "POI" */ + char S8[3]; + char *group; + char *category; } reader_data_t; typedef struct writer_data_s { - queue Q; - int ct; - int sz; - int alert; - bounds bds; - struct writer_data_s *top_left; - struct writer_data_s *top_right; - struct writer_data_s *buttom_left; - struct writer_data_s *buttom_right; + queue Q; + int ct; + int sz; + int alert; + bounds bds; + struct writer_data_s *top_left; + struct writer_data_s *top_right; + struct writer_data_s *buttom_left; + struct writer_data_s *buttom_right; } writer_data_t; typedef struct gpi_waypt_data_s { - int sz; - char *addr; - char *postal_code; + int sz; + char *addr; + char *postal_code; } gpi_waypt_data_t; - + typedef struct { - gbint32 size; - gbint16 res1; - gbint16 res2; - gbint32 image_offset; - gbint32 header_size; - gbint32 width; - gbint32 height; - gbint16 planes; - gbint16 bpp; - gbint32 compression_type; - gbint32 image_data_size; - gbint32 resolution_h; - gbint32 resolution_v; - gbint32 used_colors; - gbint32 important_colors; + gbint32 size; + gbint16 res1; + gbint16 res2; + gbint32 image_offset; + gbint32 header_size; + gbint32 width; + gbint32 height; + gbint16 planes; + gbint16 bpp; + gbint32 compression_type; + gbint32 image_data_size; + gbint32 resolution_h; + gbint32 resolution_v; + gbint32 used_colors; + gbint32 important_colors; } bmp_header_t; typedef struct { - gbint16 index; - gbint16 height; - gbint16 width; - gbint16 line_sz; - gbint16 bpp; - gbint16 fixed_0; - gbint32 image_size; - gbint32 fixed_2c; - gbint32 flag1; - gbint32 tr_color; - gbint32 flag2; - gbint32 size_2c; + gbint16 index; + gbint16 height; + gbint16 width; + gbint16 line_sz; + gbint16 bpp; + gbint16 fixed_0; + gbint32 image_size; + gbint32 fixed_2c; + gbint32 flag1; + gbint32 tr_color; + gbint32 flag2; + gbint32 size_2c; } gpi_bitmap_header_t; typedef struct { - int sz; - int alerts; - short mask; - char addr_is_dynamic; - char *addr; - char *city; - char *country; - char *phone_nr; - char *postal_code; - char *state; + int sz; + int alerts; + short mask; + char addr_is_dynamic; + char *addr; + char *city; + char *country; + char *phone_nr; + char *postal_code; + char *state; } gpi_waypt_t; static gbfile *fin, *fout; @@ -198,124 +222,132 @@ static time_t gpi_timestamp = 0; static garmin_fs_t * gpi_gmsd_init(waypoint *wpt) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (wpt == NULL) { - fatal(MYNAME ": Error in file structure.\n"); - } - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - return gmsd; + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (wpt == NULL) { + fatal(MYNAME ": Error in file structure.\n"); + } + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + return gmsd; } /* read a standard string with or without 'EN' (or whatever) header */ static char * gpi_read_string(const char *field) { - int l1; - char *res = NULL; - - l1 = gbfgetint16(fin); - if (l1 > 0) { - short l2; - char first; - - first = gbfgetc(fin); - if (first == 0) { - char en[2]; - - is_fatal((gbfgetc(fin) != 0), - MYNAME ": Error reading field '%s'!", field); - - gbfread(en, 1, sizeof(en), fin); - l2 = gbfgetint16(fin); - is_fatal((l2 + 4 != l1), - MYNAME ": Error out of sync (wrong size %d/%d) on field '%s'!", l1, l2, field); - - if ((en[0] < 'A') || (en[0] > 'Z') || (en[1] < 'A') || (en[1] > 'Z')) - fatal(MYNAME ": Invalid country code!\n"); - res = xmalloc(l2 + 1); - res[l2] = '\0'; - PP; - if (l2 > 0) - gbfread(res, 1, l2, fin); - } - else { - res = xmalloc(l1 + 1); - *res = first; - *(res + l1) = '\0'; - PP; - l1--; - if (l1 > 0) - gbfread(res + 1, 1, l1, fin); - - } - } + int l1; + char *res = NULL; + + l1 = gbfgetint16(fin); + if (l1 > 0) { + short l2; + char first; + + first = gbfgetc(fin); + if (first == 0) { + char en[2]; + + is_fatal((gbfgetc(fin) != 0), + MYNAME ": Error reading field '%s'!", field); + + gbfread(en, 1, sizeof(en), fin); + l2 = gbfgetint16(fin); + is_fatal((l2 + 4 != l1), + MYNAME ": Error out of sync (wrong size %d/%d) on field '%s'!", l1, l2, field); + + if ((en[0] < 'A') || (en[0] > 'Z') || (en[1] < 'A') || (en[1] > 'Z')) { + fatal(MYNAME ": Invalid country code!\n"); + } + res = xmalloc(l2 + 1); + res[l2] = '\0'; + PP; + if (l2 > 0) { + gbfread(res, 1, l2, fin); + } + } else { + res = xmalloc(l1 + 1); + *res = first; + *(res + l1) = '\0'; + PP; + l1--; + if (l1 > 0) { + gbfread(res + 1, 1, l1, fin); + } + + } + } #ifdef GPI_DBG - dbginfo("%s: %s\n", field, (res == NULL) ? "" : res); + dbginfo("%s: %s\n", field, (res == NULL) ? "" : res); #endif - return res; + return res; } static void read_header(void) { - int len, i; + int len, i; #ifdef GPI_DBG - struct tm tm; - char stime[32]; -#endif + struct tm tm; + char stime[32]; +#endif - i = gbfgetint32(fin); - if (i != 0) i = gbfgetint32(fin); - rdata->D2 = gbfgetint32(fin); + i = gbfgetint32(fin); + if (i != 0) { + i = gbfgetint32(fin); + } + rdata->D2 = gbfgetint32(fin); - gbfread(&rdata->S3, 1, sizeof(rdata->S3) - 1, fin); /* GRMRECnn */ - if (strncmp(rdata->S3, "GRMREC", 6) != 0) - fatal(MYNAME ": No GPI file!\n"); + gbfread(&rdata->S3, 1, sizeof(rdata->S3) - 1, fin); /* GRMRECnn */ + if (strncmp(rdata->S3, "GRMREC", 6) != 0) { + fatal(MYNAME ": No GPI file!\n"); + } - PP; - rdata->crdate = gbfgetint32(fin); + PP; + rdata->crdate = gbfgetint32(fin); #ifdef GPI_DBG - tm = *localtime(&rdata->crdate); - tm.tm_year += 20; /* !!! */ - tm.tm_mday -= 1; /* !!! */ - strftime(stime, sizeof(stime), "%Y/%m/%d %H:%M:%S", &tm); - dbginfo("crdate = %lu (%s)\n", rdata->crdate, stime); -#endif - - (void) gbfgetint16(fin); /* 0 */ - - len = gbfgetint16(fin); - gbfseek(fin, len, SEEK_CUR); /* "my.gpi" */ - - i = gbfgetint32(fin); /* 1 */ - (void) gbfgetint32(fin); /* 12 */ - /* There are two dwords next. On most typical files, they're - * "1" and "12". On files from garminoneline.de/extras/poi, the - * next two words are "15" and "5" and there's 17 additional bytes - * that I can't identify. So hardcode a seek here for now. - */ - if (i == 15) { - gbfseek(fin, 17, SEEK_CUR); - } - - gbfread(&rdata->POI, 1, sizeof(rdata->POI) - 1, fin); - if (strcmp(rdata->POI, "POI") != 0) - fatal(MYNAME ": Wrong or unsupported GPI file!\n"); - - for (i = 0; i < 3; i++) (void)gbfgetc(fin); - gbfread(&rdata->S8, 1, sizeof(rdata->S8) - 1, fin); - - codepage = gbfgetint16(fin); - (void) gbfgetint16(fin); /* typically 0, but 0x11 in + tm = *localtime(&rdata->crdate); + tm.tm_year += 20; /* !!! */ + tm.tm_mday -= 1; /* !!! */ + strftime(stime, sizeof(stime), "%Y/%m/%d %H:%M:%S", &tm); + dbginfo("crdate = %lu (%s)\n", rdata->crdate, stime); +#endif + + (void) gbfgetint16(fin); /* 0 */ + + len = gbfgetint16(fin); + gbfseek(fin, len, SEEK_CUR); /* "my.gpi" */ + + i = gbfgetint32(fin); /* 1 */ + (void) gbfgetint32(fin); /* 12 */ + /* There are two dwords next. On most typical files, they're + * "1" and "12". On files from garminoneline.de/extras/poi, the + * next two words are "15" and "5" and there's 17 additional bytes + * that I can't identify. So hardcode a seek here for now. + */ + if (i == 15) { + gbfseek(fin, 17, SEEK_CUR); + } + + gbfread(&rdata->POI, 1, sizeof(rdata->POI) - 1, fin); + if (strcmp(rdata->POI, "POI") != 0) { + fatal(MYNAME ": Wrong or unsupported GPI file!\n"); + } + + for (i = 0; i < 3; i++) { + (void)gbfgetc(fin); + } + gbfread(&rdata->S8, 1, sizeof(rdata->S8) - 1, fin); + + codepage = gbfgetint16(fin); + (void) gbfgetint16(fin); /* typically 0, but 0x11 in Garminonline.de files. */ #ifdef GPI_DBG - PP; - dbginfo("< leaving header\n"); -#endif + PP; + dbginfo("< leaving header\n"); +#endif } /* gpi tag handler */ @@ -326,83 +358,91 @@ static int read_tag(const char *caller, const int tag, waypoint *wpt); static void read_poi(const int sz, const int tag) { - int pos, len; - waypoint *wpt; - + int pos, len; + waypoint *wpt; + #ifdef GPI_DBG - PP; - dbginfo("> reading poi (size %d)\n", sz); -#endif - PP; - len = 0; - if (tag == 0x80002) { - len = gbfgetint32(fin); /* sub-header size */ - } + PP; + dbginfo("> reading poi (size %d)\n", sz); +#endif + PP; + len = 0; + if (tag == 0x80002) { + len = gbfgetint32(fin); /* sub-header size */ + } #ifdef GPI_DBG - dbginfo("poi sublen = %1$d (0x%1$x)\n", len); -#endif - pos = gbftell(fin); - - wpt = waypt_new(); - wpt->icon_descr = DEFAULT_ICON; - - wpt->latitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); - wpt->longitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); - - (void) gbfgetint16(fin); /* ? always 1 ? */ - (void) gbfgetc(fin); /* seems to 1 when extra options present */ - wpt->shortname = gpi_read_string("Shortname"); - - while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { - int tag = gbfgetint32(fin); - if (! read_tag("read_poi", tag, wpt)) break; - } - - if (wpt->notes && !wpt->description) wpt->description = xstrdup(wpt->notes); - if (wpt->description && !wpt->notes) wpt->notes = xstrdup(wpt->description); - - waypt_add(wpt); + dbginfo("poi sublen = %1$d (0x%1$x)\n", len); +#endif + pos = gbftell(fin); + + wpt = waypt_new(); + wpt->icon_descr = DEFAULT_ICON; + + wpt->latitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + wpt->longitude = GPS_Math_Semi_To_Deg(gbfgetint32(fin)); + + (void) gbfgetint16(fin); /* ? always 1 ? */ + (void) gbfgetc(fin); /* seems to 1 when extra options present */ + wpt->shortname = gpi_read_string("Shortname"); + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi", tag, wpt)) { + break; + } + } + + if (wpt->notes && !wpt->description) { + wpt->description = xstrdup(wpt->notes); + } + if (wpt->description && !wpt->notes) { + wpt->notes = xstrdup(wpt->description); + } + + waypt_add(wpt); #ifdef GPI_DBG - PP; - dbginfo("< leaving poi\n"); -#endif + PP; + dbginfo("< leaving poi\n"); +#endif } /* read poi's following a group header */ static void read_poi_list(const int sz) { - int pos, i; - - pos = gbftell(fin); + int pos, i; + + pos = gbftell(fin); #ifdef GPI_DBG - PP; - dbginfo("> reading poi list (-> %1$x / %1$d )\n", pos + sz); + PP; + dbginfo("> reading poi list (-> %1$x / %1$d )\n", pos + sz); #endif - PP; - i = gbfgetint32(fin); /* mostly 23 (0x17) */ + PP; + i = gbfgetint32(fin); /* mostly 23 (0x17) */ #ifdef GPI_DBG - dbginfo("list sublen = %1$d (0x%1$x)\n", i); -#endif - (void) gbfgetint32(fin); /* max-lat */ - (void) gbfgetint32(fin); /* max-lon */ - (void) gbfgetint32(fin); /* min-lat */ - (void) gbfgetint32(fin); /* min-lon */ - - (void) gbfgetc(fin); /* three unknown bytes */ - (void) gbfgetc(fin); /* ? should be zero ? */ - (void) gbfgetc(fin); - - (void) gbfgetint32(fin); /* ? const 0x1000100 ? */ - - while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { - int tag = gbfgetint32(fin); - if (! read_tag("read_poi_list", tag, NULL)) return; - } + dbginfo("list sublen = %1$d (0x%1$x)\n", i); +#endif + (void) gbfgetint32(fin); /* max-lat */ + (void) gbfgetint32(fin); /* max-lon */ + (void) gbfgetint32(fin); /* min-lat */ + (void) gbfgetint32(fin); /* min-lon */ + + (void) gbfgetc(fin); /* three unknown bytes */ + (void) gbfgetc(fin); /* ? should be zero ? */ + (void) gbfgetc(fin); + + (void) gbfgetint32(fin); /* ? const 0x1000100 ? */ + + while (gbftell(fin) < (gbsize_t)(pos + sz - 4)) { + int tag = gbfgetint32(fin); + if (! read_tag("read_poi_list", tag, NULL)) { + return; + } + } #ifdef GPI_DBG - PP; - dbginfo("< leaving poi list\n"); + PP; + dbginfo("< leaving poi list\n"); #endif } @@ -410,230 +450,250 @@ read_poi_list(const int sz) static void read_poi_group(const int sz, const int tag) { - int pos; + int pos; - pos = gbftell(fin); + pos = gbftell(fin); #ifdef GPI_DBG - PP; - dbginfo("> reading poi group (-> %1$x / %1$d)\n", pos + sz); + PP; + dbginfo("> reading poi group (-> %1$x / %1$d)\n", pos + sz); #endif - if (tag == 0x80009) { - int subsz; - - PP; - subsz = gbfgetint32(fin); /* ? offset to category data ? */ + if (tag == 0x80009) { + int subsz; + + PP; + subsz = gbfgetint32(fin); /* ? offset to category data ? */ #ifdef GPI_DBG - dbginfo("group sublen = %d (-> %x / %d)\n", subsz, pos + subsz + 4, pos + subsz + 4); + dbginfo("group sublen = %d (-> %x / %d)\n", subsz, pos + subsz + 4, pos + subsz + 4); #endif - } - if (rdata->group) xfree(rdata->group); /* currently unused */ - rdata->group = gpi_read_string("Group"); - - while (gbftell(fin) < (gbsize_t)(pos + sz)) { - int subtag = gbfgetint32(fin); - if (! read_tag("read_poi_group", subtag, NULL)) break; - } - + } + if (rdata->group) { + xfree(rdata->group); /* currently unused */ + } + rdata->group = gpi_read_string("Group"); + + while (gbftell(fin) < (gbsize_t)(pos + sz)) { + int subtag = gbfgetint32(fin); + if (! read_tag("read_poi_group", subtag, NULL)) { + break; + } + } + #ifdef GPI_DBG - PP; - dbginfo("< leaving poi group\n"); + PP; + dbginfo("< leaving poi group\n"); #endif } // TODO: 'tag' is probably not a 32 bit value. // most likely it's a pair of 16's: the first pair is the tag number. // if the second 16 is "eight", then it's an -// extended thingy and it has a 4-byte extended record length (total number -// of bytes for all record fields and all nested records, starting after the +// extended thingy and it has a 4-byte extended record length (total number +// of bytes for all record fields and all nested records, starting after the // length field) /* gpi tag handler */ static int read_tag(const char *caller, const int tag, waypoint *wpt) { - int pos, sz, dist; - double speed; - short mask; - char *str; - garmin_fs_t *gmsd; - - sz = gbfgetint32(fin); - pos = gbftell(fin); - + int pos, sz, dist; + double speed; + short mask; + char *str; + garmin_fs_t *gmsd; + + sz = gbfgetint32(fin); + pos = gbftell(fin); + #ifdef GPI_DBG - PP; - dbginfo("%s: tag = 0x%x (size %d)\n", caller, tag, sz); + PP; + dbginfo("%s: tag = 0x%x (size %d)\n", caller, tag, sz); #endif - if ((tag >= 0x80000) && (tag <= 0x800ff)) sz += 4; - - switch(tag) { - case 0x3: /* size = 12 */ - case 0x80003: /* size = 12 */ - - dist = gbfgetint16(fin); /* proximity distance in meters */ - speed = (double)gbfgetint16(fin) / 100; /* speed in meters per second */ - - if (dist > 0) WAYPT_SET(wpt, proximity, dist); - if (speed > 0) { - /* speed isn't part of a normal waypoint - WAYPT_SET(wpt, speed, speed); - */ - if ((wpt->shortname == NULL) || (! strchr(wpt->shortname, '@'))) { - if (units == 's') speed = MPS_TO_MPH(speed); - else speed = MPS_TO_KPH(speed); - xasprintf(&str, "%s@%.f", wpt->shortname ? wpt->shortname : "WPT", speed); - if (wpt->shortname) xfree(wpt->shortname); - wpt->shortname = str; - } - } - - (void) gbfgetint32(fin); - (void) gbfgetint32(fin); - break; - - case 0x4: /* size = 2 ? */ - case 0x6: /* size = 2 ? */ - break; - - case 0x5: /* group bitmap */ - break; - - case 0x7: - (void) gbfgetint16(fin); /* category number */ - if (rdata->category) xfree(rdata->category); - rdata->category = gpi_read_string("Category"); - break; - - case 0xa: - wpt->description = gpi_read_string("Description"); - break; - - case 0xe: /* ? notes or description / or both ? */ - mask = gbfgetc(fin); - if (mask == 0x01) { - str = gpi_read_string("Notes"); - } - else if (mask == 0x32) { - str = gpi_read_string("Notes"); - } - else break; - - if (wpt->description) wpt->notes = str; - else wpt->description = str; - break; - - case 0x2: - case 0x80002: - read_poi(sz, tag); - break; - - case 0x80008: - read_poi_list(sz); - break; - - case 0x9: /* ? older versions / no category data ? */ - case 0x80009: /* current POI loader */ - read_poi_group(sz, tag); - break; - - case 0x8000b: /* address (street/city...) */ - (void) gbfgetint32(fin); - case 0xb: /* as seen in German POI files. */ - PP; - mask = gbfgetint16(fin); /* address fields mask */ + if ((tag >= 0x80000) && (tag <= 0x800ff)) { + sz += 4; + } + + switch (tag) { + case 0x3: /* size = 12 */ + case 0x80003: /* size = 12 */ + + dist = gbfgetint16(fin); /* proximity distance in meters */ + speed = (double)gbfgetint16(fin) / 100; /* speed in meters per second */ + + if (dist > 0) { + WAYPT_SET(wpt, proximity, dist); + } + if (speed > 0) { + /* speed isn't part of a normal waypoint + WAYPT_SET(wpt, speed, speed); + */ + if ((wpt->shortname == NULL) || (! strchr(wpt->shortname, '@'))) { + if (units == 's') { + speed = MPS_TO_MPH(speed); + } else { + speed = MPS_TO_KPH(speed); + } + xasprintf(&str, "%s@%.f", wpt->shortname ? wpt->shortname : "WPT", speed); + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = str; + } + } + + (void) gbfgetint32(fin); + (void) gbfgetint32(fin); + break; + + case 0x4: /* size = 2 ? */ + case 0x6: /* size = 2 ? */ + break; + + case 0x5: /* group bitmap */ + break; + + case 0x7: + (void) gbfgetint16(fin); /* category number */ + if (rdata->category) { + xfree(rdata->category); + } + rdata->category = gpi_read_string("Category"); + break; + + case 0xa: + wpt->description = gpi_read_string("Description"); + break; + + case 0xe: /* ? notes or description / or both ? */ + mask = gbfgetc(fin); + if (mask == 0x01) { + str = gpi_read_string("Notes"); + } else if (mask == 0x32) { + str = gpi_read_string("Notes"); + } else { + break; + } + + if (wpt->description) { + wpt->notes = str; + } else { + wpt->description = str; + } + break; + + case 0x2: + case 0x80002: + read_poi(sz, tag); + break; + + case 0x80008: + read_poi_list(sz); + break; + + case 0x9: /* ? older versions / no category data ? */ + case 0x80009: /* current POI loader */ + read_poi_group(sz, tag); + break; + + case 0x8000b: /* address (street/city...) */ + (void) gbfgetint32(fin); + case 0xb: /* as seen in German POI files. */ + PP; + mask = gbfgetint16(fin); /* address fields mask */ #ifdef GPI_DBG - dbginfo("GPI Address field mask: %d (0x%02x)\n", mask, mask); + dbginfo("GPI Address field mask: %d (0x%02x)\n", mask, mask); #endif - if ((mask & GPI_ADDR_CITY) && (str = gpi_read_string("City"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(city, str); - } - if ((mask & GPI_ADDR_COUNTRY) && (str = gpi_read_string("Country"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(country, str); - } - if ((mask & GPI_ADDR_STATE) && (str = gpi_read_string("State"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(state, str); - } - if ((mask & GPI_ADDR_POSTAL_CODE) && (str = gpi_read_string("Postal code"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(postal_code, str); - } - if ((mask & GPI_ADDR_ADDR) && (str = gpi_read_string("Street address"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(addr, str); - } - break; - - case 0xc: - mask = gbfgetint16(fin); - if ((mask & 1) && (str = gpi_read_string("Phone"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr, str); - } - if ((mask & 2) && (str = gpi_read_string("Phone2"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr2, str); - } - if ((mask & 4) && (str = gpi_read_string("Fax"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(fax_nr, str); - } - if ((mask & 8) && (str = gpi_read_string("Email"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(email, str); - } - if ((mask & 0x10) && (str = gpi_read_string("Link"))) { - waypt_add_url(wpt, xstrdup(str), xstrdup(str)); - } - break; - - case 0x8000c: /* phone-number */ - (void) gbfgetint32(fin); - PP; - - mask = gbfgetint16(fin); /* phone fields mask */ + if ((mask & GPI_ADDR_CITY) && (str = gpi_read_string("City"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(city, str); + } + if ((mask & GPI_ADDR_COUNTRY) && (str = gpi_read_string("Country"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(country, str); + } + if ((mask & GPI_ADDR_STATE) && (str = gpi_read_string("State"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(state, str); + } + if ((mask & GPI_ADDR_POSTAL_CODE) && (str = gpi_read_string("Postal code"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(postal_code, str); + } + if ((mask & GPI_ADDR_ADDR) && (str = gpi_read_string("Street address"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(addr, str); + } + break; + + case 0xc: + mask = gbfgetint16(fin); + if ((mask & 1) && (str = gpi_read_string("Phone"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr, str); + } + if ((mask & 2) && (str = gpi_read_string("Phone2"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr2, str); + } + if ((mask & 4) && (str = gpi_read_string("Fax"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(fax_nr, str); + } + if ((mask & 8) && (str = gpi_read_string("Email"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(email, str); + } + if ((mask & 0x10) && (str = gpi_read_string("Link"))) { + waypt_add_url(wpt, xstrdup(str), xstrdup(str)); + } + break; + + case 0x8000c: /* phone-number */ + (void) gbfgetint32(fin); + PP; + + mask = gbfgetint16(fin); /* phone fields mask */ #ifdef GPI_DBG - dbginfo("GPI Phone field mask: %d (0x%02x)\n", mask, mask); + dbginfo("GPI Phone field mask: %d (0x%02x)\n", mask, mask); #endif - if ((mask & 1) && (str = gpi_read_string("Phone"))) { - gmsd = gpi_gmsd_init(wpt); - GMSD_SET(phone_nr, str); - } - break; - - case 0x80012: /* ? sounds / images ? */ - break; - - /* Images? Seen in http://geepeeex.com/Stonepages.gpi */ - case 0xd: - break; - - case 0x11: - case 0x80007: - /* Looks like some kind of calendar information. */ + if ((mask & 1) && (str = gpi_read_string("Phone"))) { + gmsd = gpi_gmsd_init(wpt); + GMSD_SET(phone_nr, str); + } + break; + + case 0x80012: /* ? sounds / images ? */ + break; + + /* Images? Seen in http://geepeeex.com/Stonepages.gpi */ + case 0xd: + break; + + case 0x11: + case 0x80007: + /* Looks like some kind of calendar information. */ #ifdef GPI_DBG - { - int x; - unsigned char *b = xmalloc(sz); - fprintf(stderr, "Tag: %x\n", tag); - gbfread(b, 1, sz, fin); - fprintf(stderr, "\n"); - for (x = 0; x < sz; x++) - fprintf(stderr, "%02x ", b[x]); - fprintf(stderr, "\n"); - for (x = 0; x < sz; x++) - fprintf(stderr, "%c", isalnum(b[x]) ? b[x] : '.'); - fprintf(stderr, "\n"); - } + { + int x; + unsigned char *b = xmalloc(sz); + fprintf(stderr, "Tag: %x\n", tag); + gbfread(b, 1, sz, fin); + fprintf(stderr, "\n"); + for (x = 0; x < sz; x++) { + fprintf(stderr, "%02x ", b[x]); + } + fprintf(stderr, "\n"); + for (x = 0; x < sz; x++) { + fprintf(stderr, "%c", isalnum(b[x]) ? b[x] : '.'); + } + fprintf(stderr, "\n"); + } #endif // GPI_DBG - break; - default: - warning(MYNAME ": Unknown tag (0x%x). Please report!\n", tag); - return 0; - } - gbfseek(fin, pos + sz, SEEK_SET); - return 1; + break; + default: + warning(MYNAME ": Unknown tag (0x%x). Please report!\n", tag); + return 0; + } + gbfseek(fin, pos + sz, SEEK_SET); + return 1; } /******************************************************************************* @@ -643,603 +703,702 @@ read_tag(const char *caller, const int tag, waypoint *wpt) static void write_string(const char *str, const char long_format) { - int len; - - len = strlen(str); - if (long_format) { - gbfputint32(len + 4, fout); - gbfwrite("EN", 1, 2, fout); - } - gbfputint16(len, fout); - gbfwrite(str, 1, len, fout); + int len; + + len = strlen(str); + if (long_format) { + gbfputint32(len + 4, fout); + gbfwrite("EN", 1, 2, fout); + } + gbfputint16(len, fout); + gbfwrite(str, 1, len, fout); } static int compare_wpt_cb(const queue *a, const queue *b) { - const waypoint *wa = (waypoint *) a; - const waypoint *wb = (waypoint *) b; - - return strcmp(wa->shortname, wb->shortname); + const waypoint *wa = (waypoint *) a; + const waypoint *wb = (waypoint *) b; + + return strcmp(wa->shortname, wb->shortname); } static char compare_strings(const char *s1, const char *s2) { - if (s1 == s2) return 0; - else if (s1) { - if (s2) return strcmp(s1, s2); - else return 1; - } - else return 1; + if (s1 == s2) { + return 0; + } else if (s1) { + if (s2) { + return strcmp(s1, s2); + } else { + return 1; + } + } else { + return 1; + } } static writer_data_t * wdata_alloc() { - writer_data_t *res; + writer_data_t *res; - res = xcalloc(1, sizeof(*res)); - QUEUE_INIT(&res->Q); - waypt_init_bounds(&res->bds); + res = xcalloc(1, sizeof(*res)); + QUEUE_INIT(&res->Q); + waypt_init_bounds(&res->bds); - return res; + return res; } static void wdata_free(writer_data_t *data) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - - if (wpt->extra_data) { - gpi_waypt_t *dt = (gpi_waypt_t *) wpt->extra_data; - if (dt->addr_is_dynamic) xfree(dt->addr); - xfree(dt); - } - waypt_free(wpt); - } - - if (data->top_left) wdata_free(data->top_left); - if (data->top_right) wdata_free(data->top_right); - if (data->buttom_left) wdata_free(data->buttom_left); - if (data->buttom_right) wdata_free(data->buttom_right); - - xfree(data); + queue *elem, *tmp; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + + if (wpt->extra_data) { + gpi_waypt_t *dt = (gpi_waypt_t *) wpt->extra_data; + if (dt->addr_is_dynamic) { + xfree(dt->addr); + } + xfree(dt); + } + waypt_free(wpt); + } + + if (data->top_left) { + wdata_free(data->top_left); + } + if (data->top_right) { + wdata_free(data->top_right); + } + if (data->buttom_left) { + wdata_free(data->buttom_left); + } + if (data->buttom_right) { + wdata_free(data->buttom_right); + } + + xfree(data); } static void wdata_add_wpt(writer_data_t *data, waypoint *wpt) { - data->ct++; - ENQUEUE_TAIL(&data->Q, &wpt->Q); - waypt_add_to_bounds(&data->bds, wpt); + data->ct++; + ENQUEUE_TAIL(&data->Q, &wpt->Q); + waypt_add_to_bounds(&data->bds, wpt); } static void wdata_check(writer_data_t *data) { - queue *elem, *tmp; - double center_lat, center_lon; - - if ((data->ct <= WAYPOINTS_PER_BLOCK) || - /* avoid endless loop for points (more than WAYPOINTS_PER_BLOCK) - at same coordinates */ - ((data->bds.min_lat >= data->bds.max_lat) && (data->bds.min_lon >= data->bds.max_lon))) { - if (data->ct > 1) - sortqueue(&data->Q, compare_wpt_cb); - return; - } - - /* compute the (mean) center of current bounds */ - - center_lat = center_lon = 0; - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - center_lat += wpt->latitude; - center_lon += wpt->longitude; - } - center_lat /= data->ct; - center_lon /= data->ct; - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - writer_data_t **ref; - - if (wpt->latitude < center_lat) { - if (wpt->longitude < center_lon) - ref = &data->buttom_left; - else - ref = &data->buttom_right; - } else { - if (wpt->longitude < center_lon) - ref = &data->top_left; - else - ref = &data->top_right; - } - - if (*ref == NULL) *ref = wdata_alloc(); - - data->ct--; - dequeue(&wpt->Q); - - wdata_add_wpt(*ref, wpt); - } - - if (data->top_left) wdata_check(data->top_left); - if (data->top_right) wdata_check(data->top_right); - if (data->buttom_left) wdata_check(data->buttom_left); - if (data->buttom_right) wdata_check(data->buttom_right); + queue *elem, *tmp; + double center_lat, center_lon; + + if ((data->ct <= WAYPOINTS_PER_BLOCK) || + /* avoid endless loop for points (more than WAYPOINTS_PER_BLOCK) + at same coordinates */ + ((data->bds.min_lat >= data->bds.max_lat) && (data->bds.min_lon >= data->bds.max_lon))) { + if (data->ct > 1) { + sortqueue(&data->Q, compare_wpt_cb); + } + return; + } + + /* compute the (mean) center of current bounds */ + + center_lat = center_lon = 0; + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + center_lat += wpt->latitude; + center_lon += wpt->longitude; + } + center_lat /= data->ct; + center_lon /= data->ct; + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + writer_data_t **ref; + + if (wpt->latitude < center_lat) { + if (wpt->longitude < center_lon) { + ref = &data->buttom_left; + } else { + ref = &data->buttom_right; + } + } else { + if (wpt->longitude < center_lon) { + ref = &data->top_left; + } else { + ref = &data->top_right; + } + } + + if (*ref == NULL) { + *ref = wdata_alloc(); + } + + data->ct--; + dequeue(&wpt->Q); + + wdata_add_wpt(*ref, wpt); + } + + if (data->top_left) { + wdata_check(data->top_left); + } + if (data->top_right) { + wdata_check(data->top_right); + } + if (data->buttom_left) { + wdata_check(data->buttom_left); + } + if (data->buttom_right) { + wdata_check(data->buttom_right); + } } static int wdata_compute_size(writer_data_t *data) { - queue *elem, *tmp; - int res; - - res = 23; /* bounds, ... of tag 0x80008 */ - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - waypoint *wpt = (waypoint *) elem; - gpi_waypt_t *dt; - garmin_fs_t *gmsd; - char *str; - - res += 12; /* tag/sz/sub-sz */ - res += 19; /* poi fixed size */ - res += strlen(wpt->shortname); - if (! opt_hide_bitmap) res += 10; /* tag(4) */ - - dt = xcalloc(1, sizeof(*dt)); - wpt->extra_data = dt; - - if (alerts) { - char *pos; - - if ((pos = strchr(wpt->shortname, '@'))) { - double speed, scale; - if (units == 's') scale = MPH_TO_MPS(1); - else scale = KPH_TO_MPS(1); - parse_speed(pos + 1, &speed, scale, MYNAME); - if (speed > 0) WAYPT_SET(wpt, speed, speed); -#if 0 - if (pos > wpt->shortname) wpt->shortname[pos - wpt->shortname] = '\0'; + queue *elem, *tmp; + int res; + + res = 23; /* bounds, ... of tag 0x80008 */ + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + gpi_waypt_t *dt; + garmin_fs_t *gmsd; + char *str; + + res += 12; /* tag/sz/sub-sz */ + res += 19; /* poi fixed size */ + res += strlen(wpt->shortname); + if (! opt_hide_bitmap) { + res += 10; /* tag(4) */ + } + + dt = xcalloc(1, sizeof(*dt)); + wpt->extra_data = dt; + + if (alerts) { + char *pos; + + if ((pos = strchr(wpt->shortname, '@'))) { + double speed, scale; + if (units == 's') { + scale = MPH_TO_MPS(1); + } else { + scale = KPH_TO_MPS(1); + } + parse_speed(pos + 1, &speed, scale, MYNAME); + if (speed > 0) { + WAYPT_SET(wpt, speed, speed); + } +#if 0 + if (pos > wpt->shortname) { + wpt->shortname[pos - wpt->shortname] = '\0'; + } #endif - } - else if ((opt_speed) && (! WAYPT_HAS(wpt, speed))) - WAYPT_SET(wpt, speed, defspeed); - - if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity))) - WAYPT_SET(wpt, proximity, defproximity); - - if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || - (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) { - data->alert = 1; - dt->alerts++; - res += 20; /* tag(3) */ - } - } - - str = NULL; - if (opt_descr) { - if (wpt->description && *wpt->description) - str = xstrdup(wpt->description); - } - else if (opt_notes) { - if (wpt->notes && *wpt->notes) - str = xstrdup(wpt->notes); - } - else if (opt_pos) - str = pretty_deg_format(wpt->latitude, wpt->longitude, 's', " ", 0); - - - if (str) { - dt->addr_is_dynamic = 1; - dt->addr = str; - dt->mask |= GPI_ADDR_ADDR; - dt->sz += (8 + strlen(dt->addr)); - } - - if ((gmsd = GMSD_FIND(wpt))) { - if ((dt->mask == 0) && ((dt->addr = GMSD_GET(addr, NULL)))) { - dt->mask |= GPI_ADDR_ADDR; - dt->sz += (8 + strlen(dt->addr)); - } - if ((dt->city = GMSD_GET(city, NULL))) { - dt->mask |= GPI_ADDR_CITY; - dt->sz += (8 + strlen(dt->city)); - } - if ((dt->country = GMSD_GET(country, NULL))) { - dt->mask |= GPI_ADDR_COUNTRY; - dt->sz += (8 + strlen(dt->country)); - } - if ((dt->state = GMSD_GET(state, NULL))) { - dt->mask |= GPI_ADDR_STATE; - dt->sz += (8 + strlen(dt->state)); - } - if ((dt->postal_code = GMSD_GET(postal_code, NULL))) { - dt->mask |= GPI_ADDR_POSTAL_CODE; - dt->sz += (2 + strlen(dt->postal_code)); /* short form */ - } - - if ((dt->phone_nr = GMSD_GET(phone_nr, NULL))) - res += (12 + 4 + strlen(dt->phone_nr)); - } - if (dt->mask) dt->sz += 2; /* + mask (two bytes) */ - if (dt->sz) res += (dt->sz + 12); /* + header size */ - - str = wpt->description; - if (! str) str = wpt->notes; + } else if ((opt_speed) && (! WAYPT_HAS(wpt, speed))) { + WAYPT_SET(wpt, speed, defspeed); + } + + if ((opt_proximity) && (! WAYPT_HAS(wpt, proximity))) { + WAYPT_SET(wpt, proximity, defproximity); + } + + if ((WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) || + (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0))) { + data->alert = 1; + dt->alerts++; + res += 20; /* tag(3) */ + } + } + + str = NULL; + if (opt_descr) { + if (wpt->description && *wpt->description) { + str = xstrdup(wpt->description); + } + } else if (opt_notes) { + if (wpt->notes && *wpt->notes) { + str = xstrdup(wpt->notes); + } + } else if (opt_pos) { + str = pretty_deg_format(wpt->latitude, wpt->longitude, 's', " ", 0); + } + + + if (str) { + dt->addr_is_dynamic = 1; + dt->addr = str; + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + + if ((gmsd = GMSD_FIND(wpt))) { + if ((dt->mask == 0) && ((dt->addr = GMSD_GET(addr, NULL)))) { + dt->mask |= GPI_ADDR_ADDR; + dt->sz += (8 + strlen(dt->addr)); + } + if ((dt->city = GMSD_GET(city, NULL))) { + dt->mask |= GPI_ADDR_CITY; + dt->sz += (8 + strlen(dt->city)); + } + if ((dt->country = GMSD_GET(country, NULL))) { + dt->mask |= GPI_ADDR_COUNTRY; + dt->sz += (8 + strlen(dt->country)); + } + if ((dt->state = GMSD_GET(state, NULL))) { + dt->mask |= GPI_ADDR_STATE; + dt->sz += (8 + strlen(dt->state)); + } + if ((dt->postal_code = GMSD_GET(postal_code, NULL))) { + dt->mask |= GPI_ADDR_POSTAL_CODE; + dt->sz += (2 + strlen(dt->postal_code)); /* short form */ + } + + if ((dt->phone_nr = GMSD_GET(phone_nr, NULL))) { + res += (12 + 4 + strlen(dt->phone_nr)); + } + } + if (dt->mask) { + dt->sz += 2; /* + mask (two bytes) */ + } + if (dt->sz) { + res += (dt->sz + 12); /* + header size */ + } + + str = wpt->description; + if (! str) { + str = wpt->notes; + } // if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - if (str) res += (12 + 4 + strlen(str)); - } - - if (data->top_left) res += wdata_compute_size(data->top_left); - if (data->top_right) res += wdata_compute_size(data->top_right); - if (data->buttom_left) res += wdata_compute_size(data->buttom_left); - if (data->buttom_right) res += wdata_compute_size(data->buttom_right); - - data->sz = res; - - return res + 12; /* + 12 = caller needs info about tag header size */ + if (str) { + res += (12 + 4 + strlen(str)); + } + } + + if (data->top_left) { + res += wdata_compute_size(data->top_left); + } + if (data->top_right) { + res += wdata_compute_size(data->top_right); + } + if (data->buttom_left) { + res += wdata_compute_size(data->buttom_left); + } + if (data->buttom_right) { + res += wdata_compute_size(data->buttom_right); + } + + data->sz = res; + + return res + 12; /* + 12 = caller needs info about tag header size */ } static void wdata_write(const writer_data_t *data) { - queue *elem, *tmp; - - gbfputint32(0x80008, fout); - gbfputint32(data->sz, fout); - gbfputint32(23, fout); /* bounds + three bytes */ - - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lat), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lon), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lat), fout); - gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lon), fout); - - gbfputint32(0, fout); - gbfputint16(1, fout); - gbfputc(data->alert, fout); - - QUEUE_FOR_EACH(&data->Q, elem, tmp) { - char *str; - int s0, s1; - waypoint *wpt = (waypoint *)elem; - gpi_waypt_t *dt = wpt->extra_data; - - str = wpt->description; - if (! str) str = wpt->notes; + queue *elem, *tmp; + + gbfputint32(0x80008, fout); + gbfputint32(data->sz, fout); + gbfputint32(23, fout); /* bounds + three bytes */ + + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.max_lon), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lat), fout); + gbfputint32(GPS_Math_Deg_To_Semi(data->bds.min_lon), fout); + + gbfputint32(0, fout); + gbfputint16(1, fout); + gbfputc(data->alert, fout); + + QUEUE_FOR_EACH(&data->Q, elem, tmp) { + char *str; + int s0, s1; + waypoint *wpt = (waypoint *)elem; + gpi_waypt_t *dt = wpt->extra_data; + + str = wpt->description; + if (! str) { + str = wpt->notes; + } // if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - gbfputint32(0x80002, fout); - - s0 = s1 = 19 + strlen(wpt->shortname); - if (! opt_hide_bitmap) s0 += 10; /* tag(4) */ - if (str) s0 += (12 + 4 + strlen(str)); /* descr */ - if (dt->sz) s0 += (12 + dt->sz); /* address part */ - if (dt->phone_nr) s0 += (12 + 4 + strlen(dt->phone_nr)); - if (dt->alerts) s0 += 20; /* tag(3) */ - - gbfputint32(s0, fout); /* size of following data (tag) */ - gbfputint32(s1, fout); /* basic size (without options) */ - - gbfputint32(GPS_Math_Deg_To_Semi(wpt->latitude), fout); - gbfputint32(GPS_Math_Deg_To_Semi(wpt->longitude), fout); - - gbfputint16(1, fout); /* ? always 1 ? */ - gbfputc(alerts, fout); /* seems to be 1 when extra options present */ - - write_string(wpt->shortname, 1); - - if (dt->alerts) { - char flag = 0; - - gbfputint32(3, fout); /* tag(3) */ - gbfputint32(12, fout); /* always 12 */ - - if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { - gbfputint16((int) wpt->proximity, fout); - flag = 4; - } - else - gbfputint16(0, fout); - if (WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) { - gbfputint16((int) (wpt->speed * 100), fout); - flag = 5; - } - else - gbfputint16(0, fout); - - gbfputint32(0x100100, fout); /* ??? */ - gbfputc(1, fout); /* ??? */ - gbfputc(1, fout); /* ??? */ - gbfputc(flag, fout); - gbfputc(0x10, fout); /* ??? */ - } - - if (! opt_hide_bitmap) { - gbfputint32(4, fout); /* tag(4) */ - gbfputint32(2, fout); /* ? always 2 == version ??? */ - gbfputint16(0, fout); - } - - if (str) { - gbfputint32(0xa, fout); - gbfputint32(strlen(str) + 8, fout); /* string + string header */ - write_string(str, 1); - } - - if (dt->sz) { /* gpi address */ - gbfputint32(0x8000b, fout); - gbfputint32(dt->sz, fout); - gbfputint32(0x2, fout); /* ? always 2 ? */ - gbfputint16(dt->mask, fout); - if (dt->mask & GPI_ADDR_CITY) write_string(dt->city, 1); - if (dt->mask & GPI_ADDR_COUNTRY) write_string(dt->country, 1); - if (dt->mask & GPI_ADDR_STATE) write_string(dt->state, 1); - if (dt->mask & GPI_ADDR_POSTAL_CODE) write_string(dt->postal_code, 0); - if (dt->mask & GPI_ADDR_ADDR) write_string(dt->addr, 1); - } - - if (dt->phone_nr) { - gbfputint32(0x8000c, fout); - gbfputint32(strlen(dt->phone_nr) + 2 + 2, fout); - gbfputint32(0x2, fout); /* ? always 2 ? */ - gbfputint16(1, fout); /* mask */ - write_string(dt->phone_nr, 0); - } - } - - if (data->top_left) wdata_write(data->top_left); - if (data->top_right) wdata_write(data->top_right); - if (data->buttom_left) wdata_write(data->buttom_left); - if (data->buttom_right) wdata_write(data->buttom_right); + gbfputint32(0x80002, fout); + + s0 = s1 = 19 + strlen(wpt->shortname); + if (! opt_hide_bitmap) { + s0 += 10; /* tag(4) */ + } + if (str) { + s0 += (12 + 4 + strlen(str)); /* descr */ + } + if (dt->sz) { + s0 += (12 + dt->sz); /* address part */ + } + if (dt->phone_nr) { + s0 += (12 + 4 + strlen(dt->phone_nr)); + } + if (dt->alerts) { + s0 += 20; /* tag(3) */ + } + + gbfputint32(s0, fout); /* size of following data (tag) */ + gbfputint32(s1, fout); /* basic size (without options) */ + + gbfputint32(GPS_Math_Deg_To_Semi(wpt->latitude), fout); + gbfputint32(GPS_Math_Deg_To_Semi(wpt->longitude), fout); + + gbfputint16(1, fout); /* ? always 1 ? */ + gbfputc(alerts, fout); /* seems to be 1 when extra options present */ + + write_string(wpt->shortname, 1); + + if (dt->alerts) { + char flag = 0; + + gbfputint32(3, fout); /* tag(3) */ + gbfputint32(12, fout); /* always 12 */ + + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { + gbfputint16((int) wpt->proximity, fout); + flag = 4; + } else { + gbfputint16(0, fout); + } + if (WAYPT_HAS(wpt, speed) && (wpt->speed > 0)) { + gbfputint16((int)(wpt->speed * 100), fout); + flag = 5; + } else { + gbfputint16(0, fout); + } + + gbfputint32(0x100100, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(1, fout); /* ??? */ + gbfputc(flag, fout); + gbfputc(0x10, fout); /* ??? */ + } + + if (! opt_hide_bitmap) { + gbfputint32(4, fout); /* tag(4) */ + gbfputint32(2, fout); /* ? always 2 == version ??? */ + gbfputint16(0, fout); + } + + if (str) { + gbfputint32(0xa, fout); + gbfputint32(strlen(str) + 8, fout); /* string + string header */ + write_string(str, 1); + } + + if (dt->sz) { /* gpi address */ + gbfputint32(0x8000b, fout); + gbfputint32(dt->sz, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(dt->mask, fout); + if (dt->mask & GPI_ADDR_CITY) { + write_string(dt->city, 1); + } + if (dt->mask & GPI_ADDR_COUNTRY) { + write_string(dt->country, 1); + } + if (dt->mask & GPI_ADDR_STATE) { + write_string(dt->state, 1); + } + if (dt->mask & GPI_ADDR_POSTAL_CODE) { + write_string(dt->postal_code, 0); + } + if (dt->mask & GPI_ADDR_ADDR) { + write_string(dt->addr, 1); + } + } + + if (dt->phone_nr) { + gbfputint32(0x8000c, fout); + gbfputint32(strlen(dt->phone_nr) + 2 + 2, fout); + gbfputint32(0x2, fout); /* ? always 2 ? */ + gbfputint16(1, fout); /* mask */ + write_string(dt->phone_nr, 0); + } + } + + if (data->top_left) { + wdata_write(data->top_left); + } + if (data->top_right) { + wdata_write(data->top_right); + } + if (data->buttom_left) { + wdata_write(data->buttom_left); + } + if (data->buttom_right) { + wdata_write(data->buttom_right); + } } static void write_category(const char *category, const char *image, const int image_sz) { - int sz; - - sz = wdata_compute_size(wdata); - sz += 8; /* string header */ - sz += strlen(opt_cat); - - gbfputint32(0x80009, fout); - if ((! opt_hide_bitmap) && image_sz) - gbfputint32(sz + image_sz + 8, fout); - else - gbfputint32(sz, fout); - gbfputint32(sz, fout); - write_string(opt_cat, 1); - - wdata_write(wdata); - - if ((! opt_hide_bitmap) && image_sz) { - gbfputint32(5, fout); - gbfputint32(image_sz, fout); - gbfwrite(image, 1, image_sz, fout); - } + int sz; + + sz = wdata_compute_size(wdata); + sz += 8; /* string header */ + sz += strlen(opt_cat); + + gbfputint32(0x80009, fout); + if ((! opt_hide_bitmap) && image_sz) { + gbfputint32(sz + image_sz + 8, fout); + } else { + gbfputint32(sz, fout); + } + gbfputint32(sz, fout); + write_string(opt_cat, 1); + + wdata_write(wdata); + + if ((! opt_hide_bitmap) && image_sz) { + gbfputint32(5, fout); + gbfputint32(image_sz, fout); + gbfwrite(image, 1, image_sz, fout); + } } static void write_header(void) { - time_t time = gpi_timestamp; - - if (time != 0) { - struct tm tm; - tm = *gmtime(&time); - tm.tm_year -= 20; - time = mkgmtime(&tm); - time += SECONDS_PER_DAY; - } - - gbfputint32(0, fout); - gbfputint32(0x16, fout); - gbfwrite("GRMREC00", 1, 8, fout); - gbfputint32(time, fout); - gbfputint16(0, fout); - gbfputint16(6, fout); - gbfwrite("my.gpi", 1, 6, fout); - gbfputint32(1, fout); - gbfputint32(0xc, fout); - gbfwrite("POI", 1, 3, fout); - gbfputc(0, fout); - gbfputc(0, fout); - gbfputc(0, fout); - gbfwrite("00", 1, 2, fout); - gbfputint16(codepage, fout); - gbfputint16(0, fout); + time_t time = gpi_timestamp; + + if (time != 0) { + struct tm tm; + tm = *gmtime(&time); + tm.tm_year -= 20; + time = mkgmtime(&tm); + time += SECONDS_PER_DAY; + } + + gbfputint32(0, fout); + gbfputint32(0x16, fout); + gbfwrite("GRMREC00", 1, 8, fout); + gbfputint32(time, fout); + gbfputint16(0, fout); + gbfputint16(6, fout); + gbfwrite("my.gpi", 1, 6, fout); + gbfputint32(1, fout); + gbfputint32(0xc, fout); + gbfwrite("POI", 1, 3, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfputc(0, fout); + gbfwrite("00", 1, 2, fout); + gbfputint16(codepage, fout); + gbfputint16(0, fout); } static void enum_waypt_cb(const waypoint *ref) { - waypoint *wpt; - char *str; - queue *elem, *tmp; - - QUEUE_FOR_EACH(&wdata->Q, elem, tmp) { - waypoint *cmp = (waypoint *) elem; - - /* sort out nearly equal waypoints */ - if ((compare_strings(cmp->shortname, ref->shortname) == 0) && - (cmp->latitude == ref->latitude) && - (cmp->longitude == ref->longitude) && - (compare_strings(cmp->description, ref->description) == 0) && - (compare_strings(cmp->notes, ref->notes) == 0)) return; - } - - wpt = waypt_dupe(ref); - - if (*opt_unique == '1') { - str = mkshort(short_h, wpt->shortname); - xfree(wpt->shortname); - wpt->shortname = str; - } - - wdata_add_wpt(wdata, wpt); + waypoint *wpt; + char *str; + queue *elem, *tmp; + + QUEUE_FOR_EACH(&wdata->Q, elem, tmp) { + waypoint *cmp = (waypoint *) elem; + + /* sort out nearly equal waypoints */ + if ((compare_strings(cmp->shortname, ref->shortname) == 0) && + (cmp->latitude == ref->latitude) && + (cmp->longitude == ref->longitude) && + (compare_strings(cmp->description, ref->description) == 0) && + (compare_strings(cmp->notes, ref->notes) == 0)) { + return; + } + } + + wpt = waypt_dupe(ref); + + if (*opt_unique == '1') { + str = mkshort(short_h, wpt->shortname); + xfree(wpt->shortname); + wpt->shortname = str; + } + + wdata_add_wpt(wdata, wpt); } static void load_bitmap_from_file(const char *fname, char **data, int *data_sz) { - gbfile *f; - int i, sz; - int dest_bpp; - int src_line_sz, dest_line_sz; - bmp_header_t src_h; - int *color_table = NULL; - gpi_bitmap_header_t *dest_h; - char *ptr; - - f = gbfopen_le(fname, "rb", MYNAME); - is_fatal(gbfgetint16(f) != 0x4d42, MYNAME ": No BMP image."); - - /* read a standard bmp file header */ - src_h.size = gbfgetint32(f); - src_h.res1 = gbfgetint16(f); - src_h.res2 = gbfgetint16(f); - src_h.image_offset = gbfgetint32(f); - src_h.header_size = gbfgetint32(f); - src_h.width = gbfgetint32(f); - src_h.height = gbfgetint32(f); - src_h.planes = gbfgetint16(f); - src_h.bpp = gbfgetint16(f); - src_h.compression_type = gbfgetint32(f); - src_h.image_data_size = gbfgetint32(f); - src_h.resolution_h = gbfgetint32(f); - src_h.resolution_v = gbfgetint32(f); - src_h.used_colors = gbfgetint32(f); - src_h.important_colors = gbfgetint32(f); - - /* Workaround for indexed BMP's with used_colors = 0 */ - if ((src_h.bpp == 8) && (src_h.used_colors == 0)) - src_h.used_colors = (src_h.image_offset - gbftell(f)) / 4; + gbfile *f; + int i, sz; + int dest_bpp; + int src_line_sz, dest_line_sz; + bmp_header_t src_h; + int *color_table = NULL; + gpi_bitmap_header_t *dest_h; + char *ptr; + + f = gbfopen_le(fname, "rb", MYNAME); + is_fatal(gbfgetint16(f) != 0x4d42, MYNAME ": No BMP image."); + + /* read a standard bmp file header */ + src_h.size = gbfgetint32(f); + src_h.res1 = gbfgetint16(f); + src_h.res2 = gbfgetint16(f); + src_h.image_offset = gbfgetint32(f); + src_h.header_size = gbfgetint32(f); + src_h.width = gbfgetint32(f); + src_h.height = gbfgetint32(f); + src_h.planes = gbfgetint16(f); + src_h.bpp = gbfgetint16(f); + src_h.compression_type = gbfgetint32(f); + src_h.image_data_size = gbfgetint32(f); + src_h.resolution_h = gbfgetint32(f); + src_h.resolution_v = gbfgetint32(f); + src_h.used_colors = gbfgetint32(f); + src_h.important_colors = gbfgetint32(f); + + /* Workaround for indexed BMP's with used_colors = 0 */ + if ((src_h.bpp == 8) && (src_h.used_colors == 0)) { + src_h.used_colors = (src_h.image_offset - gbftell(f)) / 4; + } #ifdef GPI_DBG - printf("data size: 0x%1$x (%1$d)\n", src_h.size); - printf("image data offset: 0x%1$x (%1$d)\n", src_h.image_offset); - printf("header size: 0x%1$x (%1$d)\n", src_h.header_size); - printf("image width: 0x%1$x (%1$d)\n", src_h.width); - printf("image height: 0x%1$x (%1$d)\n", src_h.height); - printf("number of planes: 0x%1$x (%1$d)\n", src_h.planes); - printf("bits per pixel: 0x%1$x (%1$d)\n", src_h.bpp); - printf("compression type: 0x%1$x (%1$d)\n", src_h.compression_type); - printf("image size: 0x%1$x (%1$d)\n", src_h.image_data_size); - printf("horizontal resolution: 0x%1$x (%1$d)\n", src_h.resolution_h); - printf("vertical resolution: 0x%1$x (%1$d)\n", src_h.resolution_v); - printf("number of colors: 0x%1$x (%1$d)\n", src_h.used_colors); - printf("important colors: 0x%1$x (%1$d)\n", src_h.important_colors); + printf("data size: 0x%1$x (%1$d)\n", src_h.size); + printf("image data offset: 0x%1$x (%1$d)\n", src_h.image_offset); + printf("header size: 0x%1$x (%1$d)\n", src_h.header_size); + printf("image width: 0x%1$x (%1$d)\n", src_h.width); + printf("image height: 0x%1$x (%1$d)\n", src_h.height); + printf("number of planes: 0x%1$x (%1$d)\n", src_h.planes); + printf("bits per pixel: 0x%1$x (%1$d)\n", src_h.bpp); + printf("compression type: 0x%1$x (%1$d)\n", src_h.compression_type); + printf("image size: 0x%1$x (%1$d)\n", src_h.image_data_size); + printf("horizontal resolution: 0x%1$x (%1$d)\n", src_h.resolution_h); + printf("vertical resolution: 0x%1$x (%1$d)\n", src_h.resolution_v); + printf("number of colors: 0x%1$x (%1$d)\n", src_h.used_colors); + printf("important colors: 0x%1$x (%1$d)\n", src_h.important_colors); #endif - - /* sort out unsupported files */ - if (! ((src_h.width <= 24) && (src_h.height <= 24) && - (src_h.width > 0) && (src_h.height > 0))) - fatal(MYNAME ": Unsupported format (%dx%d)!\n", src_h.width, src_h.height); - if (! ((src_h.bpp == 8) || (src_h.bpp == 24) || (src_h.bpp == 32))) - fatal(MYNAME ": Unsupported color depth (%d)!\n", src_h.bpp); - if (! (src_h.compression_type == 0)) - fatal(MYNAME ": Sorry, we don't support compressed bitmaps.\n"); - - if (src_h.used_colors > 0) { - color_table = xmalloc(4 * src_h.used_colors); - gbfread(color_table, 1, 4 * src_h.used_colors, f); - for (i = 0; i < src_h.used_colors; i++) { - int color = color_table[i]; - /* swap blue and red value */ - color = (color >> 16) | (color << 16) | (color & 0x00ff00); - color_table[i] = color & 0xffffff; - } - } - - /* calculate line-size for source and destination */ - src_line_sz = (src_h.width * src_h.bpp) / 8; - src_line_sz = ((int)((src_line_sz + 3) / 4)) * 4; - - if (src_h.bpp == 24) dest_bpp = 32; - else dest_bpp = src_h.bpp; - - dest_line_sz = (src_h.width * dest_bpp) / 8; - dest_line_sz = ((int)((dest_line_sz + 3) / 4)) * 4; - - sz = sizeof(*dest_h) + (src_h.height * dest_line_sz); - if (src_h.used_colors) sz += (src_h.used_colors * 4); - - ptr = xmalloc(sz); - dest_h = (void *)ptr; - *data = ptr; - *data_sz = sz; - - le_write16(&dest_h->index, 0); - le_write16(&dest_h->height, src_h.height); - le_write16(&dest_h->width, src_h.width); - le_write16(&dest_h->line_sz, dest_line_sz); - le_write16(&dest_h->bpp, dest_bpp); - le_write16(&dest_h->fixed_0, 0); /* seems to be fixed */ - le_write32(&dest_h->image_size, dest_line_sz * src_h.height); - le_write32(&dest_h->fixed_2c, 0x2c); /* seems to be fixed */ - le_write32(&dest_h->flag1, (dest_bpp == 8) ? 0x100 : 0); - le_write32(&dest_h->tr_color, 0xff00ff); /* magenta = transparent color */ - le_write32(&dest_h->flag2, 0x1); /* ? enable transparent mode ? */ - le_write32(&dest_h->size_2c, (dest_line_sz * src_h.height) + 0x2c); - - /* copy and revert order of BMP lines */ - ptr = (void *)dest_h; - ptr += (sizeof(*dest_h) + (dest_line_sz * (src_h.height - 1))); - - if (src_h.bpp == 24) { - /* 24 bpp seems to be not supported, convert to 32 bpp */ - for (i = 0; i < src_h.height; i++) { - int j; - char *p = ptr; - - for (j = 0; j < src_h.width; j++) { - int color; - color = (gbint32)gbfgetint16(f) | (gbfgetc(f) << 16); - le_write32(p, color); - p += 4; - } - for (j = (src_h.width * src_h.bpp) / 8; j < src_line_sz; j++) { - gbfgetc(f); /* drop fill-in bytes */ - } - ptr -= dest_line_sz; - } - } - else for (i = 0; i < src_h.height; i++) { - gbfread(ptr, 1, src_line_sz, f); - ptr -= dest_line_sz; - } - - if (src_h.used_colors > 0) { - ptr = (void *)dest_h; - ptr += (sizeof(*dest_h) + (src_h.height * src_line_sz)); - - for (i = 0; i < src_h.used_colors; i++) { - le_write32(ptr, color_table[i]); - ptr += 4; - } - } - - if (color_table) xfree(color_table); - gbfclose(f); + + /* sort out unsupported files */ + if (!((src_h.width <= 24) && (src_h.height <= 24) && + (src_h.width > 0) && (src_h.height > 0))) { + fatal(MYNAME ": Unsupported format (%dx%d)!\n", src_h.width, src_h.height); + } + if (!((src_h.bpp == 8) || (src_h.bpp == 24) || (src_h.bpp == 32))) { + fatal(MYNAME ": Unsupported color depth (%d)!\n", src_h.bpp); + } + if (!(src_h.compression_type == 0)) { + fatal(MYNAME ": Sorry, we don't support compressed bitmaps.\n"); + } + + if (src_h.used_colors > 0) { + color_table = xmalloc(4 * src_h.used_colors); + gbfread(color_table, 1, 4 * src_h.used_colors, f); + for (i = 0; i < src_h.used_colors; i++) { + int color = color_table[i]; + /* swap blue and red value */ + color = (color >> 16) | (color << 16) | (color & 0x00ff00); + color_table[i] = color & 0xffffff; + } + } + + /* calculate line-size for source and destination */ + src_line_sz = (src_h.width * src_h.bpp) / 8; + src_line_sz = ((int)((src_line_sz + 3) / 4)) * 4; + + if (src_h.bpp == 24) { + dest_bpp = 32; + } else { + dest_bpp = src_h.bpp; + } + + dest_line_sz = (src_h.width * dest_bpp) / 8; + dest_line_sz = ((int)((dest_line_sz + 3) / 4)) * 4; + + sz = sizeof(*dest_h) + (src_h.height * dest_line_sz); + if (src_h.used_colors) { + sz += (src_h.used_colors * 4); + } + + ptr = xmalloc(sz); + dest_h = (void *)ptr; + *data = ptr; + *data_sz = sz; + + le_write16(&dest_h->index, 0); + le_write16(&dest_h->height, src_h.height); + le_write16(&dest_h->width, src_h.width); + le_write16(&dest_h->line_sz, dest_line_sz); + le_write16(&dest_h->bpp, dest_bpp); + le_write16(&dest_h->fixed_0, 0); /* seems to be fixed */ + le_write32(&dest_h->image_size, dest_line_sz * src_h.height); + le_write32(&dest_h->fixed_2c, 0x2c); /* seems to be fixed */ + le_write32(&dest_h->flag1, (dest_bpp == 8) ? 0x100 : 0); + le_write32(&dest_h->tr_color, 0xff00ff); /* magenta = transparent color */ + le_write32(&dest_h->flag2, 0x1); /* ? enable transparent mode ? */ + le_write32(&dest_h->size_2c, (dest_line_sz * src_h.height) + 0x2c); + + /* copy and revert order of BMP lines */ + ptr = (void *)dest_h; + ptr += (sizeof(*dest_h) + (dest_line_sz * (src_h.height - 1))); + + if (src_h.bpp == 24) { + /* 24 bpp seems to be not supported, convert to 32 bpp */ + for (i = 0; i < src_h.height; i++) { + int j; + char *p = ptr; + + for (j = 0; j < src_h.width; j++) { + int color; + color = (gbint32)gbfgetint16(f) | (gbfgetc(f) << 16); + le_write32(p, color); + p += 4; + } + for (j = (src_h.width * src_h.bpp) / 8; j < src_line_sz; j++) { + gbfgetc(f); /* drop fill-in bytes */ + } + ptr -= dest_line_sz; + } + } else for (i = 0; i < src_h.height; i++) { + gbfread(ptr, 1, src_line_sz, f); + ptr -= dest_line_sz; + } + + if (src_h.used_colors > 0) { + ptr = (void *)dest_h; + ptr += (sizeof(*dest_h) + (src_h.height * src_line_sz)); + + for (i = 0; i < src_h.used_colors; i++) { + le_write32(ptr, color_table[i]); + ptr += 4; + } + } + + if (color_table) { + xfree(color_table); + } + gbfclose(f); } /******************************************************************************* @@ -1249,182 +1408,205 @@ load_bitmap_from_file(const char *fname, char **data, int *data_sz) static void garmin_gpi_rd_init(const char *fname) { - char cp[8]; - - fin = gbfopen_le(fname, "rb", MYNAME); - rdata = xcalloc(1, sizeof(*rdata)); - - read_header(); - - if ((codepage >= 1250) && (codepage <= 1257)) { - snprintf(cp, sizeof(cp), "CP%d", codepage); - cet_convert_init(cp, 1); - } - else warning(MYNAME ": Unsupported code page (%d).\n", codepage); - - units = tolower(opt_units[0]); - if ((units != 'm') && (units != 's')) - fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + char cp[8]; + + fin = gbfopen_le(fname, "rb", MYNAME); + rdata = xcalloc(1, sizeof(*rdata)); + + read_header(); + + if ((codepage >= 1250) && (codepage <= 1257)) { + snprintf(cp, sizeof(cp), "CP%d", codepage); + cet_convert_init(cp, 1); + } else { + warning(MYNAME ": Unsupported code page (%d).\n", codepage); + } + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) { + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + } } static void garmin_gpi_wr_init(const char *fname) { - char cp[8]; - cet_cs_vec_t *vec; - int i; - - if (gpi_timestamp != 0) { /* not the first gpi output session */ - time_t t = time(NULL); - if (t <= gpi_timestamp) - gpi_timestamp++; /* don't create files with same timestamp */ - else - gpi_timestamp = t; - } - else - gpi_timestamp = gpsbabel_time; /* always ZERO during 'testo' */ - - fout = gbfopen_le(fname, "wb", MYNAME); - - short_h = mkshort_new_handle(); - - setshort_length(short_h, 1024); - setshort_badchars(short_h, "\r\n"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 0); - setshort_defname(short_h, "POI"); - - codepage = 0; - - for (i = 1250; i <= 1257; i++) { - snprintf(cp, sizeof(cp), "CP%d", i); - vec = cet_find_cs_by_name(cp); - if (vec == global_opts.charset) { - codepage = i; - break; - } - } - - if (! codepage) { - warning(MYNAME ": Unsupported character set (%s)!\n", global_opts.charset_name); - fatal(MYNAME ": Valid values are CP1250 to CP1257.\n"); - } - - units = tolower(opt_units[0]); - if ((units != 'm') && (units != 's')) - fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); - - alerts = (opt_alerts) ? 1 : 0; - - if (opt_speed) { - double scale; - alerts = 1; /* Force alerts to be enabled */ - if (units == 's') scale = MPH_TO_MPS(1); /* We need speed in meters per second */ - else scale = KPH_TO_MPS(1); - parse_speed(opt_speed, &defspeed, scale, MYNAME); - } - - if (opt_proximity) { - double scale; - alerts = 1; /* Force alerts to be enabled */ - if (units == 's') scale = MILES_TO_METERS(1); /* We need proximity in meters */ - else scale = 1000.0; /* one kilometer in meters */ - parse_distance(opt_proximity, &defproximity, scale, MYNAME); - } - wdata = wdata_alloc(); + char cp[8]; + cet_cs_vec_t *vec; + int i; + + if (gpi_timestamp != 0) { /* not the first gpi output session */ + time_t t = time(NULL); + if (t <= gpi_timestamp) { + gpi_timestamp++; /* don't create files with same timestamp */ + } else { + gpi_timestamp = t; + } + } else { + gpi_timestamp = gpsbabel_time; /* always ZERO during 'testo' */ + } + + fout = gbfopen_le(fname, "wb", MYNAME); + + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); + setshort_badchars(short_h, "\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 0); + setshort_defname(short_h, "POI"); + + codepage = 0; + + for (i = 1250; i <= 1257; i++) { + snprintf(cp, sizeof(cp), "CP%d", i); + vec = cet_find_cs_by_name(cp); + if (vec == global_opts.charset) { + codepage = i; + break; + } + } + + if (! codepage) { + warning(MYNAME ": Unsupported character set (%s)!\n", global_opts.charset_name); + fatal(MYNAME ": Valid values are CP1250 to CP1257.\n"); + } + + units = tolower(opt_units[0]); + if ((units != 'm') && (units != 's')) { + fatal(MYNAME ": Unknown units parameter (%c).\n", opt_units[0]); + } + + alerts = (opt_alerts) ? 1 : 0; + + if (opt_speed) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') { + scale = MPH_TO_MPS(1); /* We need speed in meters per second */ + } else { + scale = KPH_TO_MPS(1); + } + parse_speed(opt_speed, &defspeed, scale, MYNAME); + } + + if (opt_proximity) { + double scale; + alerts = 1; /* Force alerts to be enabled */ + if (units == 's') { + scale = MILES_TO_METERS(1); /* We need proximity in meters */ + } else { + scale = 1000.0; /* one kilometer in meters */ + } + parse_distance(opt_proximity, &defproximity, scale, MYNAME); + } + wdata = wdata_alloc(); } -static void +static void garmin_gpi_rd_deinit(void) { - if (rdata->category) xfree(rdata->category); - if (rdata->group) xfree(rdata->group); - xfree(rdata); - gbfclose(fin); + if (rdata->category) { + xfree(rdata->category); + } + if (rdata->group) { + xfree(rdata->group); + } + xfree(rdata); + gbfclose(fin); } -static void +static void garmin_gpi_wr_deinit(void) { - wdata_free(wdata); - mkshort_del_handle(&short_h); - gbfclose(fout); - - if ((opt_sleep) && (gpi_timestamp != 0)) { /* don't sleep during 'testo' */ - int sleep = atoi(opt_sleep); - if (sleep < 1) sleep = 1; - gpi_timestamp += sleep; - while (gpi_timestamp > time(NULL)) { - gb_sleep(100); - } - } + wdata_free(wdata); + mkshort_del_handle(&short_h); + gbfclose(fout); + + if ((opt_sleep) && (gpi_timestamp != 0)) { /* don't sleep during 'testo' */ + int sleep = atoi(opt_sleep); + if (sleep < 1) { + sleep = 1; + } + gpi_timestamp += sleep; + while (gpi_timestamp > time(NULL)) { + gb_sleep(100); + } + } } static void garmin_gpi_read(void) { - while (1) { - int tag = gbfgetint32(fin); - if (tag == 0xffff) return; - if (! read_tag("garmin_gpi_read", tag, NULL)) return; - }; + while (1) { + int tag = gbfgetint32(fin); + if (tag == 0xffff) { + return; + } + if (! read_tag("garmin_gpi_read", tag, NULL)) { + return; + } + }; } static void garmin_gpi_write(void) { - char *image; - int image_sz; - - if (strlen(opt_cat) == 0) fatal(MYNAME ": Can't write empty category!\n"); - - if (opt_hide_bitmap) { - image = NULL; - image_sz = 0; - } - else if (opt_bitmap && *opt_bitmap) - load_bitmap_from_file(opt_bitmap, &image, &image_sz); - else { - image = gpi_bitmap; /* embedded GPSBabel icon in gpi format */ - image_sz = GPI_BITMAP_SIZE; - } - waypt_disp_all(enum_waypt_cb); - - wdata_check(wdata); - write_header(); - write_category(opt_cat, image, image_sz); - - gbfputint32(0xffff, fout); /* final tag */ - gbfputint32(0, fout); /* ? dummy size ? */ - - if (image != gpi_bitmap) xfree(image); + char *image; + int image_sz; + + if (strlen(opt_cat) == 0) { + fatal(MYNAME ": Can't write empty category!\n"); + } + + if (opt_hide_bitmap) { + image = NULL; + image_sz = 0; + } else if (opt_bitmap && *opt_bitmap) { + load_bitmap_from_file(opt_bitmap, &image, &image_sz); + } else { + image = gpi_bitmap; /* embedded GPSBabel icon in gpi format */ + image_sz = GPI_BITMAP_SIZE; + } + waypt_disp_all(enum_waypt_cb); + + wdata_check(wdata); + write_header(); + write_category(opt_cat, image, image_sz); + + gbfputint32(0xffff, fout); /* final tag */ + gbfputint32(0, fout); /* ? dummy size ? */ + + if (image != gpi_bitmap) { + xfree(image); + } } /**************************************************************************/ ff_vecs_t garmin_gpi_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - garmin_gpi_rd_init, - garmin_gpi_wr_init, - garmin_gpi_rd_deinit, - garmin_gpi_wr_deinit, - garmin_gpi_read, - garmin_gpi_write, - NULL, - garmin_gpi_args, - CET_CHARSET_MS_ANSI, 0 /* WIN-CP1252 */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + garmin_gpi_rd_init, + garmin_gpi_wr_init, + garmin_gpi_rd_deinit, + garmin_gpi_wr_deinit, + garmin_gpi_read, + garmin_gpi_write, + NULL, + garmin_gpi_args, + CET_CHARSET_MS_ANSI, 0 /* WIN-CP1252 */ }; /**************************************************************************/ diff --git a/gpsbabel/garmin_gpi.h b/gpsbabel/garmin_gpi.h index 8c2bab369..9e816ba11 100644 --- a/gpsbabel/garmin_gpi.h +++ b/gpsbabel/garmin_gpi.h @@ -2,109 +2,109 @@ #define GARMIN_GPI_H static char gpi_bitmap[] = { - 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x40,0x02,0x00,0x00, - 0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0x01,0x00,0x00,0x00, - 0x6c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x59,0x67,0x65,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x74,0x3d,0x42,0x56,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x72,0x38,0x49,0x47,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x6c,0x50,0x44,0x5e,0x4f,0x76,0x7e,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x77,0x7e,0x7f,0x7f,0x7e,0x62,0x0d,0x00,0x05, - 0x10,0x08,0x09,0x59,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x29,0x1c, - 0x4c,0x7f,0x7f,0x60,0x02,0x0c,0x2a,0x37,0x51,0x63,0x57,0x15,0x58,0x7e,0x7e,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x68,0x5a,0x41,0x5f,0x5f,0x07,0x0e,0x3d,0x41,0x41, - 0x4d,0x55,0x6b,0x61,0x26,0x57,0x57,0x2b,0x2f,0x30,0x00,0x7e,0x00,0x7e,0x77,0x7d, - 0x4e,0x3d,0x3d,0x16,0x35,0x41,0x7d,0x49,0x18,0x48,0x52,0x54,0x5b,0x31,0x31,0x63, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x40,0x7d,0x75,0x47,0x47,0x41,0x35,0x40,0x72,0x1e, - 0x7c,0x5d,0x1d,0x20,0x49,0x3d,0x3d,0x5b,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x60,0x5c, - 0x7a,0x1a,0x1a,0x3b,0x38,0x5d,0x0e,0x59,0x7d,0x3c,0x72,0x37,0x78,0x60,0x60,0x28, - 0x4f,0x71,0x00,0x7e,0x00,0x7e,0x7e,0x43,0x33,0x69,0x69,0x17,0x22,0x7d,0x2c,0x27, - 0x2a,0x2b,0x7d,0x32,0x61,0x4f,0x4f,0x36,0x3f,0x4c,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x3a,0x2b,0x2b,0x45,0x1a,0x40,0x47,0x7d,0x37,0x41,0x12,0x25,0x5e,0x46,0x46,0x4d, - 0x62,0x53,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x73,0x71,0x71,0x6a,0x13,0x39,0x1b,0x45, - 0x62,0x50,0x3a,0x7e,0x7e,0x7b,0x7b,0x5c,0x5b,0x49,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e,0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e, - 0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e, - 0x7c,0x0a,0x0a,0x0f,0x65,0x7d,0x74,0x71,0x7c,0x7e,0x7e,0x7e,0x58,0x03,0x03,0x2b, - 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x6d,0x6d,0x6f,0x2d,0x1d,0x63,0x7a, - 0x7e,0x75,0x5d,0x19,0x32,0x70,0x70,0x6f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, - 0x7f,0x7f,0x7f,0x7e,0x7d,0x53,0x35,0x0b,0x1f,0x0e,0x34,0x5a,0x7f,0x7f,0x7f,0x7f, - 0x7f,0x7f,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7f,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, - 0x7e,0x7e,0x7e,0x7e,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x16,0x16,0x16,0x00, - 0x1f,0x1f,0x1f,0x00,0x28,0x28,0x28,0x00,0x2d,0x2d,0x2d,0x00,0x35,0x35,0x35,0x00, - 0x3d,0x3d,0x3d,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00, - 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x4b,0x4b,0x4b,0x00,0x4e,0x4e,0x4e,0x00, - 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x59,0x59,0x59,0x00, - 0x5a,0x5a,0x5a,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00, - 0x63,0x63,0x63,0x00,0x6a,0x6a,0x6a,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, - 0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, - 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, - 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00, - 0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, - 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x90,0x00, - 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, - 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9b,0x9b,0x9b,0x00, - 0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, - 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, - 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, - 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, - 0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, - 0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00, - 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, - 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, - 0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xce,0x00, - 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00, - 0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd9,0xd9,0xd9,0x00, - 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, - 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, - 0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, - 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00, - 0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00, - 0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, - 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xff,0xff,0xff,0x00, - 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00 + 0x00,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x08,0x00,0x00,0x00,0x40,0x02,0x00,0x00, + 0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xff,0x00,0xff,0x00,0x01,0x00,0x00,0x00, + 0x6c,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x59,0x67,0x65,0x7f,0x7f,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x74,0x3d,0x42,0x56,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x72,0x38,0x49,0x47,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7d,0x37,0x47,0x7d,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7f,0x7f,0x7c,0x6c,0x50,0x44,0x5e,0x4f,0x76,0x7e,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x77,0x7e,0x7f,0x7f,0x7e,0x62,0x0d,0x00,0x05, + 0x10,0x08,0x09,0x59,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x29,0x1c, + 0x4c,0x7f,0x7f,0x60,0x02,0x0c,0x2a,0x37,0x51,0x63,0x57,0x15,0x58,0x7e,0x7e,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x68,0x5a,0x41,0x5f,0x5f,0x07,0x0e,0x3d,0x41,0x41, + 0x4d,0x55,0x6b,0x61,0x26,0x57,0x57,0x2b,0x2f,0x30,0x00,0x7e,0x00,0x7e,0x77,0x7d, + 0x4e,0x3d,0x3d,0x16,0x35,0x41,0x7d,0x49,0x18,0x48,0x52,0x54,0x5b,0x31,0x31,0x63, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x40,0x7d,0x75,0x47,0x47,0x41,0x35,0x40,0x72,0x1e, + 0x7c,0x5d,0x1d,0x20,0x49,0x3d,0x3d,0x5b,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x60,0x5c, + 0x7a,0x1a,0x1a,0x3b,0x38,0x5d,0x0e,0x59,0x7d,0x3c,0x72,0x37,0x78,0x60,0x60,0x28, + 0x4f,0x71,0x00,0x7e,0x00,0x7e,0x7e,0x43,0x33,0x69,0x69,0x17,0x22,0x7d,0x2c,0x27, + 0x2a,0x2b,0x7d,0x32,0x61,0x4f,0x4f,0x36,0x3f,0x4c,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x3a,0x2b,0x2b,0x45,0x1a,0x40,0x47,0x7d,0x37,0x41,0x12,0x25,0x5e,0x46,0x46,0x4d, + 0x62,0x53,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x73,0x71,0x71,0x6a,0x13,0x39,0x1b,0x45, + 0x62,0x50,0x3a,0x7e,0x7e,0x7b,0x7b,0x5c,0x5b,0x49,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e,0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e,0x59,0x01,0x01,0x06,0x64,0x35,0x4e,0x3e, + 0x26,0x21,0x66,0x7f,0x45,0x04,0x04,0x11,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7e, + 0x7c,0x0a,0x0a,0x0f,0x65,0x7d,0x74,0x71,0x7c,0x7e,0x7e,0x7e,0x58,0x03,0x03,0x2b, + 0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f,0x7f,0x6d,0x6d,0x6f,0x2d,0x1d,0x63,0x7a, + 0x7e,0x75,0x5d,0x19,0x32,0x70,0x70,0x6f,0x7f,0x7f,0x00,0x7e,0x00,0x7e,0x7f,0x7f, + 0x7f,0x7f,0x7f,0x7e,0x7d,0x53,0x35,0x0b,0x1f,0x0e,0x34,0x5a,0x7f,0x7f,0x7f,0x7f, + 0x7f,0x7f,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x7f,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e,0x7e, + 0x7e,0x7e,0x7e,0x7e,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x16,0x16,0x16,0x00, + 0x1f,0x1f,0x1f,0x00,0x28,0x28,0x28,0x00,0x2d,0x2d,0x2d,0x00,0x35,0x35,0x35,0x00, + 0x3d,0x3d,0x3d,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x4b,0x4b,0x4b,0x00,0x4e,0x4e,0x4e,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00, + 0x63,0x63,0x63,0x00,0x6a,0x6a,0x6a,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00, + 0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9b,0x9b,0x9b,0x00, + 0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, + 0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00, + 0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00, + 0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00, + 0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xff,0xff,0xff,0x00, + 0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00 }; #define GPI_BITMAP_SIZE sizeof(gpi_bitmap) diff --git a/gpsbabel/garmin_tables.c b/gpsbabel/garmin_tables.c index ed4a38b1b..3c58cff64 100644 --- a/gpsbabel/garmin_tables.c +++ b/gpsbabel/garmin_tables.c @@ -30,648 +30,644 @@ /* MapSource 4.13 */ icon_mapping_t garmin_icon_table[] = { -/* mps pcx desc */ - { 107, 16384, "Airport" }, - { 73, 8204, "Amusement Park" }, - { 55, 169, "Ball Park" }, - { 6, 6, "Bank" }, - { 13, 13, "Bar" }, - { 104, 8244, "Beach" }, - { 1, 1, "Bell" }, - { 37, 150, "Boat Ramp" }, - { 74, 8205, "Bowling" }, - { 93, 8233, "Bridge" }, - { 94, 8234, "Building" }, - { 38, 151, "Campground" }, - { 56, 170, "Car" }, - { 75, 8206, "Car Rental" }, - { 76, 8207, "Car Repair" }, - { 95, 8235, "Cemetery" }, - { 96, 8236, "Church" }, - { 65, 179, "Circle with X" }, - { 72, 8203, "City (Capitol)" }, - { 71, 8200, "City (Large)" }, - { 70, 8199, "City (Medium)" }, - { 69, 8198, "City (Small)" }, - { 69, 8198, "Small City" }, - { 97, 8237, "Civil" }, - { 119, 8262, "Contact, Afro" }, - { 120, 8272, "Contact, Alien" }, - { 121, 8258, "Contact, Ball Cap" }, - { 122, 8259, "Contact, Big Ears" }, - { 123, 8271, "Contact, Biker" }, - { 124, 8273, "Contact, Bug" }, - { 125, 8274, "Contact, Cat" }, - { 126, 8275, "Contact, Dog" }, - { 127, 8263, "Contact, Dreadlocks" }, - { 128, 8264, "Contact, Female1" }, - { 129, 8265, "Contact, Female2" }, - { 130, 8266, "Contact, Female3" }, - { 131, 8261, "Contact, Goatee" }, - { 132, 8268, "Contact, Kung-Fu" }, - { 133, 8276, "Contact, Pig" }, - { 134, 8270, "Contact, Pirate" }, - { 135, 8267, "Contact, Ranger" }, - { 136, 8257, "Contact, Smiley" }, - { 137, 8260, "Contact, Spike" }, - { 138, 8269, "Contact, Sumo" }, - { 52, 165, "Controlled Area" }, - { 89, 8220, "Convenience Store" }, - { 98, 8238, "Crossing" }, - { 51, 164, "Dam" }, - { 53, 166, "Danger Area" }, - { 87, 8218, "Department Store" }, - { 4, 4, "Diver Down Flag 1" }, - { 5, 5, "Diver Down Flag 2" }, - { 41, 154, "Drinking Water" }, - { 63, 177, "Exit" }, - { 77, 8208, "Fast Food" }, - { 7, 7, "Fishing Area" }, - { 78, 8209, "Fitness Center" }, - { 64, 178, "Flag" }, - { 105, 8245, "Forest" }, - { 8, 8, "Gas Station" }, - { 117, 8255, "Geocache" }, - { 118, 8256, "Geocache Found" }, - { 99, 8239, "Ghost Town" }, - { 113, 16393, "Glider Area" }, - { 68, 8197, "Golf Course" }, - { 2, 2, "Diamond, Green" }, - { 15, 15, "Square, Green" }, - { 108, 16388, "Heliport" }, - { 9, 9, "Horn" }, - { 57, 171, "Hunting Area" }, - { 44, 157, "Information" }, - { 100, 8240, "Levee" }, - { 12, 12, "Light" }, - { 90, 8221, "Live Theater" }, - { 59, 173, "Lodging" }, - { 59, 173, "Hotel" }, - { 20, 21, "Man Overboard" }, - { 0, 0, "Anchor" }, - { 43, 156, "Medical Facility" }, - { 66, 8195, "Mile Marker" }, - { 101, 8241, "Military" }, - { 60, 174, "Mine" }, - { 79, 8210, "Movie Theater" }, - { 80, 8211, "Museum" }, - { 21, 22, "Navaid, Amber" }, - { 22, 23, "Navaid, Black" }, - { 23, 24, "Navaid, Blue" }, - { 24, 25, "Navaid, Green" }, - { 25, 26, "Navaid, Green/Red" }, - { 26, 27, "Navaid, Green/White" }, - { 27, 28, "Navaid, Orange" }, - { 28, 29, "Navaid, Red" }, - { 29, 30, "Navaid, Red/Green" }, - { 30, 31, "Navaid, Red/White" }, - { 31, 32, "Navaid, Violet" }, - { 32, 33, "Navaid, White" }, - { 33, 34, "Navaid, White/Green" }, - { 34, 35, "Navaid, White/Red" }, - { 102, 8242, "Oil Field" }, - { 115, 16395, "Parachute Area" }, - { 46, 159, "Park" }, - { 45, 158, "Parking Area" }, - { 81, 8212, "Pharmacy" }, - { 47, 160, "Picnic Area" }, - { 82, 8213, "Pizza" }, - { 83, 8214, "Post Office" }, - { 109, 16389, "Private Field" }, - { 36, 37, "Radio Beacon" }, - { 3, 3, "Diamond, Red" }, - { 16, 16, "Square, Red" }, - { 10, 10, "Residence" }, - { 10, 10, "House" }, - { 11, 11, "Restaurant" }, - { 54, 167, "Restricted Area" }, - { 39, 152, "Restroom" }, - { 84, 8215, "RV Park" }, - { 91, 8226, "Scales" }, - { 48, 161, "Scenic Area" }, - { 85, 8216, "School" }, - { 116, 16402, "Seaplane Base" }, - { 19, 19, "Shipwreck" }, - { 58, 172, "Shopping Center" }, - { 112, 16392, "Short Tower" }, - { 40, 153, "Shower" }, - { 49, 162, "Skiing Area" }, - { 14, 14, "Skull and Crossbones" }, - { 110, 16390, "Soft Field" }, - { 86, 8217, "Stadium" }, - { 106, 8246, "Summit" }, - { 50, 163, "Swimming Area" }, - { 111, 16391, "Tall Tower" }, - { 42, 155, "Telephone" }, - { 92, 8227, "Toll Booth" }, - { 67, 8196, "TracBack Point" }, - { 61, 175, "Trail Head" }, - { 62, 176, "Truck Stop" }, - { 103, 8243, "Tunnel" }, - { 114, 16394, "Ultralight Area" }, - { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ - { 18, 18, "Waypoint" }, - { 17, 17, "Buoy, White" }, - { 35, 36, "Dot, White" }, - { 88, 8219, "Zoo" }, - - /* Custom icons. The spec reserves 7680-8191 for the custom - * icons on the C units, Quest, 27xx, 276, 296, and other units. - * Note that firmware problems on the earlier unit result in these - * being mangled, so be sure you're on a version from at least - * late 2005. - * { -2, 7680, "Custom 0" }, - * .... - * { -2, 8192, "Custom 511" }, - */ - /* MapSource V6.x */ - - { 140, 8286, "Flag, Red" }, - { 141, 8284, "Flag, Blue" }, - { 142, 8285, "Flag, Green" }, - { 143, 8289, "Pin, Red" }, - { 144, 8287, "Pin, Blue" }, - { 145, 8288, "Pin, Green" }, - { 146, 8292, "Block, Red" }, - { 147, 8290, "Block, Blue" }, - { 148, 8291, "Block, Green" }, - { 149, 8293, "Bike Trail" }, - { 150, 181, "Fishing Hot Spot Facility" }, - { 151, 8249, "Police Station"}, - { 152, 8251, "Ski Resort" }, - { 153, 8252, "Ice Skating" }, - { 154, 8253, "Wrecker" }, - { 155, 184, "Anchor Prohibited" }, - { 156, 185, "Beacon" }, - { 157, 186, "Coast Guard" }, - { 158, 187, "Reef" }, - { 159, 188, "Weed Bed" }, - { 160, 189, "Dropoff" }, - { 161, 190, "Dock" }, - { 162, 191, "Marina" }, - { 163, 192, "Bait and Tackle" }, - { 164, 193, "Stump" }, - - /* New in Garmin protocol spec from June 2006. Extracted from - * spec and fed through some horrible awk to add ones we didn't - * have before but normalized for consistency. */ - { -1, 8359, "Asian Food" }, - { 167, 8296, "Circle, Blue" }, - { 168, 8299, "Diamond, Blue" }, - { 178, 8317, "Letter A, Blue" }, - { 181, 8318, "Letter B, Blue" }, - { 184, 8319, "Letter C, Blue" }, - { 187, 8320, "Letter D, Blue" }, - { 190, 8341, "Number 0, Blue" }, - { 193, 8342, "Number 1, Blue" }, - { 196, 8343, "Number 2, Blue" }, - { 199, 8344, "Number 3, Blue" }, - { 202, 8345, "Number 4, Blue" }, - { 205, 8346, "Number 5, Blue" }, - { 208, 8347, "Number 6, Blue" }, - { 211, 8348, "Number 7, Blue" }, - { 214, 8349, "Number 8, Blue" }, - { 217, 8350, "Number 9, Blue" }, - { 171, 8302, "Oval, Blue" }, - { 174, 8305, "Rectangle, Blue" }, - { 175, 8308, "Square, Blue" }, - { 218, 8351, "Triangle, Blue" }, - { -1, 8254, "Border Crossing (Port Of Entry)" }, - { -1, 182, "Bottom Conditions" }, - { -1, 8360, "Deli" }, - { -1, 8228, "Elevation point" }, - { -1, 8229, "Exit without services" }, - { -1, 16398, "First approach fix" }, - { -1, 8250, "Gambling/casino" }, - { -1, 8232, "Geographic place name, land" }, - { -1, 8230, "Geographic place name, Man-made" }, - { -1, 8231, "Geographic place name, water" }, - { 166, 8295, "Circle, Green" }, - { 177, 8313, "Letter A, Green" }, - { 180, 8315, "Letter B, Green" }, - { 183, 8314, "Letter C, Green" }, - { 186, 8316, "Letter D, Green" }, - { 189, 8331, "Number 0, Green" }, - { 192, 8332, "Number 1, Green" }, - { 195, 8333, "Number 2, Green" }, - { 198, 8334, "Number 3, Green" }, - { 201, 8335, "Number 4, Green" }, - { 204, 8336, "Number 5, Green" }, - { 207, 8337, "Number 6, Green" }, - { 210, 8338, "Number 7, Green" }, - { 213, 8339, "Number 8, Green" }, - { 216, 8340, "Number 9, Green" }, - { 170, 8301, "Oval, Green" }, - { 173, 8304, "Rectangle, Green" }, - { 219, 8352, "Triangle, Green" }, - { -1, 16385, "Intersection" }, - { -1, 8201, "Intl freeway hwy" }, - { -1, 8202, "Intl national hwy" }, - { -1, 8361, "Italian food" }, - { -1, 8248, "Large exit without services" }, - { -1, 8247, "Large Ramp intersection" }, - { -1, 16399, "Localizer Outer Marker" }, - { -1, 16400, "Missed approach point" }, - { -1, 16386, "Non-directional beacon" }, - { -1, 168, "Null" }, - { -1, 180, "Open 24 Hours" }, - { -1, 8222, "Ramp intersection" }, - { 165, 8294, "Circle, Red" }, - { 176, 8309, "Letter A, Red" }, - { 179, 8310, "Letter B, Red" }, - { 182, 8311, "Letter C, Red" }, - { 185, 8312, "Letter D, Red" }, - { 188, 8321, "Number 0, Red" }, - { 191, 8322, "Number 1, Red" }, - { 194, 8323, "Number 2, Red" }, - { 197, 8324, "Number 3, Red" }, - { 200, 8325, "Number 4, Red" }, - { 203, 8326, "Number 5, Red" }, - { 206, 8327, "Number 6, Red" }, - { 209, 8328, "Number 7, Red" }, - { 212, 8329, "Number 8, Red" }, - { 215, 8330, "Number 9, Red" }, - { 169, 8300, "Oval, Red" }, - { 172, 8303, "Rectangle, Red" }, - { 220, 8353, "Triangle, Red" }, - { -1, 8362, "Seafood" }, - { -1, 8194, "State Hwy" }, - { -1, 8363, "Steak" }, - { -1, 8223, "Street Intersection" }, - { -1, 16401, "TACAN" }, - { -1, 183, "Tide/Current PRediction Station" }, - { -1, 191, "U Marina" }, - { -1, 8193, "US hwy" }, - { -1, 193, "U stump" }, - { -1, 16387, "VHF Omni-range" }, - { -1, 16397, "VOR-DME" }, - { -1, 16396, "VOR/TACAN" }, - - /* This block new on 1/15 from the Mapsource 6.12 beta */ - { 221, -1, "Contact, Blonde" }, - { 222, -1, "Contact, Clown" }, - { 223, -1, "Contact, Glasses" }, - { 224, -1, "Contact, Panda" }, - { 225, -1, "Multi-Cache" }, - { 226, -1, "Letterbox Cache" }, - { 227, -1, "Puzzle Cache" }, - { 228, -1, "Library" }, - { 229, -1, "Ground Transportation" }, - { 230, -1, "City Hall" }, - { 231, -1, "Winery" }, - { 232, -1, "ATV" }, - { 233, -1, "Big Game" }, - { 234, -1, "Blind" }, - { 235, -1, "Blood Trail" }, - { 236, -1, "Cover" }, - { 237, -1, "Covey" }, - { 238, -1, "Food Source" }, - { 239, -1, "Furbearer" }, - { 240, -1, "Lodge" }, - { 241, -1, "Small Game" }, - { 242, -1, "Animal Tracks" }, - { 243, -1, "Treed Quarry" }, - { 244, -1, "Tree Stand" }, - { 245, -1, "Truck" }, - { 246, -1, "Upland Game" }, - { 247, -1, "Waterfowl" }, - { 248, -1, "Water Source" }, - - - { -1, -1, NULL }, + /* mps pcx desc */ + { 107, 16384, "Airport" }, + { 73, 8204, "Amusement Park" }, + { 55, 169, "Ball Park" }, + { 6, 6, "Bank" }, + { 13, 13, "Bar" }, + { 104, 8244, "Beach" }, + { 1, 1, "Bell" }, + { 37, 150, "Boat Ramp" }, + { 74, 8205, "Bowling" }, + { 93, 8233, "Bridge" }, + { 94, 8234, "Building" }, + { 38, 151, "Campground" }, + { 56, 170, "Car" }, + { 75, 8206, "Car Rental" }, + { 76, 8207, "Car Repair" }, + { 95, 8235, "Cemetery" }, + { 96, 8236, "Church" }, + { 65, 179, "Circle with X" }, + { 72, 8203, "City (Capitol)" }, + { 71, 8200, "City (Large)" }, + { 70, 8199, "City (Medium)" }, + { 69, 8198, "City (Small)" }, + { 69, 8198, "Small City" }, + { 97, 8237, "Civil" }, + { 119, 8262, "Contact, Afro" }, + { 120, 8272, "Contact, Alien" }, + { 121, 8258, "Contact, Ball Cap" }, + { 122, 8259, "Contact, Big Ears" }, + { 123, 8271, "Contact, Biker" }, + { 124, 8273, "Contact, Bug" }, + { 125, 8274, "Contact, Cat" }, + { 126, 8275, "Contact, Dog" }, + { 127, 8263, "Contact, Dreadlocks" }, + { 128, 8264, "Contact, Female1" }, + { 129, 8265, "Contact, Female2" }, + { 130, 8266, "Contact, Female3" }, + { 131, 8261, "Contact, Goatee" }, + { 132, 8268, "Contact, Kung-Fu" }, + { 133, 8276, "Contact, Pig" }, + { 134, 8270, "Contact, Pirate" }, + { 135, 8267, "Contact, Ranger" }, + { 136, 8257, "Contact, Smiley" }, + { 137, 8260, "Contact, Spike" }, + { 138, 8269, "Contact, Sumo" }, + { 52, 165, "Controlled Area" }, + { 89, 8220, "Convenience Store" }, + { 98, 8238, "Crossing" }, + { 51, 164, "Dam" }, + { 53, 166, "Danger Area" }, + { 87, 8218, "Department Store" }, + { 4, 4, "Diver Down Flag 1" }, + { 5, 5, "Diver Down Flag 2" }, + { 41, 154, "Drinking Water" }, + { 63, 177, "Exit" }, + { 77, 8208, "Fast Food" }, + { 7, 7, "Fishing Area" }, + { 78, 8209, "Fitness Center" }, + { 64, 178, "Flag" }, + { 105, 8245, "Forest" }, + { 8, 8, "Gas Station" }, + { 117, 8255, "Geocache" }, + { 118, 8256, "Geocache Found" }, + { 99, 8239, "Ghost Town" }, + { 113, 16393, "Glider Area" }, + { 68, 8197, "Golf Course" }, + { 2, 2, "Diamond, Green" }, + { 15, 15, "Square, Green" }, + { 108, 16388, "Heliport" }, + { 9, 9, "Horn" }, + { 57, 171, "Hunting Area" }, + { 44, 157, "Information" }, + { 100, 8240, "Levee" }, + { 12, 12, "Light" }, + { 90, 8221, "Live Theater" }, + { 59, 173, "Lodging" }, + { 59, 173, "Hotel" }, + { 20, 21, "Man Overboard" }, + { 0, 0, "Anchor" }, + { 43, 156, "Medical Facility" }, + { 66, 8195, "Mile Marker" }, + { 101, 8241, "Military" }, + { 60, 174, "Mine" }, + { 79, 8210, "Movie Theater" }, + { 80, 8211, "Museum" }, + { 21, 22, "Navaid, Amber" }, + { 22, 23, "Navaid, Black" }, + { 23, 24, "Navaid, Blue" }, + { 24, 25, "Navaid, Green" }, + { 25, 26, "Navaid, Green/Red" }, + { 26, 27, "Navaid, Green/White" }, + { 27, 28, "Navaid, Orange" }, + { 28, 29, "Navaid, Red" }, + { 29, 30, "Navaid, Red/Green" }, + { 30, 31, "Navaid, Red/White" }, + { 31, 32, "Navaid, Violet" }, + { 32, 33, "Navaid, White" }, + { 33, 34, "Navaid, White/Green" }, + { 34, 35, "Navaid, White/Red" }, + { 102, 8242, "Oil Field" }, + { 115, 16395, "Parachute Area" }, + { 46, 159, "Park" }, + { 45, 158, "Parking Area" }, + { 81, 8212, "Pharmacy" }, + { 47, 160, "Picnic Area" }, + { 82, 8213, "Pizza" }, + { 83, 8214, "Post Office" }, + { 109, 16389, "Private Field" }, + { 36, 37, "Radio Beacon" }, + { 3, 3, "Diamond, Red" }, + { 16, 16, "Square, Red" }, + { 10, 10, "Residence" }, + { 10, 10, "House" }, + { 11, 11, "Restaurant" }, + { 54, 167, "Restricted Area" }, + { 39, 152, "Restroom" }, + { 84, 8215, "RV Park" }, + { 91, 8226, "Scales" }, + { 48, 161, "Scenic Area" }, + { 85, 8216, "School" }, + { 116, 16402, "Seaplane Base" }, + { 19, 19, "Shipwreck" }, + { 58, 172, "Shopping Center" }, + { 112, 16392, "Short Tower" }, + { 40, 153, "Shower" }, + { 49, 162, "Skiing Area" }, + { 14, 14, "Skull and Crossbones" }, + { 110, 16390, "Soft Field" }, + { 86, 8217, "Stadium" }, + { 106, 8246, "Summit" }, + { 50, 163, "Swimming Area" }, + { 111, 16391, "Tall Tower" }, + { 42, 155, "Telephone" }, + { 92, 8227, "Toll Booth" }, + { 67, 8196, "TracBack Point" }, + { 61, 175, "Trail Head" }, + { 62, 176, "Truck Stop" }, + { 103, 8243, "Tunnel" }, + { 114, 16394, "Ultralight Area" }, + { 139, 8282, "Water Hydrant" }, /* new in MapSource V5 */ + { 18, 18, "Waypoint" }, + { 17, 17, "Buoy, White" }, + { 35, 36, "Dot, White" }, + { 88, 8219, "Zoo" }, + + /* Custom icons. The spec reserves 7680-8191 for the custom + * icons on the C units, Quest, 27xx, 276, 296, and other units. + * Note that firmware problems on the earlier unit result in these + * being mangled, so be sure you're on a version from at least + * late 2005. + * { -2, 7680, "Custom 0" }, + * .... + * { -2, 8192, "Custom 511" }, + */ + /* MapSource V6.x */ + + { 140, 8286, "Flag, Red" }, + { 141, 8284, "Flag, Blue" }, + { 142, 8285, "Flag, Green" }, + { 143, 8289, "Pin, Red" }, + { 144, 8287, "Pin, Blue" }, + { 145, 8288, "Pin, Green" }, + { 146, 8292, "Block, Red" }, + { 147, 8290, "Block, Blue" }, + { 148, 8291, "Block, Green" }, + { 149, 8293, "Bike Trail" }, + { 150, 181, "Fishing Hot Spot Facility" }, + { 151, 8249, "Police Station"}, + { 152, 8251, "Ski Resort" }, + { 153, 8252, "Ice Skating" }, + { 154, 8253, "Wrecker" }, + { 155, 184, "Anchor Prohibited" }, + { 156, 185, "Beacon" }, + { 157, 186, "Coast Guard" }, + { 158, 187, "Reef" }, + { 159, 188, "Weed Bed" }, + { 160, 189, "Dropoff" }, + { 161, 190, "Dock" }, + { 162, 191, "Marina" }, + { 163, 192, "Bait and Tackle" }, + { 164, 193, "Stump" }, + + /* New in Garmin protocol spec from June 2006. Extracted from + * spec and fed through some horrible awk to add ones we didn't + * have before but normalized for consistency. */ + { -1, 8359, "Asian Food" }, + { 167, 8296, "Circle, Blue" }, + { 168, 8299, "Diamond, Blue" }, + { 178, 8317, "Letter A, Blue" }, + { 181, 8318, "Letter B, Blue" }, + { 184, 8319, "Letter C, Blue" }, + { 187, 8320, "Letter D, Blue" }, + { 190, 8341, "Number 0, Blue" }, + { 193, 8342, "Number 1, Blue" }, + { 196, 8343, "Number 2, Blue" }, + { 199, 8344, "Number 3, Blue" }, + { 202, 8345, "Number 4, Blue" }, + { 205, 8346, "Number 5, Blue" }, + { 208, 8347, "Number 6, Blue" }, + { 211, 8348, "Number 7, Blue" }, + { 214, 8349, "Number 8, Blue" }, + { 217, 8350, "Number 9, Blue" }, + { 171, 8302, "Oval, Blue" }, + { 174, 8305, "Rectangle, Blue" }, + { 175, 8308, "Square, Blue" }, + { 218, 8351, "Triangle, Blue" }, + { -1, 8254, "Border Crossing (Port Of Entry)" }, + { -1, 182, "Bottom Conditions" }, + { -1, 8360, "Deli" }, + { -1, 8228, "Elevation point" }, + { -1, 8229, "Exit without services" }, + { -1, 16398, "First approach fix" }, + { -1, 8250, "Gambling/casino" }, + { -1, 8232, "Geographic place name, land" }, + { -1, 8230, "Geographic place name, Man-made" }, + { -1, 8231, "Geographic place name, water" }, + { 166, 8295, "Circle, Green" }, + { 177, 8313, "Letter A, Green" }, + { 180, 8315, "Letter B, Green" }, + { 183, 8314, "Letter C, Green" }, + { 186, 8316, "Letter D, Green" }, + { 189, 8331, "Number 0, Green" }, + { 192, 8332, "Number 1, Green" }, + { 195, 8333, "Number 2, Green" }, + { 198, 8334, "Number 3, Green" }, + { 201, 8335, "Number 4, Green" }, + { 204, 8336, "Number 5, Green" }, + { 207, 8337, "Number 6, Green" }, + { 210, 8338, "Number 7, Green" }, + { 213, 8339, "Number 8, Green" }, + { 216, 8340, "Number 9, Green" }, + { 170, 8301, "Oval, Green" }, + { 173, 8304, "Rectangle, Green" }, + { 219, 8352, "Triangle, Green" }, + { -1, 16385, "Intersection" }, + { -1, 8201, "Intl freeway hwy" }, + { -1, 8202, "Intl national hwy" }, + { -1, 8361, "Italian food" }, + { -1, 8248, "Large exit without services" }, + { -1, 8247, "Large Ramp intersection" }, + { -1, 16399, "Localizer Outer Marker" }, + { -1, 16400, "Missed approach point" }, + { -1, 16386, "Non-directional beacon" }, + { -1, 168, "Null" }, + { -1, 180, "Open 24 Hours" }, + { -1, 8222, "Ramp intersection" }, + { 165, 8294, "Circle, Red" }, + { 176, 8309, "Letter A, Red" }, + { 179, 8310, "Letter B, Red" }, + { 182, 8311, "Letter C, Red" }, + { 185, 8312, "Letter D, Red" }, + { 188, 8321, "Number 0, Red" }, + { 191, 8322, "Number 1, Red" }, + { 194, 8323, "Number 2, Red" }, + { 197, 8324, "Number 3, Red" }, + { 200, 8325, "Number 4, Red" }, + { 203, 8326, "Number 5, Red" }, + { 206, 8327, "Number 6, Red" }, + { 209, 8328, "Number 7, Red" }, + { 212, 8329, "Number 8, Red" }, + { 215, 8330, "Number 9, Red" }, + { 169, 8300, "Oval, Red" }, + { 172, 8303, "Rectangle, Red" }, + { 220, 8353, "Triangle, Red" }, + { -1, 8362, "Seafood" }, + { -1, 8194, "State Hwy" }, + { -1, 8363, "Steak" }, + { -1, 8223, "Street Intersection" }, + { -1, 16401, "TACAN" }, + { -1, 183, "Tide/Current PRediction Station" }, + { -1, 191, "U Marina" }, + { -1, 8193, "US hwy" }, + { -1, 193, "U stump" }, + { -1, 16387, "VHF Omni-range" }, + { -1, 16397, "VOR-DME" }, + { -1, 16396, "VOR/TACAN" }, + + /* This block new on 1/15 from the Mapsource 6.12 beta */ + { 221, -1, "Contact, Blonde" }, + { 222, -1, "Contact, Clown" }, + { 223, -1, "Contact, Glasses" }, + { 224, -1, "Contact, Panda" }, + { 225, -1, "Multi-Cache" }, + { 226, -1, "Letterbox Cache" }, + { 227, -1, "Puzzle Cache" }, + { 228, -1, "Library" }, + { 229, -1, "Ground Transportation" }, + { 230, -1, "City Hall" }, + { 231, -1, "Winery" }, + { 232, -1, "ATV" }, + { 233, -1, "Big Game" }, + { 234, -1, "Blind" }, + { 235, -1, "Blood Trail" }, + { 236, -1, "Cover" }, + { 237, -1, "Covey" }, + { 238, -1, "Food Source" }, + { 239, -1, "Furbearer" }, + { 240, -1, "Lodge" }, + { 241, -1, "Small Game" }, + { 242, -1, "Animal Tracks" }, + { 243, -1, "Treed Quarry" }, + { 244, -1, "Tree Stand" }, + { 245, -1, "Truck" }, + { 246, -1, "Upland Game" }, + { 247, -1, "Waterfowl" }, + { 248, -1, "Water Source" }, + + + { -1, -1, NULL }, }; icon_mapping_t garmin_smart_icon_table[] = { - /* Additional (optional, activated with -Si) icons */ - { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ - { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ - { 86, 8217, "Multi-Cache" }, /* icon for "Stadium" */ - { 44, 157, "Unknown Cache" }, /* icon for "Information" */ - { 64, 178, "Locationless (Reverse) Cache" }, /* Icon for "Flag" */ - { 83, 8214, "Post Office" }, /* Icon for "Post Office" */ - { 47, 160, "Event Cache" }, /* Icon for "Event" */ - { 90, 8221, "Webcam Cache" }, /* Icon for "Live Theatre" */ - { -1, -1, NULL } + /* Additional (optional, activated with -Si) icons */ + { 92, 8227, "Micro-Cache" }, /* icon for "Toll Booth" */ + { 48, 161, "Virtual cache" }, /* icon for "Scenic Area" */ + { 86, 8217, "Multi-Cache" }, /* icon for "Stadium" */ + { 44, 157, "Unknown Cache" }, /* icon for "Information" */ + { 64, 178, "Locationless (Reverse) Cache" }, /* Icon for "Flag" */ + { 83, 8214, "Post Office" }, /* Icon for "Post Office" */ + { 47, 160, "Event Cache" }, /* Icon for "Event" */ + { 90, 8221, "Webcam Cache" }, /* Icon for "Live Theatre" */ + { -1, -1, NULL } }; /* ICAO coutry code table */ /* source: http://en.wikipedia.org/wiki/ICAO_airport_code */ -gt_country_code_t gt_country_codes[] = -{ - { "ZM,", "Mongolia" }, - { "ZK,", "North Korea" }, - { "Z*,", "China" }, - { "Y*,", "Australia" }, - { "WS,", "Singapore" }, - { "WM,", "Brunei/Malaysia" }, - { "WB,", "Malaysia" }, - { "WA,WI,WQ,WR,", "Indonesia" }, - { "VV,", "Vietnam" }, - { "VT,", "Thailand" }, - { "VR,", "Maldives" }, - { "VQ,", "Bhutan" }, - { "VN,", "Nepal" }, - { "VM,", "Macau" }, - { "VL,", "Laos" }, - { "VH,", "Hong Kong" }, - { "VG,", "Bangladesh" }, - { "VD,", "Kampuchea" }, - { "VC,", "Sri Lanka" }, - { "VB,VY,", "Myanmar/Burma" }, - { "VA,VE,VI,VO,", "India" }, - { "UR,", "Kazakhstan/Russia" }, - { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, - { "UM,", "Belorussia/Russia" }, - { "UK,", "Ukraine" }, - { "UB,", "Azerbaijan" }, - { "UA,", "Kazakhstan/Kirgizia" }, - { "U*,", "Russia" }, - { "TX,", "Bermuda" }, - { "TV,", "St Vincent and the Grenadines" }, - { "TU,", "British Virgin Islands" }, - { "TT,", "Trinidad and Tobago" }, - { "TR,", "Montserrat Island" }, - { "TQ,", "Anguilla" }, - { "TN,", "Aruba/Neth Antilles" }, - { "TL,", "St Lucia" }, - { "TK,", "St Kitts/Nevis Islands" }, - { "TJ,", "Puerto Rico" }, - { "TG,", "Grenada" }, - { "TF,", "Guadeloupe/Martinique" }, - { "TD,", "Dominica" }, - { "TB,", "Barbados" }, - { "TA,", "Antigua" }, - { "SY,", "Guyana" }, - { "SV,", "Venezuela" }, - { "SU,", "Uruguay" }, - { "SP,", "Peru" }, - { "SO,", "French Guiana" }, - { "SM,", "Suriname" }, - { "SL,", "Bolivia" }, - { "SK,", "Colombia/San Andres" }, - { "SG,", "Paraguay" }, - { "SF,", "Falkland Islands" }, - { "SE,", "Ecuador" }, - { "SC,", "Chile/Easter Island" }, - { "SB,SD,SN,SS,SW,", "Brazil" }, - { "SA,", "Argentina" }, - { "S1,", "Antarctica (Argentina/Chile)" }, - { "RP,", "Philippines" }, - { "RK,", "South Korea" }, - { "RJ,", "Japan" }, - { "RC,", "Taiwan" }, - { "PW,", "Wake Island" }, - { "PT,", "Caroline Islands/Micronesia/Palau" }, - { "PM,", "Midway Islands" }, - { "PK,", "Marshall Islands" }, - { "PJ,", "Johnston Atoll" }, - { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, - { "PC,", "Kiribati" }, - { "P", "Oakland Octa" }, - { "OY,", "Yemen Arab Rep" }, - { "OT,", "Qatar" }, - { "OS,", "Syria" }, - { "OR,", "Iraq" }, - { "OP,", "Pakistan" }, - { "OO,", "Oman" }, - { "OM,", "United Arab Emirates" }, - { "OL,", "Lebanon" }, - { "OK,", "Kuwait" }, - { "OJ,", "Jordan" }, - { "OI,", "Iran" }, - { "OE,", "Saudi Arabia" }, - { "OB,", "Bahrain" }, - { "OA,", "Afghanistan" }, - { "NZ,PL,", "New Zealand" }, - { "NW,", "New Caledonia" }, - { "NV,", "Vanuatu" }, - { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, - { "NS,", "American Samoa/Western Samoa" }, - { "NL,", "Futuna Island/Wallis Island" }, - { "NI,", "Niue" }, - { "NG,", "Kiribati/Tuvalu" }, - { "NF,", "Fiji Island/Tonga" }, - { "NC,", "Cook Islands" }, - { "MZ,", "Belize" }, - { "MY,", "Bahamas" }, - { "MW,", "Cayman Islands" }, - { "MU,", "Cuba" }, - { "MT,", "Haiti" }, - { "MS,", "El Salvador" }, - { "MR,", "Costa rica" }, - { "MP,", "Panama" }, - { "MN,", "Nicaragua" }, - { "MM,", "Mexico" }, - { "MK,", "Jamaica" }, - { "MI,TI,", "Virgin Islands (U.S.)" }, - { "MH,", "Honduras" }, - { "MG,", "Guatemala" }, - { "MD,", "Dominican Republic" }, - { "MB,", "Turks Island/Caicos Island" }, - { "LZ,", "Slovakia" }, - { "LY,", "Yugoslavia" }, - { "LX,", "Gibraltar" }, - { "LW,", "Macedonia" }, - { "LV,", "Gaza" }, - { "LU,", "Moldova" }, - { "LT,", "Turkey" }, - { "LS,", "Switzerland" }, - { "LR,", "Romania" }, - { "LQ,", "Bosnia-Herzegovina" }, - { "LP,", "Portugal/Azores/Madeira Islands" }, - { "LO,", "Austria" }, - { "LN,", "Monaco" }, - { "LM,", "Malta" }, - { "LL,", "Israel/Jerusalem" }, - { "LK,", "Czech" }, - { "LI,", "Italy" }, - { "LH,", "Hungary" }, - { "LG,", "Slovenia" }, - { "LG,", "Greece" }, - { "LF,", "France" }, - { "LF,", "Miquelon Island/St Pierre Island" }, - { "LE,", "Spain" }, - { "LD,", "Croatia" }, - { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, - { "LB,", "Bulgaria" }, - { "LA,", "Albania" }, - { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, - { "HU,", "Uganda" }, - { "HT,", "Tanzania" }, - { "HS,", "Sudan" }, - { "HR,", "Rwanda" }, - { "HL,", "Libya, Spa Jamahiriya" }, - { "HK,", "Kenya" }, - { "HH,", "Eritrea" }, - { "HE,", "Egypt" }, - { "HD,HF,", "Djibouti" }, - { "HC,", "Somalia" }, - { "HB,", "Burundi" }, - { "HA,", "Ethiopia" }, - { "GV,", "Cape Verde" }, - { "GU,", "Guinea Tepublic" }, - { "GQ,", "Mauritania" }, - { "GO,", "Senegal" }, - { "GM,", "Morocco/Ad Dakhla/La'Youn" }, - { "GL,", "Liberia" }, - { "GG,", "Guinea-Bissau" }, - { "GF,", "Sierra Leone" }, - { "GE,", "Melilla" }, - { "GC,", "Canary Island" }, - { "GB,", "Gambia" }, - { "GA,", "Mali" }, - { "FZ,", "Democratic Republic of Congo" }, - { "FY,", "Namibia" }, - { "FX,", "Lesotho" }, - { "FW,", "Malawi" }, - { "FV,", "Zimbabwe" }, - { "FT,", "Chad" }, - { "FS,", "Seychelles" }, - { "FQ,", "Mozambique" }, - { "FP,", "Sao Tome & Principe" }, - { "FO,", "Gabon" }, - { "FN,", "Angola" }, - { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, - { "FL,", "Zambia" }, - { "FK,", "Cameroon" }, - { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, - { "FI,", "Mauritius" }, - { "FH,", "Ascension Island/St Helena Island" }, - { "FG,", "Equitorial Guinea" }, - { "FE,", "Central African Republic" }, - { "FD,", "Swaziland" }, - { "FC,", "Congo" }, - { "FB,", "Botswana" }, - { "FA,", "South African Republic" }, - { "EY,", "Lithuania" }, - { "EV,", "Latvia" }, - { "ES,", "Sweden" }, - { "EP,", "Poland" }, - { "EN,", "Norway" }, - { "EL,", "Luxembourg" }, - { "EK,", "Denmark/Faroe Island" }, - { "EI,", "Ireland" }, - { "EH,", "Netherlands" }, - { "EG,LX,", "United Kingdom" }, - { "EF,", "Finland" }, - { "EE,", "Estonia" }, - { "ED,ET,", "Germany" }, - { "EB,", "Belgium" }, - { "DX,", "Togo" }, - { "DT,", "Tunisia" }, - { "DR,", "Niger" }, - { "DN,", "Nigeria" }, - { "DI,", "Ivory Coast" }, - { "DG,", "Ghana" }, - { "DF,", "Burkina Faso" }, - { "DB,", "Benin" }, - { "DA,", "Algeria" }, - { "C*,", "Canada" }, - { "BI,", "Iceland" }, - { "BG,", "Greenland" }, - { "AY,", "Papua New Guinea" }, - { "AN,", "Nauru" }, - { "AG,", "Solomon Island" }, - { NULL, NULL } +gt_country_code_t gt_country_codes[] = { + { "ZM,", "Mongolia" }, + { "ZK,", "North Korea" }, + { "Z*,", "China" }, + { "Y*,", "Australia" }, + { "WS,", "Singapore" }, + { "WM,", "Brunei/Malaysia" }, + { "WB,", "Malaysia" }, + { "WA,WI,WQ,WR,", "Indonesia" }, + { "VV,", "Vietnam" }, + { "VT,", "Thailand" }, + { "VR,", "Maldives" }, + { "VQ,", "Bhutan" }, + { "VN,", "Nepal" }, + { "VM,", "Macau" }, + { "VL,", "Laos" }, + { "VH,", "Hong Kong" }, + { "VG,", "Bangladesh" }, + { "VD,", "Kampuchea" }, + { "VC,", "Sri Lanka" }, + { "VB,VY,", "Myanmar/Burma" }, + { "VA,VE,VI,VO,", "India" }, + { "UR,", "Kazakhstan/Russia" }, + { "UT,", "Kazakhstan/Tadzhikistan/Turkmenistan/Uzbekistan" }, + { "UM,", "Belorussia/Russia" }, + { "UK,", "Ukraine" }, + { "UB,", "Azerbaijan" }, + { "UA,", "Kazakhstan/Kirgizia" }, + { "U*,", "Russia" }, + { "TX,", "Bermuda" }, + { "TV,", "St Vincent and the Grenadines" }, + { "TU,", "British Virgin Islands" }, + { "TT,", "Trinidad and Tobago" }, + { "TR,", "Montserrat Island" }, + { "TQ,", "Anguilla" }, + { "TN,", "Aruba/Neth Antilles" }, + { "TL,", "St Lucia" }, + { "TK,", "St Kitts/Nevis Islands" }, + { "TJ,", "Puerto Rico" }, + { "TG,", "Grenada" }, + { "TF,", "Guadeloupe/Martinique" }, + { "TD,", "Dominica" }, + { "TB,", "Barbados" }, + { "TA,", "Antigua" }, + { "SY,", "Guyana" }, + { "SV,", "Venezuela" }, + { "SU,", "Uruguay" }, + { "SP,", "Peru" }, + { "SO,", "French Guiana" }, + { "SM,", "Suriname" }, + { "SL,", "Bolivia" }, + { "SK,", "Colombia/San Andres" }, + { "SG,", "Paraguay" }, + { "SF,", "Falkland Islands" }, + { "SE,", "Ecuador" }, + { "SC,", "Chile/Easter Island" }, + { "SB,SD,SN,SS,SW,", "Brazil" }, + { "SA,", "Argentina" }, + { "S1,", "Antarctica (Argentina/Chile)" }, + { "RP,", "Philippines" }, + { "RK,", "South Korea" }, + { "RJ,", "Japan" }, + { "RC,", "Taiwan" }, + { "PW,", "Wake Island" }, + { "PT,", "Caroline Islands/Micronesia/Palau" }, + { "PM,", "Midway Islands" }, + { "PK,", "Marshall Islands" }, + { "PJ,", "Johnston Atoll" }, + { "PG,", "Guam/Mariana Islands/Northern Mariana Islands" }, + { "PC,", "Kiribati" }, + { "P", "Oakland Octa" }, + { "OY,", "Yemen Arab Rep" }, + { "OT,", "Qatar" }, + { "OS,", "Syria" }, + { "OR,", "Iraq" }, + { "OP,", "Pakistan" }, + { "OO,", "Oman" }, + { "OM,", "United Arab Emirates" }, + { "OL,", "Lebanon" }, + { "OK,", "Kuwait" }, + { "OJ,", "Jordan" }, + { "OI,", "Iran" }, + { "OE,", "Saudi Arabia" }, + { "OB,", "Bahrain" }, + { "OA,", "Afghanistan" }, + { "NZ,PL,", "New Zealand" }, + { "NW,", "New Caledonia" }, + { "NV,", "Vanuatu" }, + { "NT,", "French Polynesia/Society Islands/Tuamotu Islands" }, + { "NS,", "American Samoa/Western Samoa" }, + { "NL,", "Futuna Island/Wallis Island" }, + { "NI,", "Niue" }, + { "NG,", "Kiribati/Tuvalu" }, + { "NF,", "Fiji Island/Tonga" }, + { "NC,", "Cook Islands" }, + { "MZ,", "Belize" }, + { "MY,", "Bahamas" }, + { "MW,", "Cayman Islands" }, + { "MU,", "Cuba" }, + { "MT,", "Haiti" }, + { "MS,", "El Salvador" }, + { "MR,", "Costa rica" }, + { "MP,", "Panama" }, + { "MN,", "Nicaragua" }, + { "MM,", "Mexico" }, + { "MK,", "Jamaica" }, + { "MI,TI,", "Virgin Islands (U.S.)" }, + { "MH,", "Honduras" }, + { "MG,", "Guatemala" }, + { "MD,", "Dominican Republic" }, + { "MB,", "Turks Island/Caicos Island" }, + { "LZ,", "Slovakia" }, + { "LY,", "Yugoslavia" }, + { "LX,", "Gibraltar" }, + { "LW,", "Macedonia" }, + { "LV,", "Gaza" }, + { "LU,", "Moldova" }, + { "LT,", "Turkey" }, + { "LS,", "Switzerland" }, + { "LR,", "Romania" }, + { "LQ,", "Bosnia-Herzegovina" }, + { "LP,", "Portugal/Azores/Madeira Islands" }, + { "LO,", "Austria" }, + { "LN,", "Monaco" }, + { "LM,", "Malta" }, + { "LL,", "Israel/Jerusalem" }, + { "LK,", "Czech" }, + { "LI,", "Italy" }, + { "LH,", "Hungary" }, + { "LG,", "Slovenia" }, + { "LG,", "Greece" }, + { "LF,", "France" }, + { "LF,", "Miquelon Island/St Pierre Island" }, + { "LE,", "Spain" }, + { "LD,", "Croatia" }, + { "LC,", "Cyprus/Turkey (Northern Cyprus)" }, + { "LB,", "Bulgaria" }, + { "LA,", "Albania" }, + { "K*,X*,PA,PB,PF,PJ,PL,PM,PO,PP,PH,PW,", "United States of America" }, + { "HU,", "Uganda" }, + { "HT,", "Tanzania" }, + { "HS,", "Sudan" }, + { "HR,", "Rwanda" }, + { "HL,", "Libya, Spa Jamahiriya" }, + { "HK,", "Kenya" }, + { "HH,", "Eritrea" }, + { "HE,", "Egypt" }, + { "HD,HF,", "Djibouti" }, + { "HC,", "Somalia" }, + { "HB,", "Burundi" }, + { "HA,", "Ethiopia" }, + { "GV,", "Cape Verde" }, + { "GU,", "Guinea Tepublic" }, + { "GQ,", "Mauritania" }, + { "GO,", "Senegal" }, + { "GM,", "Morocco/Ad Dakhla/La'Youn" }, + { "GL,", "Liberia" }, + { "GG,", "Guinea-Bissau" }, + { "GF,", "Sierra Leone" }, + { "GE,", "Melilla" }, + { "GC,", "Canary Island" }, + { "GB,", "Gambia" }, + { "GA,", "Mali" }, + { "FZ,", "Democratic Republic of Congo" }, + { "FY,", "Namibia" }, + { "FX,", "Lesotho" }, + { "FW,", "Malawi" }, + { "FV,", "Zimbabwe" }, + { "FT,", "Chad" }, + { "FS,", "Seychelles" }, + { "FQ,", "Mozambique" }, + { "FP,", "Sao Tome & Principe" }, + { "FO,", "Gabon" }, + { "FN,", "Angola" }, + { "FM,", "Madagascar/Comoros/Reunion/Mayotte Islands" }, + { "FL,", "Zambia" }, + { "FK,", "Cameroon" }, + { "FJ,", "Chagos Archipelago/British Indian Ocean Territory" }, + { "FI,", "Mauritius" }, + { "FH,", "Ascension Island/St Helena Island" }, + { "FG,", "Equitorial Guinea" }, + { "FE,", "Central African Republic" }, + { "FD,", "Swaziland" }, + { "FC,", "Congo" }, + { "FB,", "Botswana" }, + { "FA,", "South African Republic" }, + { "EY,", "Lithuania" }, + { "EV,", "Latvia" }, + { "ES,", "Sweden" }, + { "EP,", "Poland" }, + { "EN,", "Norway" }, + { "EL,", "Luxembourg" }, + { "EK,", "Denmark/Faroe Island" }, + { "EI,", "Ireland" }, + { "EH,", "Netherlands" }, + { "EG,LX,", "United Kingdom" }, + { "EF,", "Finland" }, + { "EE,", "Estonia" }, + { "ED,ET,", "Germany" }, + { "EB,", "Belgium" }, + { "DX,", "Togo" }, + { "DT,", "Tunisia" }, + { "DR,", "Niger" }, + { "DN,", "Nigeria" }, + { "DI,", "Ivory Coast" }, + { "DG,", "Ghana" }, + { "DF,", "Burkina Faso" }, + { "DB,", "Benin" }, + { "DA,", "Algeria" }, + { "C*,", "Canada" }, + { "BI,", "Iceland" }, + { "BG,", "Greenland" }, + { "AY,", "Papua New Guinea" }, + { "AN,", "Nauru" }, + { "AG,", "Solomon Island" }, + { NULL, NULL } }; /* gt_waypt_classes: gdb internal order */ char *gt_waypt_class_names[] = { - "User Waypoint", - "Airport", - "Intersection", - "NDB", - "VOR", - "Runway Threshold", - "Airport Intersection", - "Airport NDB", - "Map Point", - "Map Area", - "Map Intersection", - "Map Address", - "Map Line", - NULL + "User Waypoint", + "Airport", + "Intersection", + "NDB", + "VOR", + "Runway Threshold", + "Airport Intersection", + "Airport NDB", + "Map Point", + "Map Area", + "Map Intersection", + "Map Address", + "Map Line", + NULL }; /* gt_display_mode_names: this order is used by most devices */ char *gt_display_mode_names[] = { - "Symbol & Name", - "Symbol", - "Symbol & Description" + "Symbol & Name", + "Symbol", + "Symbol & Description" }; typedef struct { - const char *shortname; - const char *longname; - grid_type grid; + const char *shortname; + const char *longname; + grid_type grid; } grid_mapping_t; /* gt_mps_grid_names: !!! degree sign substituted with '*' !!! */ -grid_mapping_t gt_mps_grid_names[] = -{ - { "ddd", "Lat/Lon hddd.ddddd*", grid_lat_lon_ddd }, - { "dmm", "Lat/Lon hddd*mm.mmm'", grid_lat_lon_dmm }, - { "dms", "Lat/Lon hddd*mm'ss.s\"", grid_lat_lon_dms }, - { "bng", "British National Grid", grid_bng }, - { "utm", "UTM", grid_utm }, - { "swiss", "Swiss grid", grid_swiss }, - { NULL, NULL, 0 } +grid_mapping_t gt_mps_grid_names[] = { + { "ddd", "Lat/Lon hddd.ddddd*", grid_lat_lon_ddd }, + { "dmm", "Lat/Lon hddd*mm.mmm'", grid_lat_lon_dmm }, + { "dms", "Lat/Lon hddd*mm'ss.s\"", grid_lat_lon_dms }, + { "bng", "British National Grid", grid_bng }, + { "utm", "UTM", grid_utm }, + { "swiss", "Swiss grid", grid_swiss }, + { NULL, NULL, 0 } }; /* gt_mps_datum_names: */ typedef struct { - const char *jeeps_name; - const char *mps_name; + const char *jeeps_name; + const char *mps_name; } datum_mapping_t; -/* will be continued (when requested) */ -static datum_mapping_t gt_mps_datum_names[] = -{ - { "Alaska-NAD27", "NAD27 Alaska" }, - { "Bahamas NAD27", "NAD27 Bahamas" }, - { "Canada_Mean(NAD27)", "NAD27 Canada" }, - { "Canal_Zone_(NAD27)", "NAD27 Canal Zone" }, - { "Carribean NAD27", "NAD27 Caribbean" }, - { "Cent America NAD27", "NAD27 Central" }, - { "Cuba NAD27", "NAD27 Cuba" }, - { "Geodetic Datum 49", "Geodetic Datum '49" }, - { "Greenland NAD27", "NAD27 Greenland" }, - { "Mexico NAD27", "NAD27 Mexico" }, - { "North America 83", "NAD83" }, - { "OSGB36", "Ord Srvy Grt Britn" }, - { NULL, NULL } +/* will be continued (when requested) */ +static datum_mapping_t gt_mps_datum_names[] = { + { "Alaska-NAD27", "NAD27 Alaska" }, + { "Bahamas NAD27", "NAD27 Bahamas" }, + { "Canada_Mean(NAD27)", "NAD27 Canada" }, + { "Canal_Zone_(NAD27)", "NAD27 Canal Zone" }, + { "Carribean NAD27", "NAD27 Caribbean" }, + { "Cent America NAD27", "NAD27 Central" }, + { "Cuba NAD27", "NAD27 Cuba" }, + { "Geodetic Datum 49", "Geodetic Datum '49" }, + { "Greenland NAD27", "NAD27 Greenland" }, + { "Mexico NAD27", "NAD27 Mexico" }, + { "North America 83", "NAD83" }, + { "OSGB36", "Ord Srvy Grt Britn" }, + { NULL, NULL } }; typedef struct garmin_color_s { - const char *name; - gbint32 rgb; + const char *name; + gbint32 rgb; } garmin_color_t; -static garmin_color_t gt_colors[] = -{ - { "Unknown", unknown_color }, - { "Black", 0x000000 }, - { "DarkRed", 0x00008B }, - { "DarkGreen", 0x006400 }, - { "DarkYellow", 0x008B8B }, - { "DarkBlue", 0x8B0000 }, - { "DarkMagenta", 0x8B008B }, - { "DarkCyan", 0x8B8B00 }, - { "LightGray", 0xD3D3D3 }, - { "DarkGray", 0xA9A9A9 }, - { "Red", 0x0000FF }, - { "Green", 0x008000 }, - { "Yellow", 0x00FFFF }, - { "Blue", 0xFF0000 }, - { "Magenta", 0xFF00FF }, - { "Cyan", 0xFFFF00 }, - { "White", 0xFFFFFF }, - { "Transparent", unknown_color }, /* Currently not handled */ - { NULL } +static garmin_color_t gt_colors[] = { + { "Unknown", unknown_color }, + { "Black", 0x000000 }, + { "DarkRed", 0x00008B }, + { "DarkGreen", 0x006400 }, + { "DarkYellow", 0x008B8B }, + { "DarkBlue", 0x8B0000 }, + { "DarkMagenta", 0x8B008B }, + { "DarkCyan", 0x8B8B00 }, + { "LightGray", 0xD3D3D3 }, + { "DarkGray", 0xA9A9A9 }, + { "Red", 0x0000FF }, + { "Green", 0x008000 }, + { "Yellow", 0x00FFFF }, + { "Blue", 0xFF0000 }, + { "Magenta", 0xFF00FF }, + { "Cyan", 0xFFFF00 }, + { "White", 0xFFFFFF }, + { "Transparent", unknown_color }, /* Currently not handled */ + { NULL } }; #define GT_COLORS_CT ((sizeof(gt_colors) / sizeof(gt_colors[0])) - 1) @@ -679,408 +675,457 @@ static garmin_color_t gt_colors[] = unsigned char gt_switch_display_mode_value(const unsigned char display_mode, const int protoid, const char device) { - if (device) { - switch(protoid) { - - case 103: - case 107: - case 108: - case 109: - case 110: return display_mode & 3; - case 104: - switch(display_mode) { - case 0: - case 1: return gt_display_mode_symbol; - case 3: return gt_display_mode_symbol_and_name; - case 5: return gt_display_mode_symbol_and_comment; - } - case 155: - switch(display_mode) { - case 1: return gt_display_mode_symbol; - case 3: return gt_display_mode_symbol_and_name; - case 5: return gt_display_mode_symbol_and_comment; - } - } - return gt_display_mode_symbol_and_name; - } else { - switch(protoid) { - - case 103: - case 107: - case 108: - case 109: - case 110: return display_mode & 3; - case 104: - case 155: - switch(display_mode) { - case gt_display_mode_symbol: return 1; - case gt_display_mode_symbol_and_name: return 3; - case gt_display_mode_symbol_and_comment: return 5; - } - } - return 0; - } + if (device) { + switch (protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: + return display_mode & 3; + case 104: + switch (display_mode) { + case 0: + case 1: + return gt_display_mode_symbol; + case 3: + return gt_display_mode_symbol_and_name; + case 5: + return gt_display_mode_symbol_and_comment; + } + case 155: + switch (display_mode) { + case 1: + return gt_display_mode_symbol; + case 3: + return gt_display_mode_symbol_and_name; + case 5: + return gt_display_mode_symbol_and_comment; + } + } + return gt_display_mode_symbol_and_name; + } else { + switch (protoid) { + + case 103: + case 107: + case 108: + case 109: + case 110: + return display_mode & 3; + case 104: + case 155: + switch (display_mode) { + case gt_display_mode_symbol: + return 1; + case gt_display_mode_symbol_and_name: + return 3; + case gt_display_mode_symbol_and_comment: + return 5; + } + } + return 0; + } } char * gt_find_desc_from_icon_number(const int icon, garmin_formats_e garmin_format, int *dynamic) { - icon_mapping_t *i; - char custom[] = "Custom 63 "; - - if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) - { - snprintf(custom, sizeof(custom), "Custom %d", icon - 500); - *dynamic = 1; - return xstrdup(custom); - } - - if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { - snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); - *dynamic = 1; - return xstrdup(custom); - } - - if (dynamic) *dynamic = 0; - - for (i = garmin_icon_table; i->icon; i++) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - if (icon == i->mpssymnum) - return (char *)i->icon; - break; - case PCX: - case GARMIN_SERIAL: - if (icon == i->pcxsymnum) - return (char *)i->icon; - break; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - return DEFAULT_ICON_DESCR; + icon_mapping_t *i; + char custom[] = "Custom 63 "; + + if ((garmin_format == GDB) && (icon >= 500) && (icon <= 563)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 500); + *dynamic = 1; + return xstrdup(custom); + } + + if ((garmin_format == PCX) && (icon >= 7680) && (icon <= 8191)) { + snprintf(custom, sizeof(custom), "Custom %d", icon - 7680); + *dynamic = 1; + return xstrdup(custom); + } + + if (dynamic) { + *dynamic = 0; + } + + for (i = garmin_icon_table; i->icon; i++) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + if (icon == i->mpssymnum) { + return (char *)i->icon; + } + break; + case PCX: + case GARMIN_SERIAL: + if (icon == i->pcxsymnum) { + return (char *)i->icon; + } + break; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + return DEFAULT_ICON_DESCR; } int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_format) { - static int find_flag = 0; - icon_mapping_t *i; - int def_icon = DEFAULT_ICON_VALUE; - int n; - - if (!desc) - return def_icon; - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { - int base = 0; - if (garmin_format == GDB) base = 500; - if (garmin_format == PCX) base = 7680; - if (base) { - n = atoi(&desc[7]); - return n + base; - } - } - - for (i = garmin_smart_icon_table; global_opts.smart_icons && i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - for (i = garmin_icon_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - switch (garmin_format) { - case MAPSOURCE: - case GDB: - return i->mpssymnum; - case PCX: - case GARMIN_SERIAL: - return i->pcxsymnum; - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - } - } - - /* - * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" - * "find_flag" prevents us from a possible endless loop - */ - - if (find_flag == 0) - { - char **prefix; - char *prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; - - for (prefix = prefixes; *prefix != NULL; prefix++) - { - int len = strlen(*prefix); - - if (case_ignore_strncmp(desc, *prefix, len) == 0) - { - char buff[64]; - int result; - - snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); - rtrim(buff); - - find_flag = 1; - result = gt_find_icon_number_from_desc(buff, garmin_format); - find_flag = 0; - - return result; - } - } - } - return def_icon; + static int find_flag = 0; + icon_mapping_t *i; + int def_icon = DEFAULT_ICON_VALUE; + int n; + + if (!desc) { + return def_icon; + } + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + if (0 == case_ignore_strncmp(desc, "Custom ", 7)) { + int base = 0; + if (garmin_format == GDB) { + base = 500; + } + if (garmin_format == PCX) { + base = 7680; + } + if (base) { + n = atoi(&desc[7]); + return n + base; + } + } + + for (i = garmin_smart_icon_table; global_opts.smart_icons && i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + for (i = garmin_icon_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + switch (garmin_format) { + case MAPSOURCE: + case GDB: + return i->mpssymnum; + case PCX: + case GARMIN_SERIAL: + return i->pcxsymnum; + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + } + } + + /* + * try to handle some complex icon names: i.e. "Blue Diamond" and "Diamond, Blue" + * "find_flag" prevents us from a possible endless loop + */ + + if (find_flag == 0) { + char **prefix; + char *prefixes[] = {"White ", "Red ", "Green ", "Blue ", "Black ", NULL}; + + for (prefix = prefixes; *prefix != NULL; prefix++) { + int len = strlen(*prefix); + + if (case_ignore_strncmp(desc, *prefix, len) == 0) { + char buff[64]; + int result; + + snprintf(buff, sizeof(buff), "%s, %s", &desc[len], *prefix); + rtrim(buff); + + find_flag = 1; + result = gt_find_icon_number_from_desc(buff, garmin_format); + find_flag = 0; + + return result; + } + } + } + return def_icon; } const char * gt_get_icao_country(const char *cc) { - gt_country_code_t *x = >_country_codes[0]; - - if ((cc == NULL) || (*cc == '\0')) return NULL; - - do { - const char *ccx = x->cc; - while (ccx != NULL) { - if (strncmp(ccx, cc, 2) == 0) return x->country; - if ((ccx[0] == cc[0]) && (ccx[1] == '*')) return x->country; - ccx = strchr(ccx, ','); - if (ccx == NULL) break; - ccx++; - } - x++; - } while (x->cc != NULL); - return NULL; + gt_country_code_t *x = >_country_codes[0]; + + if ((cc == NULL) || (*cc == '\0')) { + return NULL; + } + + do { + const char *ccx = x->cc; + while (ccx != NULL) { + if (strncmp(ccx, cc, 2) == 0) { + return x->country; + } + if ((ccx[0] == cc[0]) && (ccx[1] == '*')) { + return x->country; + } + ccx = strchr(ccx, ','); + if (ccx == NULL) { + break; + } + ccx++; + } + x++; + } while (x->cc != NULL); + return NULL; } const char * gt_get_icao_cc(const char *country, const char *shortname) { - static char res[3]; - gt_country_code_t *x = >_country_codes[0]; - - if ((country == NULL) || (*country == '\0')) { - const char *test; - if (shortname == NULL) return NULL; - switch(strlen(shortname)) { - case 3: strncpy(res, shortname, 1); break; - case 4: strncpy(res, shortname, 2); break; - default: return NULL; - } - test = gt_get_icao_country(res); - if (test != NULL) - return res; - else - return NULL; - } - - do { - if (case_ignore_strcmp(country, x->country) != 0) { - x++; - continue; - } - - if (strlen(x->cc) <= 3) { - strncpy(res, x->cc, 3); - if (res[1] == '*') - res[1] = '\0'; - else - res[2] = '\0'; - return res; - } - if (shortname && (strlen(shortname) == 4)) { - const char *ccx = x->cc; - - strncpy(res, shortname, 2); - res[2] = '\0'; - while (ccx != NULL) { - if (strncmp(ccx, res, 2) == 0) return res; - if ((ccx[0] == res[0]) && (ccx[1] == '*')) return res; - ccx = strchr(ccx, ','); - if (ccx == NULL) break; - ccx++; - } - } - return NULL; - } while (x->country != NULL); - return NULL; + static char res[3]; + gt_country_code_t *x = >_country_codes[0]; + + if ((country == NULL) || (*country == '\0')) { + const char *test; + if (shortname == NULL) { + return NULL; + } + switch (strlen(shortname)) { + case 3: + strncpy(res, shortname, 1); + break; + case 4: + strncpy(res, shortname, 2); + break; + default: + return NULL; + } + test = gt_get_icao_country(res); + if (test != NULL) { + return res; + } else { + return NULL; + } + } + + do { + if (case_ignore_strcmp(country, x->country) != 0) { + x++; + continue; + } + + if (strlen(x->cc) <= 3) { + strncpy(res, x->cc, 3); + if (res[1] == '*') { + res[1] = '\0'; + } else { + res[2] = '\0'; + } + return res; + } + if (shortname && (strlen(shortname) == 4)) { + const char *ccx = x->cc; + + strncpy(res, shortname, 2); + res[2] = '\0'; + while (ccx != NULL) { + if (strncmp(ccx, res, 2) == 0) { + return res; + } + if ((ccx[0] == res[0]) && (ccx[1] == '*')) { + return res; + } + ccx = strchr(ccx, ','); + if (ccx == NULL) { + break; + } + ccx++; + } + } + return NULL; + } while (x->country != NULL); + return NULL; } grid_type gt_lookup_grid_type(const char *grid_name, const char *module) { - grid_mapping_t *g; - - for (g = gt_mps_grid_names; (g->shortname); g++) { - if ((case_ignore_strcmp(grid_name, g->shortname) == 0) || - (case_ignore_strcmp(grid_name, g->longname) == 0)) - return g->grid; - } - - fatal("%s: Unsupported grid (%s)! See GPSBabel help for supported grids.\n", - module, grid_name); - - return grid_unknown; /* (warnings) */ + grid_mapping_t *g; + + for (g = gt_mps_grid_names; (g->shortname); g++) { + if ((case_ignore_strcmp(grid_name, g->shortname) == 0) || + (case_ignore_strcmp(grid_name, g->longname) == 0)) { + return g->grid; + } + } + + fatal("%s: Unsupported grid (%s)! See GPSBabel help for supported grids.\n", + module, grid_name); + + return grid_unknown; /* (warnings) */ } const char * gt_get_mps_grid_longname(const grid_type grid, const char *module) { - if ((grid < GRID_INDEX_MIN) || (grid > GRID_INDEX_MAX)) - fatal("%s: Grid index out of range %d (%d..%d)!", - module, (int) grid, - (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); - return gt_mps_grid_names[grid].longname; + if ((grid < GRID_INDEX_MIN) || (grid > GRID_INDEX_MAX)) + fatal("%s: Grid index out of range %d (%d..%d)!", + module, (int) grid, + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + return gt_mps_grid_names[grid].longname; } const char * gt_get_mps_datum_name(const int datum_index) { - char *result; - datum_mapping_t *d; - - result = GPS_Math_Get_Datum_Name(datum_index); + char *result; + datum_mapping_t *d; + + result = GPS_Math_Get_Datum_Name(datum_index); - for (d = gt_mps_datum_names; (d->jeeps_name); d++) - if (case_ignore_strcmp(result, d->jeeps_name) == 0) return d->mps_name; + for (d = gt_mps_datum_names; (d->jeeps_name); d++) + if (case_ignore_strcmp(result, d->jeeps_name) == 0) { + return d->mps_name; + } - return result; + return result; } int gt_lookup_datum_index(const char *datum_str, const char *module) { - datum_mapping_t *d; - int result; - const char *name = datum_str; - - for (d = gt_mps_datum_names; (d->jeeps_name); d++) { - if (case_ignore_strcmp(name, d->mps_name) == 0) { - name = d->jeeps_name; - break; - } - } - - result = GPS_Lookup_Datum_Index(name); - - if (result < 0) { - char *tmp; - xasprintf(&tmp, "%s mean", datum_str); - result = GPS_Lookup_Datum_Index(tmp); - xfree(tmp); - } - - is_fatal(result < 0, - "%s: Unsupported datum (%s)! See GPSBabel help for supported datums.", - module, datum_str); - - return result; + datum_mapping_t *d; + int result; + const char *name = datum_str; + + for (d = gt_mps_datum_names; (d->jeeps_name); d++) { + if (case_ignore_strcmp(name, d->mps_name) == 0) { + name = d->jeeps_name; + break; + } + } + + result = GPS_Lookup_Datum_Index(name); + + if (result < 0) { + char *tmp; + xasprintf(&tmp, "%s mean", datum_str); + result = GPS_Lookup_Datum_Index(tmp); + xfree(tmp); + } + + is_fatal(result < 0, + "%s: Unsupported datum (%s)! See GPSBabel help for supported datums.", + module, datum_str); + + return result; } gbuint32 gt_color_value(const int garmin_index) { - if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) - return gt_colors[garmin_index].rgb; - else - return unknown_color; /* -1 */ + if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) { + return gt_colors[garmin_index].rgb; + } else { + return unknown_color; /* -1 */ + } } gbuint32 gt_color_value_by_name(const char *name) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (case_ignore_strcmp(gt_colors[i].name, name) == 0) - return gt_colors[i].rgb; + for (i = 0; i < GT_COLORS_CT; i++) + if (case_ignore_strcmp(gt_colors[i].name, name) == 0) { + return gt_colors[i].rgb; + } - return gt_colors[0].rgb; + return gt_colors[0].rgb; } int gt_color_index_by_name(const char *name) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (case_ignore_strcmp(name, gt_colors[i].name) == 0) return i; + for (i = 0; i < GT_COLORS_CT; i++) + if (case_ignore_strcmp(name, gt_colors[i].name) == 0) { + return i; + } - return 0; /* unknown */ + return 0; /* unknown */ } int gt_color_index_by_rgb(const int rgb) { - int i; + int i; - for (i = 0; i < GT_COLORS_CT; i++) - if (rgb == gt_colors[i].rgb) return i; + for (i = 0; i < GT_COLORS_CT; i++) + if (rgb == gt_colors[i].rgb) { + return i; + } - return 0; /* unknown */ + return 0; /* unknown */ } const char * gt_color_name(const int garmin_index) { - if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) - return gt_colors[garmin_index].name; - else - return gt_colors[0].name; + if ((garmin_index >= 0) && (garmin_index < GT_COLORS_CT)) { + return gt_colors[garmin_index].name; + } else { + return gt_colors[0].name; + } } #if MAKE_TABLE /* - * Used to generate icon tables in appendix. + * Used to generate icon tables in appendix. * cc -DMAKE_TABLE garmin_tables.c fatal.o util.o globals.o -lm */ int cet_utf8_to_ucs4(const char *str, int *bytes, int *value) { - fatal("Should not be here."); + fatal("Should not be here."); } int sortem(const void *a, const void *b) { - const icon_mapping_t *aa = a; - const icon_mapping_t *bb = b; + const icon_mapping_t *aa = a; + const icon_mapping_t *bb = b; // return aa->mpssymnum - bb->mpssymnum; - return strcmp(aa->icon, bb->icon); + return strcmp(aa->icon, bb->icon); } main() { - icon_mapping_t *i; - qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); - for (i = garmin_icon_table; i->icon; i++) { + icon_mapping_t *i; + qsort(garmin_icon_table, sizeof(garmin_icon_table) / sizeof(garmin_icon_table[0]) - 1, sizeof(garmin_icon_table[0]), sortem); + for (i = garmin_icon_table; i->icon; i++) { // printf("%03d\t%s\n", i->mpssymnum, i->icon); - printf("%s\n", i->icon); - } + printf("%s\n", i->icon); + } } #endif diff --git a/gpsbabel/garmin_tables.h b/gpsbabel/garmin_tables.h index 0d2de7734..0fd88f0f9 100644 --- a/gpsbabel/garmin_tables.h +++ b/gpsbabel/garmin_tables.h @@ -29,9 +29,9 @@ #define DEFAULT_ICON_VALUE 18 typedef struct icon_mapping { - const int mpssymnum; - const int pcxsymnum; - const char *icon; + const int mpssymnum; + const int pcxsymnum; + const char *icon; } icon_mapping_t; typedef enum {MAPSOURCE, PCX, GARMIN_SERIAL, GDB} garmin_formats_e; @@ -42,27 +42,26 @@ int gt_find_icon_number_from_desc(const char *desc, garmin_formats_e garmin_form extern icon_mapping_t garmin_icon_table[]; typedef enum { - gt_waypt_class_user_waypoint = 0, - gt_waypt_class_airport, - gt_waypt_class_intersection, - gt_waypt_class_ndb, - gt_waypt_class_vor, - gt_waypt_class_runway_threshold, - gt_waypt_class_airport_intersection, - gt_waypt_class_airport_ndb, - gt_waypt_class_map_point, - gt_waypt_class_map_area, - gt_waypt_class_map_intersection, - gt_waypt_class_map_address, - gt_waypt_class_map_line + gt_waypt_class_user_waypoint = 0, + gt_waypt_class_airport, + gt_waypt_class_intersection, + gt_waypt_class_ndb, + gt_waypt_class_vor, + gt_waypt_class_runway_threshold, + gt_waypt_class_airport_intersection, + gt_waypt_class_airport_ndb, + gt_waypt_class_map_point, + gt_waypt_class_map_area, + gt_waypt_class_map_intersection, + gt_waypt_class_map_address, + gt_waypt_class_map_line } gt_waypt_classes_e; extern char *gt_waypt_class_names[]; -typedef struct gt_country_code_s -{ - const char *cc; - const char *country; +typedef struct gt_country_code_s { + const char *cc; + const char *country; } gt_country_code_t; extern gt_country_code_t gt_country_codes[]; @@ -72,20 +71,20 @@ const char *gt_get_icao_cc(const char *country, const char *shortname); /* this order is used by most devices */ typedef enum { - gt_display_mode_symbol_and_name = 0, - gt_display_mode_symbol, - gt_display_mode_symbol_and_comment + gt_display_mode_symbol_and_name = 0, + gt_display_mode_symbol, + gt_display_mode_symbol_and_comment } gt_display_modes_e; - + extern char *gt_display_mode_names[]; #define GT_DISPLAY_MODE_MIN gt_display_mode_symbol_and_name #define GT_DISPLAY_MODE_MAX gt_display_mode_symbol_and_comment typedef enum { - gt_gdb_display_mode_symbol = 0, - gt_gdb_display_mode_symbol_and_name, - gt_gdb_display_mode_symbol_and_comment + gt_gdb_display_mode_symbol = 0, + gt_gdb_display_mode_symbol_and_name, + gt_gdb_display_mode_symbol_and_comment } gt_gdb_display_modes_e; unsigned char gt_convert_category(const char *name, int *category); diff --git a/gpsbabel/garmin_txt.c b/gpsbabel/garmin_txt.c index 99748e96c..b6a3279c6 100644 --- a/gpsbabel/garmin_txt.c +++ b/gpsbabel/garmin_txt.c @@ -1,7 +1,7 @@ /* Support for MapSource Text Export (Tab delimited) files. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #if CSVFMTS_ENABLED @@ -40,12 +40,12 @@ #define MYNAME "garmin_txt" typedef struct gtxt_flags_s { - unsigned int metric:1; - unsigned int celsius:1; - unsigned int utc:1; - unsigned int enum_waypoints:1; - unsigned int route_header_written:1; - unsigned int track_header_written:1; + unsigned int metric:1; + unsigned int celsius:1; + unsigned int utc:1; + unsigned int enum_waypoints:1; + unsigned int route_header_written:1; + unsigned int track_header_written:1; } gtxt_flags_t; static gbfile *fin, *fout; @@ -65,12 +65,12 @@ static time_t utc_offs = 0; static gtxt_flags_t gtxt_flags; typedef enum { - waypt_header = 0, - rtept_header, - trkpt_header, - route_header, - track_header, - unknown_header + waypt_header = 0, + rtept_header, + trkpt_header, + route_header, + track_header, + unknown_header } header_type; #define MAX_HEADER_FIELDS 36 @@ -100,28 +100,27 @@ static char *opt_grid = NULL; static arglist_t garmin_txt_args[] = { - {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, - {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, - {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, - {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, - {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, - ARG_TERMINATOR + {"date", &opt_date_format, "Read/Write date format (i.e. yyyy/mm/dd)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"datum", &opt_datum, "GPS datum (def. WGS 84)", "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, + {"dist", &opt_dist, "Distance unit [m=metric, s=statute]", "m", ARGTYPE_STRING, ARG_NOMINMAX}, + {"grid", &opt_grid, "Write position using this grid.", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"prec", &opt_precision, "Precision of coordinates", "3", ARGTYPE_INT, ARG_NOMINMAX}, + {"temp", &opt_temp, "Temperature unit [c=Celsius, f=Fahrenheit]", "c", ARGTYPE_STRING, ARG_NOMINMAX}, + {"time", &opt_time_format, "Read/Write time format (i.e. HH:mm:ss xx)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"utc", &opt_utc, "Write timestamps with offset x to UTC time", NULL, ARGTYPE_INT, "-23", "+23"}, + ARG_TERMINATOR }; -typedef struct info_s -{ - double length; - time_t start; - time_t time; - double speed; - double total; - int count; - waypoint *prev_wpt; - waypoint *first_wpt; - waypoint *last_wpt; +typedef struct info_s { + double length; + time_t start; + time_t time; + double speed; + double total; + int count; + waypoint *prev_wpt; + waypoint *first_wpt; + waypoint *last_wpt; } info_t; static info_t *route_info; @@ -129,14 +128,14 @@ static int route_idx; static info_t *cur_info; static char *headers[] = { - "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" - "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" - "Date Modified\tLink\tCategories", - "Waypoint Name\tDistance\tLeg Length\tCourse", - "Position\tTime\tAltitude\tDepth\tTemperature\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", - "Name\tLength\tCourse\tWaypoints\tLink", - "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", - NULL + "Name\tDescription\tType\tPosition\tAltitude\tDepth\tProximity\tTemperature\t" + "Display Mode\tColor\tSymbol\tFacility\tCity\tState\tCountry\t" + "Date Modified\tLink\tCategories", + "Waypoint Name\tDistance\tLeg Length\tCourse", + "Position\tTime\tAltitude\tDepth\tTemperature\tLeg Length\tLeg Time\tLeg Speed\tLeg Course", + "Name\tLength\tCourse\tWaypoints\tLink", + "Name\tStart Time\tElapsed Time\tLength\tAverage Speed\tLink", + NULL }; /* helpers */ @@ -144,37 +143,36 @@ static char *headers[] = { static char * get_option_val(char *option, char *def) { - char *c = (option != NULL) ? option : def; - return c; + char *c = (option != NULL) ? option : def; + return c; } static void init_date_and_time_format(void) { - char *f, *c; - - f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); - date_time_format = convert_human_date_format(f); - - date_time_format = xstrappend(date_time_format, " "); - - f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); - c = convert_human_time_format(f); - date_time_format = xstrappend(date_time_format, c); - xfree(c); + char *f, *c; + + f = get_option_val(opt_date_format, DEFAULT_DATE_FORMAT); + date_time_format = convert_human_date_format(f); + + date_time_format = xstrappend(date_time_format, " "); + + f = get_option_val(opt_time_format, DEFAULT_TIME_FORMAT); + c = convert_human_time_format(f); + date_time_format = xstrappend(date_time_format, c); + xfree(c); } static void convert_datum(const waypoint *wpt, double *dest_lat, double *dest_lon) { - double alt; - - if (datum_index == DATUM_WGS84 ) { - *dest_lat = wpt->latitude; - *dest_lon = wpt->longitude; - } - else GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, - dest_lat, dest_lon, &alt, datum_index); + double alt; + + if (datum_index == DATUM_WGS84) { + *dest_lat = wpt->latitude; + *dest_lon = wpt->longitude; + } else GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + dest_lat, dest_lon, &alt, datum_index); } /* WRITER *****************************************************************/ @@ -184,42 +182,39 @@ convert_datum(const waypoint *wpt, double *dest_lat, double *dest_lon) static void enum_waypt_cb(const waypoint *wpt) { - garmin_fs_p gmsd; - int wpt_class; - - gmsd = GMSD_FIND(wpt); - wpt_class = GMSD_GET(wpt_class, 0); - if (wpt_class < 0x80) - { - int i; - - if (gtxt_flags.enum_waypoints) /* enumerate only */ - { - waypoints++; - return; - } - for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ - waypoint *tmp = wpt_a[i]; - if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) - { - wpt_a[i] = (waypoint *)wpt; - waypoints--; - return; - - } - } - wpt_a[wpt_a_ct++] = (waypoint *)wpt; - } + garmin_fs_p gmsd; + int wpt_class; + + gmsd = GMSD_FIND(wpt); + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class < 0x80) { + int i; + + if (gtxt_flags.enum_waypoints) { /* enumerate only */ + waypoints++; + return; + } + for (i = 0; i < wpt_a_ct; i++) { /* check for duplicates */ + waypoint *tmp = wpt_a[i]; + if (case_ignore_strcmp(tmp->shortname, wpt->shortname) == 0) { + wpt_a[i] = (waypoint *)wpt; + waypoints--; + return; + + } + } + wpt_a[wpt_a_ct++] = (waypoint *)wpt; + } } static int sort_waypt_cb(const void *a, const void *b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; - return case_ignore_strcmp(wa->shortname, wb->shortname); + return case_ignore_strcmp(wa->shortname, wb->shortname); } @@ -228,35 +223,34 @@ sort_waypt_cb(const void *a, const void *b) static void prework_hdr_cb(const route_head *rte) { - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->length = 0; - cur_info->time = 0; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->length = 0; + cur_info->time = 0; } static void prework_tlr_cb(const route_head *rte) { - cur_info->last_wpt = cur_info->prev_wpt; - route_idx++; + cur_info->last_wpt = cur_info->prev_wpt; + route_idx++; } static void prework_wpt_cb(const waypoint *wpt) { - waypoint *prev = cur_info->prev_wpt; - - if (prev != NULL) { - cur_info->time += (wpt->creation_time - prev->creation_time); - cur_info->length += waypt_distance_ex(prev, wpt); - } - else { - cur_info->first_wpt = (waypoint *)wpt; - cur_info->start = wpt->creation_time; - } - cur_info->prev_wpt = (waypoint *)wpt; - cur_info->count++; - routepoints++; + waypoint *prev = cur_info->prev_wpt; + + if (prev != NULL) { + cur_info->time += (wpt->creation_time - prev->creation_time); + cur_info->length += waypt_distance_ex(prev, wpt); + } else { + cur_info->first_wpt = (waypoint *)wpt; + cur_info->start = wpt->creation_time; + } + cur_info->prev_wpt = (waypoint *)wpt; + cur_info->count++; + routepoints++; } @@ -265,240 +259,255 @@ prework_wpt_cb(const waypoint *wpt) static void print_position(const waypoint *wpt) { - int valid = 1; - double lat, lon, north, east; - char latsig, lonsig; - double latmin, lonmin, latsec, lonsec; - int latint, lonint, zone; - char map[3], zonec; - - convert_datum(wpt, &lat, &lon); - - /* ----------------------------------------------------------------------------*/ - /* the following code is from pretty_deg_format (util.c) */ - /* ----------------------------------------------------------------------------*/ - /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ - /* ----------------------------------------------------------------------------*/ - - latsig = lat < 0 ? 'S':'N'; - lonsig = lon < 0 ? 'W':'E'; - latint = abs((int) lat); - lonint = abs((int) lon); - latmin = 60.0 * (fabs(lat) - latint); - lonmin = 60.0 * (fabs(lon) - lonint); - latsec = 60.0 * (latmin - floor(latmin)); - lonsec = 60.0 * (lonmin - floor(lonmin)); - - switch(grid_index) { - - case grid_lat_lon_ddd: - - gbfprintf(fout, "%c%0.*f %c%0.*f\t", - latsig, precision, fabs(lat), - lonsig, precision, fabs(lon)); - break; - - case grid_lat_lon_dmm: - - gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", - latsig, latint, precision + 3, precision, latmin, - lonsig, lonint, precision + 3, precision, lonmin); - break; - - case grid_lat_lon_dms: - - gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", - latsig, latint, (int)latmin, precision, latsec, - lonsig, lonint, (int)lonmin, precision, lonsec); - break; - - case grid_bng: - - valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); - if (valid) gbfprintf(fout, "%s %5.0f %5.0f\t", map, east, north); - break; - - case grid_utm: - - valid = GPS_Math_Known_Datum_To_UTM_EN(lat, lon, - &east, &north, &zone, &zonec, datum_index); - if (valid) gbfprintf(fout, "%02d %c %.0f %.0f\t", zone, zonec, east, north); - break; - - case grid_swiss: - - valid = GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north); - if (valid) gbfprintf(fout, "%.f %.f\t", east, north); - break; - - default: - fatal("ToDo\n"); - } - - if (! valid) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", - wpt->shortname ? wpt->shortname : "Waypoint", - pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), - gt_get_mps_grid_longname(grid_index, MYNAME)); - } + int valid = 1; + double lat, lon, north, east; + char latsig, lonsig; + double latmin, lonmin, latsec, lonsec; + int latint, lonint, zone; + char map[3], zonec; + + convert_datum(wpt, &lat, &lon); + + /* ----------------------------------------------------------------------------*/ + /* the following code is from pretty_deg_format (util.c) */ + /* ----------------------------------------------------------------------------*/ + /* !ToDo! generate common code for calculating of degrees, minutes and seconds */ + /* ----------------------------------------------------------------------------*/ + + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + switch (grid_index) { + + case grid_lat_lon_ddd: + + gbfprintf(fout, "%c%0.*f %c%0.*f\t", + latsig, precision, fabs(lat), + lonsig, precision, fabs(lon)); + break; + + case grid_lat_lon_dmm: + + gbfprintf(fout, "%c%d %0*.*f %c%d %0*.*f\t", + latsig, latint, precision + 3, precision, latmin, + lonsig, lonint, precision + 3, precision, lonmin); + break; + + case grid_lat_lon_dms: + + gbfprintf(fout, "%c%d %d %.*f %c%d %d %.*f\t", + latsig, latint, (int)latmin, precision, latsec, + lonsig, lonint, (int)lonmin, precision, lonsec); + break; + + case grid_bng: + + valid = GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map); + if (valid) { + gbfprintf(fout, "%s %5.0f %5.0f\t", map, east, north); + } + break; + + case grid_utm: + + valid = GPS_Math_Known_Datum_To_UTM_EN(lat, lon, + &east, &north, &zone, &zonec, datum_index); + if (valid) { + gbfprintf(fout, "%02d %c %.0f %.0f\t", zone, zonec, east, north); + } + break; + + case grid_swiss: + + valid = GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north); + if (valid) { + gbfprintf(fout, "%.f %.f\t", east, north); + } + break; + + default: + fatal("ToDo\n"); + } + + if (! valid) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_index, MYNAME)); + } } static void print_date_and_time(const time_t time, const int time_only) { - struct tm tm; - char tbuf[32]; - - if (time < 0) { - gbfprintf(fout, "\t"); - return; - } - if (time_only) { - tm = *gmtime(&time); - snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); - gbfprintf(fout, "%s", tbuf); - } - else if (time != 0) { - if (gtxt_flags.utc) { - time_t t = time + utc_offs; - tm = *gmtime(&t); - } - else - tm = *localtime(&time); - strftime(tbuf, sizeof(tbuf), date_time_format, &tm); - gbfprintf(fout, "%s ", tbuf); - } - gbfprintf(fout, "\t"); + struct tm tm; + char tbuf[32]; + + if (time < 0) { + gbfprintf(fout, "\t"); + return; + } + if (time_only) { + tm = *gmtime(&time); + snprintf(tbuf, sizeof(tbuf), "%d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + gbfprintf(fout, "%s", tbuf); + } else if (time != 0) { + if (gtxt_flags.utc) { + time_t t = time + utc_offs; + tm = *gmtime(&t); + } else { + tm = *localtime(&time); + } + strftime(tbuf, sizeof(tbuf), date_time_format, &tm); + gbfprintf(fout, "%s ", tbuf); + } + gbfprintf(fout, "\t"); } static void print_categories(gbuint16 categories) { - int i, count; - char *c; - - if (categories == 0) return; - - count = 0; - for (i = 0; i < 16; i++) { - if ((categories & 1) != 0) { - if (global_opts.inifile != NULL) { - char key[3]; - snprintf(key, sizeof(key), "%d", i + 1); - c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); - } - else c = NULL; - - gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); - if (c == NULL) - gbfprintf(fout, "Category %d", i+1); + int i, count; + char *c; + + if (categories == 0) { + return; + } + + count = 0; + for (i = 0; i < 16; i++) { + if ((categories & 1) != 0) { + if (global_opts.inifile != NULL) { + char key[3]; + snprintf(key, sizeof(key), "%d", i + 1); + c = inifile_readstr(global_opts.inifile, GMSD_SECTION_CATEGORIES, key); + } else { + c = NULL; + } + + gbfprintf(fout, "%s", (count++ > 0) ? "," : ""); + if (c == NULL) { + gbfprintf(fout, "Category %d", i+1); + } // gbfprintf(fout, "%s", gps_categories[i]); - else - gbfprintf(fout, "%s", c); - - } - categories = categories >> 1; - } + else { + gbfprintf(fout, "%s", c); + } + + } + categories = categories >> 1; + } } static void print_course(const waypoint *A, const waypoint *B) /* seems to be okay */ { - if ((A != NULL) && (B != NULL) && (A != B)) { - int course; - course = si_round(waypt_course(A, B)); - cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); - } + if ((A != NULL) && (B != NULL) && (A != B)) { + int course; + course = si_round(waypt_course(A, B)); + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "%d%c true", course, 0xB0); + } } static void print_distance(const double distance, const int no_scale, const int with_tab, const int decis) { - double dist = distance; - - if (gtxt_flags.metric == 0) { - dist = METERS_TO_FEET(dist); - - if ((dist < 5280) || no_scale) - gbfprintf(fout, "%.*f ft", decis, dist); - else { - dist = METERS_TO_MILES(distance); - if (dist < (double)100) - gbfprintf(fout, "%.1f mi", dist); - else - gbfprintf(fout, "%d mi", si_round(dist)); - } - } - else - { - if ((dist < 1000) || no_scale) - gbfprintf(fout, "%.*f m", decis, dist); - else { - dist = dist / (double)1000.0; - if (dist < (double)100) - gbfprintf(fout, "%.1f km", dist); - else - gbfprintf(fout, "%d km", si_round(dist)); - } - } - if (with_tab) gbfprintf(fout, "\t"); + double dist = distance; + + if (gtxt_flags.metric == 0) { + dist = METERS_TO_FEET(dist); + + if ((dist < 5280) || no_scale) { + gbfprintf(fout, "%.*f ft", decis, dist); + } else { + dist = METERS_TO_MILES(distance); + if (dist < (double)100) { + gbfprintf(fout, "%.1f mi", dist); + } else { + gbfprintf(fout, "%d mi", si_round(dist)); + } + } + } else { + if ((dist < 1000) || no_scale) { + gbfprintf(fout, "%.*f m", decis, dist); + } else { + dist = dist / (double)1000.0; + if (dist < (double)100) { + gbfprintf(fout, "%.1f km", dist); + } else { + gbfprintf(fout, "%d km", si_round(dist)); + } + } + } + if (with_tab) { + gbfprintf(fout, "\t"); + } } static void print_speed(double *distance, time_t *time) { - int idist; - double dist = *distance; - char *unit; - - if (!gtxt_flags.metric) { - dist = METERS_TO_MILES(dist) * 1000.0; - unit = "mph"; - } - else unit = "kph"; - idist = si_round(dist); - - if ((*time != 0) && (idist > 0)) { - double speed = MPS_TO_KPH(dist / (double)*time); - int ispeed = si_round(speed); - - if (speed < (double)0.01) - gbfprintf(fout, "0 %s", unit); - else if (ispeed < 2) - gbfprintf(fout, "%.1f %s", speed, unit); - else - gbfprintf(fout, "%d %s", ispeed, unit); - } - else - gbfprintf(fout, "0 %s", unit); - gbfprintf(fout, "\t"); + int idist; + double dist = *distance; + char *unit; + + if (!gtxt_flags.metric) { + dist = METERS_TO_MILES(dist) * 1000.0; + unit = "mph"; + } else { + unit = "kph"; + } + idist = si_round(dist); + + if ((*time != 0) && (idist > 0)) { + double speed = MPS_TO_KPH(dist / (double)*time); + int ispeed = si_round(speed); + + if (speed < (double)0.01) { + gbfprintf(fout, "0 %s", unit); + } else if (ispeed < 2) { + gbfprintf(fout, "%.1f %s", speed, unit); + } else { + gbfprintf(fout, "%d %s", ispeed, unit); + } + } else { + gbfprintf(fout, "0 %s", unit); + } + gbfprintf(fout, "\t"); } static void print_temperature(const float temperature) { - if (gtxt_flags.celsius) - gbfprintf(fout, "%.f C", temperature); - else - gbfprintf(fout, "%.f F", (temperature * 1.8) + 32); + if (gtxt_flags.celsius) { + gbfprintf(fout, "%.f C", temperature); + } else { + gbfprintf(fout, "%.f F", (temperature * 1.8) + 32); + } } static void print_string(const char *fmt, const char *string) { - char *c; - char *buff; - - buff = xstrdup(string); - /* remove unwanted characters from source string */ - for (c = buff; *c; c++) { - if (iscntrl(*c)) { - *c = ' '; - } - } - gbfprintf(fout, fmt, buff); - xfree(buff); + char *c; + char *buff; + + buff = xstrdup(string); + /* remove unwanted characters from source string */ + for (c = buff; *c; c++) { + if (iscntrl(*c)) { + *c = ' '; + } + } + gbfprintf(fout, fmt, buff); + xfree(buff); } @@ -507,202 +516,218 @@ print_string(const char *fmt, const char *string) static void write_waypt(const waypoint *wpt) { - unsigned char wpt_class; - garmin_fs_p gmsd; - char *wpt_type; - char *dspl_mode; - const char *country; - double x; - int i, icon, dynamic; - char *icon_descr; - - gmsd = GMSD_FIND(wpt); - - i = GMSD_GET(display, 0); - if (i > GT_DISPLAY_MODE_MAX) i = 0; - dspl_mode = gt_display_mode_names[i]; - - wpt_class = GMSD_GET(wpt_class, 0); - if (wpt_class <= gt_waypt_class_map_line) - wpt_type = gt_waypt_class_names[wpt_class]; - else - wpt_type = gt_waypt_class_names[0]; - - gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); - if (wpt_class <= gt_waypt_class_airport_ndb) { - char *temp = wpt->notes; - if (temp == NULL) { - if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) - temp = wpt->description; - else - temp = ""; - } - print_string("%s\t", temp); - } - else - gbfprintf(fout, "\t"); - gbfprintf(fout, "%s\t", wpt_type); - - print_position(wpt); - - if IS_VALID_ALT(wpt->altitude) - print_distance(wpt->altitude, 1, 0, 0); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, depth, unknown_alt); - if (x != unknown_alt) - print_distance(x, 1, 0, 1); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, proximity, unknown_alt); - if (x != unknown_alt) - print_distance(x, 0, 0, 0); - gbfprintf(fout, "\t"); - - x = WAYPT_GET(wpt, temperature, -999); - if (x != -999) - print_temperature(x); - gbfprintf(fout, "\t%s\t", dspl_mode); - - gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ - - icon = GMSD_GET(icon, -1); - if (icon == -1) { - icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); - } - icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); - print_string("%s\t", icon_descr); - if (dynamic) xfree(icon_descr); - - print_string("%s\t", GMSD_GET(facility, "")); - print_string("%s\t", GMSD_GET(city, "")); - print_string("%s\t", GMSD_GET(state, "")); - country = gt_get_icao_country(GMSD_GET(cc, "")); - print_string("%s\t", (country != NULL) ? country : ""); - print_date_and_time(wpt->creation_time, 0); - print_string("%s\t", wpt->url ? wpt->url : ""); - print_categories(GMSD_GET(category, 0)); - - gbfprintf(fout, "\r\n"); + unsigned char wpt_class; + garmin_fs_p gmsd; + char *wpt_type; + char *dspl_mode; + const char *country; + double x; + int i, icon, dynamic; + char *icon_descr; + + gmsd = GMSD_FIND(wpt); + + i = GMSD_GET(display, 0); + if (i > GT_DISPLAY_MODE_MAX) { + i = 0; + } + dspl_mode = gt_display_mode_names[i]; + + wpt_class = GMSD_GET(wpt_class, 0); + if (wpt_class <= gt_waypt_class_map_line) { + wpt_type = gt_waypt_class_names[wpt_class]; + } else { + wpt_type = gt_waypt_class_names[0]; + } + + gbfprintf(fout, "Waypoint\t%s\t", (wpt->shortname) ? wpt->shortname : ""); + if (wpt_class <= gt_waypt_class_airport_ndb) { + char *temp = wpt->notes; + if (temp == NULL) { + if (wpt->description && (strcmp(wpt->description, wpt->shortname) != 0)) { + temp = wpt->description; + } else { + temp = ""; + } + } + print_string("%s\t", temp); + } else { + gbfprintf(fout, "\t"); + } + gbfprintf(fout, "%s\t", wpt_type); + + print_position(wpt); + + if IS_VALID_ALT(wpt->altitude) { + print_distance(wpt->altitude, 1, 0, 0); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, depth, unknown_alt); + if (x != unknown_alt) { + print_distance(x, 1, 0, 1); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, proximity, unknown_alt); + if (x != unknown_alt) { + print_distance(x, 0, 0, 0); + } + gbfprintf(fout, "\t"); + + x = WAYPT_GET(wpt, temperature, -999); + if (x != -999) { + print_temperature(x); + } + gbfprintf(fout, "\t%s\t", dspl_mode); + + gbfprintf(fout, "Unknown\t"); /* Color is fixed: Unknown */ + + icon = GMSD_GET(icon, -1); + if (icon == -1) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } + icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + print_string("%s\t", icon_descr); + if (dynamic) { + xfree(icon_descr); + } + + print_string("%s\t", GMSD_GET(facility, "")); + print_string("%s\t", GMSD_GET(city, "")); + print_string("%s\t", GMSD_GET(state, "")); + country = gt_get_icao_country(GMSD_GET(cc, "")); + print_string("%s\t", (country != NULL) ? country : ""); + print_date_and_time(wpt->creation_time, 0); + print_string("%s\t", wpt->url ? wpt->url : ""); + print_categories(GMSD_GET(category, 0)); + + gbfprintf(fout, "\r\n"); } static void route_disp_hdr_cb(const route_head *rte) { - current_trk = (route_head *)rte; - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->total = 0; - if (rte->rte_waypt_ct <= 0) return; - - if (!gtxt_flags.route_header_written) { - gtxt_flags.route_header_written = 1; - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); - } - - print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); - print_distance(cur_info->length, 0, 1, 0); - print_course(cur_info->first_wpt, cur_info->last_wpt); - gbfprintf(fout, "\t%d waypoints\t", cur_info->count); - print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); - gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); + current_trk = (route_head *)rte; + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + if (rte->rte_waypt_ct <= 0) { + return; + } + + if (!gtxt_flags.route_header_written) { + gtxt_flags.route_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[route_header]); + } + + print_string("\r\nRoute\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_distance(cur_info->length, 0, 1, 0); + print_course(cur_info->first_wpt, cur_info->last_wpt); + gbfprintf(fout, "\t%d waypoints\t", cur_info->count); + print_string("%s\r\n", rte->rte_url ? rte->rte_url : ""); + gbfprintf(fout, "\r\nHeader\t%s\r\n\r\n", headers[rtept_header]); } static void route_disp_tlr_cb(const route_head *rte) { - route_idx++; + route_idx++; } static void route_disp_wpt_cb(const waypoint *wpt) { - waypoint *prev = cur_info->prev_wpt; - - gbfprintf(fout, "Route Waypoint\t"); - gbfprintf(fout, "%s\t", wpt->shortname); - - if (prev != NULL) - { - double dist = waypt_distance_ex(prev, wpt); - cur_info->total += dist; - print_distance(cur_info->total, 0, 1, 0); - print_distance(dist, 0, 1, 0); - print_course(prev, wpt); - } - else - print_distance(0, 1, 0, 0); - - gbfprintf(fout, "\r\n"); - - cur_info->prev_wpt = (waypoint *)wpt; + waypoint *prev = cur_info->prev_wpt; + + gbfprintf(fout, "Route Waypoint\t"); + gbfprintf(fout, "%s\t", wpt->shortname); + + if (prev != NULL) { + double dist = waypt_distance_ex(prev, wpt); + cur_info->total += dist; + print_distance(cur_info->total, 0, 1, 0); + print_distance(dist, 0, 1, 0); + print_course(prev, wpt); + } else { + print_distance(0, 1, 0, 0); + } + + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; } static void track_disp_hdr_cb(const route_head *track) { - cur_info = &route_info[route_idx]; - cur_info->prev_wpt = NULL; - cur_info->total = 0; - current_trk = (route_head *)track; - if (track->rte_waypt_ct <= 0) return; - - if (!gtxt_flags.track_header_written) { - gtxt_flags.track_header_written = 1; - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); - } - - print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); - print_date_and_time(cur_info->start, 0); - print_date_and_time(cur_info->time, 1); - print_distance(cur_info->length, 0, 1, 0); - print_speed(&cur_info->length, &cur_info->time); - print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); - gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); + cur_info = &route_info[route_idx]; + cur_info->prev_wpt = NULL; + cur_info->total = 0; + current_trk = (route_head *)track; + if (track->rte_waypt_ct <= 0) { + return; + } + + if (!gtxt_flags.track_header_written) { + gtxt_flags.track_header_written = 1; + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n", headers[track_header]); + } + + print_string("\r\nTrack\t%s\t", current_trk->rte_name ? current_trk->rte_name : ""); + print_date_and_time(cur_info->start, 0); + print_date_and_time(cur_info->time, 1); + print_distance(cur_info->length, 0, 1, 0); + print_speed(&cur_info->length, &cur_info->time); + print_string("%s", (track->rte_url != NULL) ? track->rte_url : ""); + gbfprintf(fout, "\r\n\r\nHeader\t%s\r\n\r\n", headers[trkpt_header]); } static void track_disp_tlr_cb(const route_head *track) { - route_idx++; + route_idx++; } static void track_disp_wpt_cb(const waypoint *wpt) { - waypoint *prev = cur_info->prev_wpt; - time_t delta; - double dist, depth; - - gbfprintf(fout, "Trackpoint\t"); - - print_position(wpt); - print_date_and_time(wpt->creation_time, 0); - if IS_VALID_ALT(wpt->altitude) - print_distance(wpt->altitude, 1, 0, 0); - - gbfprintf(fout, "\t"); - depth = WAYPT_GET(wpt, depth, unknown_alt); - if (depth != unknown_alt) - print_distance(depth, 1, 0, 1); - - if (prev != NULL) { - float temp; - gbfprintf(fout, "\t"); - delta = wpt->creation_time - prev->creation_time; - temp = WAYPT_GET(wpt, temperature, -999); - if (temp != -999) - print_temperature(temp); - gbfprintf(fout, "\t"); - dist = waypt_distance_ex(prev, wpt); - print_distance(dist, 0, 1, 0); - print_date_and_time(delta, 1); - print_speed(&dist, &delta); - print_course(prev, wpt); - } - gbfprintf(fout, "\r\n"); - - cur_info->prev_wpt = (waypoint *)wpt; + waypoint *prev = cur_info->prev_wpt; + time_t delta; + double dist, depth; + + gbfprintf(fout, "Trackpoint\t"); + + print_position(wpt); + print_date_and_time(wpt->creation_time, 0); + if IS_VALID_ALT(wpt->altitude) { + print_distance(wpt->altitude, 1, 0, 0); + } + + gbfprintf(fout, "\t"); + depth = WAYPT_GET(wpt, depth, unknown_alt); + if (depth != unknown_alt) { + print_distance(depth, 1, 0, 1); + } + + if (prev != NULL) { + float temp; + gbfprintf(fout, "\t"); + delta = wpt->creation_time - prev->creation_time; + temp = WAYPT_GET(wpt, temperature, -999); + if (temp != -999) { + print_temperature(temp); + } + gbfprintf(fout, "\t"); + dist = waypt_distance_ex(prev, wpt); + print_distance(dist, 0, 1, 0); + print_date_and_time(delta, 1); + print_speed(&dist, &delta); + print_course(prev, wpt); + } + gbfprintf(fout, "\r\n"); + + cur_info->prev_wpt = (waypoint *)wpt; } /******************************************************************************* @@ -712,123 +737,125 @@ track_disp_wpt_cb(const waypoint *wpt) static void garmin_txt_wr_init(const char *fname) { - char *grid_str; - - memset(>xt_flags, 0, sizeof(gtxt_flags)); - - fout = gbfopen(fname, "wb", MYNAME); - - gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); - gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); - init_date_and_time_format(); - if (opt_precision) { - precision = atoi(opt_precision); - is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); - } - - datum_str = get_option_val(opt_datum, NULL); - grid_str = get_option_val(opt_grid, NULL); - - grid_index = grid_lat_lon_dmm; - if (grid_str != NULL) { - int i; - - if (sscanf(grid_str, "%d", &i)) { - grid_index = (grid_type) i; - if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX)) - fatal(MYNAME ": Grid index out of range (%d..%d)!", - (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); - } - else grid_index = gt_lookup_grid_type(grid_str, MYNAME); - } - - switch(grid_index) { - case grid_bng: /* force datum to "Ord Srvy Grt Britn" */ - datum_index = DATUM_OSGB36; - break; - case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */ - datum_index = DATUM_WGS84; - break; - default: - datum_index = gt_lookup_datum_index(datum_str, MYNAME); - } - - if (opt_utc != NULL) { - if (case_ignore_strcmp(opt_utc, "utc") == 0) - utc_offs = 0; - else - utc_offs = atoi(opt_utc); - utc_offs *= (60 * 60); - gtxt_flags.utc = 1; - } + char *grid_str; + + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fout = gbfopen(fname, "wb", MYNAME); + + gtxt_flags.metric = (toupper(*get_option_val(opt_dist, "m")) == 'M'); + gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C'); + init_date_and_time_format(); + if (opt_precision) { + precision = atoi(opt_precision); + is_fatal(precision < 0, MYNAME ": Invalid precision (%s)!", opt_precision); + } + + datum_str = get_option_val(opt_datum, NULL); + grid_str = get_option_val(opt_grid, NULL); + + grid_index = grid_lat_lon_dmm; + if (grid_str != NULL) { + int i; + + if (sscanf(grid_str, "%d", &i)) { + grid_index = (grid_type) i; + if ((grid_index < GRID_INDEX_MIN) || (grid_index > GRID_INDEX_MAX)) + fatal(MYNAME ": Grid index out of range (%d..%d)!", + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + } else { + grid_index = gt_lookup_grid_type(grid_str, MYNAME); + } + } + + switch (grid_index) { + case grid_bng: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_OSGB36; + break; + case grid_swiss: /* force datum to "Ord Srvy Grt Britn" */ + datum_index = DATUM_WGS84; + break; + default: + datum_index = gt_lookup_datum_index(datum_str, MYNAME); + } + + if (opt_utc != NULL) { + if (case_ignore_strcmp(opt_utc, "utc") == 0) { + utc_offs = 0; + } else { + utc_offs = atoi(opt_utc); + } + utc_offs *= (60 * 60); + gtxt_flags.utc = 1; + } } static void garmin_txt_wr_deinit(void) { - gbfclose(fout); - xfree(date_time_format); + gbfclose(fout); + xfree(date_time_format); } static void garmin_txt_write(void) { - char *grid_str, *c; - const char *datum_str; - - grid_str = xstrdup(gt_get_mps_grid_longname(grid_index, MYNAME)); - while ((c = strchr(grid_str, '*'))) *c = 0xB0; /* degree sign */ - cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_str); - xfree(grid_str); - - datum_str = gt_get_mps_datum_name(datum_index); - gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); - - waypoints = 0; - gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ - waypt_disp_all(enum_waypt_cb); - route_disp_all(NULL, NULL, enum_waypt_cb); - gtxt_flags.enum_waypoints = 0; - - if (waypoints > 0) { - int i; - - wpt_a_ct = 0; - wpt_a = (waypoint **)xcalloc(waypoints, sizeof(*wpt_a)); - waypt_disp_all(enum_waypt_cb); - route_disp_all(NULL, NULL, enum_waypt_cb); - qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); - - gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); - for (i = 0; i < waypoints; i++) - { - waypoint *wpt = wpt_a[i]; - write_waypt(wpt); - } - xfree(wpt_a); - - route_idx = 0; - route_info = xcalloc(route_count(), sizeof(struct info_s)); - routepoints = 0; - route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); - if (routepoints > 0) - { - route_idx = 0; - route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); - } - xfree(route_info); - } - - route_idx = 0; - route_info = xcalloc(track_count(), sizeof(struct info_s)); - routepoints = 0; - track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); - - if (routepoints > 0) { - route_idx = 0; - track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); - } - xfree(route_info); + char *grid_str, *c; + const char *datum_str; + + grid_str = xstrdup(gt_get_mps_grid_longname(grid_index, MYNAME)); + while ((c = strchr(grid_str, '*'))) { + *c = 0xB0; /* degree sign */ + } + cet_gbfprintf(fout, &cet_cs_vec_cp1252, "Grid\t%s\r\n", grid_str); + xfree(grid_str); + + datum_str = gt_get_mps_datum_name(datum_index); + gbfprintf(fout, "Datum\t%s\r\n\r\n", datum_str); + + waypoints = 0; + gtxt_flags.enum_waypoints = 1; /* enum all waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + gtxt_flags.enum_waypoints = 0; + + if (waypoints > 0) { + int i; + + wpt_a_ct = 0; + wpt_a = (waypoint **)xcalloc(waypoints, sizeof(*wpt_a)); + waypt_disp_all(enum_waypt_cb); + route_disp_all(NULL, NULL, enum_waypt_cb); + qsort(wpt_a, waypoints, sizeof(*wpt_a), sort_waypt_cb); + + gbfprintf(fout, "Header\t%s\r\n\r\n", headers[waypt_header]); + for (i = 0; i < waypoints; i++) { + waypoint *wpt = wpt_a[i]; + write_waypt(wpt); + } + xfree(wpt_a); + + route_idx = 0; + route_info = xcalloc(route_count(), sizeof(struct info_s)); + routepoints = 0; + route_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + if (routepoints > 0) { + route_idx = 0; + route_disp_all(route_disp_hdr_cb, route_disp_tlr_cb, route_disp_wpt_cb); + } + xfree(route_info); + } + + route_idx = 0; + route_info = xcalloc(track_count(), sizeof(struct info_s)); + routepoints = 0; + track_disp_all(prework_hdr_cb, prework_tlr_cb, prework_wpt_cb); + + if (routepoints > 0) { + route_idx = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + } + xfree(route_info); } /* READER *****************************************************************/ @@ -838,17 +865,17 @@ garmin_txt_write(void) static void free_header(const header_type ht) { - int i; - - for (i = 0; i < MAX_HEADER_FIELDS; i++) { - char *c = header_lines[ht][i]; - if (c != NULL) { - xfree(c); - header_lines[ht][i] = NULL; - } - } - header_ct[ht] = 0; - memset(header_fields[ht], 0, sizeof(header_fields[ht])); + int i; + + for (i = 0; i < MAX_HEADER_FIELDS; i++) { + char *c = header_lines[ht][i]; + if (c != NULL) { + xfree(c); + header_lines[ht][i] = NULL; + } + } + header_ct[ht] = 0; + memset(header_fields[ht], 0, sizeof(header_fields[ht])); } /* data parsers */ @@ -856,353 +883,435 @@ free_header(const header_type ht) static int parse_date_and_time(char *str, time_t *value) { - struct tm tm; - char *cerr, *cin; - - memset(&tm, 0, sizeof(tm)); - cin = lrtrim(str); - if (*cin == '\0') return 0; - - cerr = strptime(cin, date_time_format, &tm); - if (cerr == NULL) { - cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); - is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); - } - + struct tm tm; + char *cerr, *cin; + + memset(&tm, 0, sizeof(tm)); + cin = lrtrim(str); + if (*cin == '\0') { + return 0; + } + + cerr = strptime(cin, date_time_format, &tm); + if (cerr == NULL) { + cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm); + is_fatal(cerr == NULL, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line); + } + // printf(MYNAME "_parse_date_and_time: %02d.%02d.%04d, %02d:%02d:%02d\n", // tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec); - *value = mklocaltime(&tm); - return 1; + *value = mklocaltime(&tm); + return 1; } static gbuint16 parse_categories(const char *str) { - char buff[256]; - gbuint16 val; - gbuint16 res = 0; - char *cin, *cx; - - if (*str == '\0') return 0; - - strncpy(buff, str, sizeof(buff)); - cin = lrtrim(buff); - if (*cin == '\0') return 0; - - strcat(cin, ","); - - while ((cx = strchr(cin, ','))) { - *cx++ = '\0'; - cin = lrtrim(cin); - if (*cin != '\0') { - if (!garmin_fs_convert_category(cin, &val)) - warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line); - else - res = res | val; - } - cin = cx; - } - return res; + char buff[256]; + gbuint16 val; + gbuint16 res = 0; + char *cin, *cx; + + if (*str == '\0') { + return 0; + } + + strncpy(buff, str, sizeof(buff)); + cin = lrtrim(buff); + if (*cin == '\0') { + return 0; + } + + strcat(cin, ","); + + while ((cx = strchr(cin, ','))) { + *cx++ = '\0'; + cin = lrtrim(cin); + if (*cin != '\0') { + if (!garmin_fs_convert_category(cin, &val)) { + warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line); + } else { + res = res | val; + } + } + cin = cx; + } + return res; } static int parse_temperature(const char *str, double *temperature) { - double value; - unsigned char unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - if (sscanf(str, "%lf %c", &value, &unit) == 2) { - unit = toupper(unit); - switch(unit) { - case 'C': *temperature = value; break; - case 'F': *temperature = FAHRENHEIT_TO_CELSIUS(value); break; - default: - fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); - } - return 1; - } - else - fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); - return 0; + double value; + unsigned char unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + if (sscanf(str, "%lf %c", &value, &unit) == 2) { + unit = toupper(unit); + switch (unit) { + case 'C': + *temperature = value; + break; + case 'F': + *temperature = FAHRENHEIT_TO_CELSIUS(value); + break; + default: + fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line); + } + return 1; + } else { + fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line); + } + return 0; } static void parse_header(void) { - char *str; - int column = -1; - - free_header(unknown_header); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - header_lines[unknown_header][column] = strupper(xstrdup(str)); - header_ct[unknown_header]++; - if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) break; - } + char *str; + int column = -1; + + free_header(unknown_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + header_lines[unknown_header][column] = strupper(xstrdup(str)); + header_ct[unknown_header]++; + if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) { + break; + } + } } static int parse_display(const char *str, int *val) { - gt_display_modes_e i; - - if ((str == NULL) || (*str == '\0')) return 0; - - for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { - if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { - *val = i; - return 1; - } - } - warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); - return 0; + gt_display_modes_e i; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + for (i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; i++) { + if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) { + *val = i; + return 1; + } + } + warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line); + return 0; } static void bind_fields(const header_type ht) { - int i; - char *fields, *c; - - is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); - - if (header_ct[unknown_header] <= 0) return; - free_header(ht); - - /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ - - i = strlen(headers[ht]); - fields = xmalloc(i + 2); - strcpy(fields, headers[ht]); - strcat(fields, "\t"); - c = strupper(fields); - while ((c = strchr(c, '\t'))) *c++ = '\0'; - - for (i = 0; i < header_ct[unknown_header]; i++) { - char *name; - int field_no; - name = header_lines[ht][i] = header_lines[unknown_header][i]; - header_lines[unknown_header][i] = NULL; - - c = fields; - field_no = 1; - while (*c) { - if (strcmp(c, name) == 0) { - header_fields[ht][i] = field_no; + int i; + char *fields, *c; + + is_fatal((grid_index < 0) || (datum_index < 0), MYNAME ": Incomplete or invalid file header!"); + + if (header_ct[unknown_header] <= 0) { + return; + } + free_header(ht); + + /* make a copy of headers[ht], uppercase, replace "\t" with "\0" */ + + i = strlen(headers[ht]); + fields = xmalloc(i + 2); + strcpy(fields, headers[ht]); + strcat(fields, "\t"); + c = strupper(fields); + while ((c = strchr(c, '\t'))) { + *c++ = '\0'; + } + + for (i = 0; i < header_ct[unknown_header]; i++) { + char *name; + int field_no; + name = header_lines[ht][i] = header_lines[unknown_header][i]; + header_lines[unknown_header][i] = NULL; + + c = fields; + field_no = 1; + while (*c) { + if (strcmp(c, name) == 0) { + header_fields[ht][i] = field_no; #if 0 - printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); + printf("Binding field \"%s\" to internal number %d (%d,%d)\n", name, field_no, ht, i); #endif - break; - } - field_no++; - c = c + strlen(c) + 1; - } - } - header_ct[unknown_header] = 0; - xfree(fields); + break; + } + field_no++; + c = c + strlen(c) + 1; + } + } + header_ct[unknown_header] = 0; + xfree(fields); } static void parse_grid(void) { - char *str = csv_lineparse(NULL, "\t", "", 1); - - if (str != NULL) { - if (strstr(str, "dd.ddddd") != 0) grid_index = grid_lat_lon_ddd; - else if (strstr(str, "mm.mmm") != 0) grid_index = grid_lat_lon_dmm; - else if (strstr(str, "mm'ss.s") != 0) grid_index = grid_lat_lon_dms; - else grid_index = gt_lookup_grid_type(str, MYNAME); - } - else - fatal(MYNAME ": Missing grid headline!\n"); + char *str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + if (strstr(str, "dd.ddddd") != 0) { + grid_index = grid_lat_lon_ddd; + } else if (strstr(str, "mm.mmm") != 0) { + grid_index = grid_lat_lon_dmm; + } else if (strstr(str, "mm'ss.s") != 0) { + grid_index = grid_lat_lon_dms; + } else { + grid_index = gt_lookup_grid_type(str, MYNAME); + } + } else { + fatal(MYNAME ": Missing grid headline!\n"); + } } static void parse_datum(void) { - char *str = csv_lineparse(NULL, "\t", "", 1); - - if (str != NULL) - datum_index = gt_lookup_datum_index(str, MYNAME); - else - fatal(MYNAME ": Missing GPS datum headline!\n"); + char *str = csv_lineparse(NULL, "\t", "", 1); + + if (str != NULL) { + datum_index = gt_lookup_datum_index(str, MYNAME); + } else { + fatal(MYNAME ": Missing GPS datum headline!\n"); + } } static void parse_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt; - garmin_fs_p gmsd = NULL; - - bind_fields(waypt_header); - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) - { - int i, dynamic; - double d; - int field_no = header_fields[waypt_header][column]; - - switch(field_no) { - case 1: wpt->shortname = DUPSTR(str); break; - case 2: wpt->notes = DUPSTR(str); break; - case 3: - for (i = 0; i <= gt_waypt_class_map_line; i++) { - if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { - GMSD_SET(wpt_class, i); - break; - } - } - break; - case 4: - parse_coordinates(str, datum_index, grid_index, - &wpt->latitude, &wpt->longitude, MYNAME); - break; - case 5: if (parse_distance(str, &d, 1, MYNAME)) wpt->altitude = d; break; - case 6: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, depth, d); break; - case 7: if (parse_distance(str, &d, 1, MYNAME)) WAYPT_SET(wpt, proximity, d); break; - case 8: if (parse_temperature(str, &d)) WAYPT_SET(wpt, temperature, d); break; - case 9: if (parse_display(str, &i)) GMSD_SET(display, i); break; - case 10: break; /* skip color */ - case 11: - i = gt_find_icon_number_from_desc(str, GDB); - GMSD_SET(icon, i); - wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); - wpt->wpt_flags.icon_descr_is_dynamic = dynamic; - break; - case 12: GMSD_SETSTR(facility, str); break; - case 13: GMSD_SETSTR(city, str); break; - case 14: GMSD_SETSTR(state, str); break; - case 15: - GMSD_SETSTR(country, str); - GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); - break; - case 16: parse_date_and_time(str, &wpt->creation_time); break; - case 17: wpt->url = DUPSTR(str); break; - case 18: GMSD_SET(category, parse_categories(str)); break; - default: break; - } - } - waypt_add(wpt); + char *str; + int column = -1; + waypoint *wpt; + garmin_fs_p gmsd = NULL; + + bind_fields(waypt_header); + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int i, dynamic; + double d; + int field_no = header_fields[waypt_header][column]; + + switch (field_no) { + case 1: + wpt->shortname = DUPSTR(str); + break; + case 2: + wpt->notes = DUPSTR(str); + break; + case 3: + for (i = 0; i <= gt_waypt_class_map_line; i++) { + if (case_ignore_strcmp(str, gt_waypt_class_names[i]) == 0) { + GMSD_SET(wpt_class, i); + break; + } + } + break; + case 4: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 5: + if (parse_distance(str, &d, 1, MYNAME)) { + wpt->altitude = d; + } + break; + case 6: + if (parse_distance(str, &d, 1, MYNAME)) { + WAYPT_SET(wpt, depth, d); + } + break; + case 7: + if (parse_distance(str, &d, 1, MYNAME)) { + WAYPT_SET(wpt, proximity, d); + } + break; + case 8: + if (parse_temperature(str, &d)) { + WAYPT_SET(wpt, temperature, d); + } + break; + case 9: + if (parse_display(str, &i)) { + GMSD_SET(display, i); + } + break; + case 10: + break; /* skip color */ + case 11: + i = gt_find_icon_number_from_desc(str, GDB); + GMSD_SET(icon, i); + wpt->icon_descr = gt_find_desc_from_icon_number(i, GDB, &dynamic); + wpt->wpt_flags.icon_descr_is_dynamic = dynamic; + break; + case 12: + GMSD_SETSTR(facility, str); + break; + case 13: + GMSD_SETSTR(city, str); + break; + case 14: + GMSD_SETSTR(state, str); + break; + case 15: + GMSD_SETSTR(country, str); + GMSD_SETSTR(cc, gt_get_icao_cc(str, wpt->shortname)); + break; + case 16: + parse_date_and_time(str, &wpt->creation_time); + break; + case 17: + wpt->url = DUPSTR(str); + break; + case 18: + GMSD_SET(category, parse_categories(str)); + break; + default: + break; + } + } + waypt_add(wpt); } static void parse_route_header(void) { - char *str; - int column = -1; - route_head *rte; - - rte = route_head_alloc(); - - bind_fields(route_header); - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[route_header][column]; - switch(field_no) { - case 1: rte->rte_name = DUPSTR(str); break; - case 5: rte->rte_url = DUPSTR(str); break; - } - } - route_add_head(rte); - current_rte = rte; + char *str; + int column = -1; + route_head *rte; + + rte = route_head_alloc(); + + bind_fields(route_header); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[route_header][column]; + switch (field_no) { + case 1: + rte->rte_name = DUPSTR(str); + break; + case 5: + rte->rte_url = DUPSTR(str); + break; + } + } + route_add_head(rte); + current_rte = rte; } static void parse_track_header(void) { - char *str; - int column = -1; - route_head *trk; - - bind_fields(track_header); - trk = route_head_alloc(); - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[track_header][column]; - switch(field_no) { - case 1: trk->rte_name = DUPSTR(str); break; - case 6: trk->rte_url = DUPSTR(str); break; - } - } - track_add_head(trk); - current_trk = trk; + char *str; + int column = -1; + route_head *trk; + + bind_fields(track_header); + trk = route_head_alloc(); + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[track_header][column]; + switch (field_no) { + case 1: + trk->rte_name = DUPSTR(str); + break; + case 6: + trk->rte_url = DUPSTR(str); + break; + } + } + track_add_head(trk); + current_trk = trk; } static void parse_route_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt = NULL; - - bind_fields(rtept_header); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no = header_fields[rtept_header][column]; - switch(field_no) { - case 1: - is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); - wpt = find_waypt_by_name(str); - is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); - wpt = waypt_dupe(wpt); - break; - } - } - if (wpt != NULL) - route_add_wpt(current_rte, wpt); + char *str; + int column = -1; + waypoint *wpt = NULL; + + bind_fields(rtept_header); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no = header_fields[rtept_header][column]; + switch (field_no) { + case 1: + is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line); + wpt = find_waypt_by_name(str); + is_fatal((wpt == NULL), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line); + wpt = waypt_dupe(wpt); + break; + } + } + if (wpt != NULL) { + route_add_wpt(current_rte, wpt); + } } static void parse_track_waypoint(void) { - char *str; - int column = -1; - waypoint *wpt; - - bind_fields(trkpt_header); - wpt = waypt_new(); - - while ((str = csv_lineparse(NULL, "\t", "", column++))) { - int field_no; - double x; - - if (! *str) continue; - - field_no = header_fields[trkpt_header][column]; - switch(field_no) { - case 1: - parse_coordinates(str, datum_index, grid_index, - &wpt->latitude, &wpt->longitude, MYNAME); - break; - case 2: - parse_date_and_time(str, &wpt->creation_time); - break; - case 3: - if (parse_distance(str, &x, 1, MYNAME)) - wpt->altitude = x; - break; - case 4: - if (parse_distance(str, &x, 1, MYNAME)) WAYPT_SET(wpt, depth, x); - break; - case 5: - if (parse_temperature(str, &x)) WAYPT_SET(wpt, temperature, x); - break; - case 8: - if (parse_speed(str, &x, 1, MYNAME)) WAYPT_SET(wpt, speed, x); - break; - case 9: - WAYPT_SET(wpt, course, atoi(str)); - break; - } - } - track_add_wpt(current_trk, wpt); + char *str; + int column = -1; + waypoint *wpt; + + bind_fields(trkpt_header); + wpt = waypt_new(); + + while ((str = csv_lineparse(NULL, "\t", "", column++))) { + int field_no; + double x; + + if (! *str) { + continue; + } + + field_no = header_fields[trkpt_header][column]; + switch (field_no) { + case 1: + parse_coordinates(str, datum_index, grid_index, + &wpt->latitude, &wpt->longitude, MYNAME); + break; + case 2: + parse_date_and_time(str, &wpt->creation_time); + break; + case 3: + if (parse_distance(str, &x, 1, MYNAME)) { + wpt->altitude = x; + } + break; + case 4: + if (parse_distance(str, &x, 1, MYNAME)) { + WAYPT_SET(wpt, depth, x); + } + break; + case 5: + if (parse_temperature(str, &x)) { + WAYPT_SET(wpt, temperature, x); + } + break; + case 8: + if (parse_speed(str, &x, 1, MYNAME)) { + WAYPT_SET(wpt, speed, x); + } + break; + case 9: + WAYPT_SET(wpt, course, atoi(str)); + break; + } + } + track_add_wpt(current_trk, wpt); } /***************************************************************/ @@ -1210,77 +1319,92 @@ parse_track_waypoint(void) static void garmin_txt_rd_init(const char *fname) { - memset(>xt_flags, 0, sizeof(gtxt_flags)); - - fin = gbfopen(fname, "rb", MYNAME); - memset(&header_ct, 0, sizeof(header_ct)); - - datum_index = -1; - grid_index = -1; - - init_date_and_time_format(); + memset(>xt_flags, 0, sizeof(gtxt_flags)); + + fin = gbfopen(fname, "rb", MYNAME); + memset(&header_ct, 0, sizeof(header_ct)); + + datum_index = -1; + grid_index = -1; + + init_date_and_time_format(); } -static void +static void garmin_txt_rd_deinit(void) { - header_type h; + header_type h; - for (h = waypt_header; h <= unknown_header; h++) { - free_header(h); - } - gbfclose(fin); - xfree(date_time_format); + for (h = waypt_header; h <= unknown_header; h++) { + free_header(h); + } + gbfclose(fin); + xfree(date_time_format); } static void garmin_txt_read(void) { - char *buff; - - current_line = 0; - - while ((buff = gbfgetstr(fin))) { - char *cin; - - if ((current_line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - cin = lrtrim(buff); - if (*cin == '\0') continue; - - cin = csv_lineparse(cin, "\t", "", 0); - - if (cin == NULL) continue; - - if (case_ignore_strcmp(cin, "Header") == 0) parse_header(); - else if (case_ignore_strcmp(cin, "Grid") == 0) parse_grid(); - else if (case_ignore_strcmp(cin, "Datum") == 0) parse_datum(); - else if (case_ignore_strcmp(cin, "Waypoint") == 0) parse_waypoint(); - else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) parse_route_waypoint(); - else if (case_ignore_strcmp(cin, "Trackpoint") == 0) parse_track_waypoint(); - else if (case_ignore_strcmp(cin, "Route") == 0) parse_route_header(); - else if (case_ignore_strcmp(cin, "Track") == 0) parse_track_header(); - else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; - else - fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); - - /* flush pending data */ - while (csv_lineparse(NULL, "\t", "", 0)); - } + char *buff; + + current_line = 0; + + while ((buff = gbfgetstr(fin))) { + char *cin; + + if ((current_line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + cin = lrtrim(buff); + if (*cin == '\0') { + continue; + } + + cin = csv_lineparse(cin, "\t", "", 0); + + if (cin == NULL) { + continue; + } + + if (case_ignore_strcmp(cin, "Header") == 0) { + parse_header(); + } else if (case_ignore_strcmp(cin, "Grid") == 0) { + parse_grid(); + } else if (case_ignore_strcmp(cin, "Datum") == 0) { + parse_datum(); + } else if (case_ignore_strcmp(cin, "Waypoint") == 0) { + parse_waypoint(); + } else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) { + parse_route_waypoint(); + } else if (case_ignore_strcmp(cin, "Trackpoint") == 0) { + parse_track_waypoint(); + } else if (case_ignore_strcmp(cin, "Route") == 0) { + parse_route_header(); + } else if (case_ignore_strcmp(cin, "Track") == 0) { + parse_track_header(); + } else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ; + else { + fatal(MYNAME ": Unknwon identifier (%s) at line %d!\n", cin, current_line); + } + + /* flush pending data */ + while (csv_lineparse(NULL, "\t", "", 0)); + } } ff_vecs_t garmin_txt_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - garmin_txt_rd_init, - garmin_txt_wr_init, - garmin_txt_rd_deinit, - garmin_txt_wr_deinit, - garmin_txt_read, - garmin_txt_write, - NULL, - garmin_txt_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, + garmin_txt_rd_init, + garmin_txt_wr_init, + garmin_txt_rd_deinit, + garmin_txt_wr_deinit, + garmin_txt_read, + garmin_txt_write, + NULL, + garmin_txt_args, + CET_CHARSET_MS_ANSI, 0 }; #endif // CSVFMTS_ENABLED diff --git a/gpsbabel/garmin_xt.c b/gpsbabel/garmin_xt.c index 84cf2a387..716010edf 100644 --- a/gpsbabel/garmin_xt.c +++ b/gpsbabel/garmin_xt.c @@ -31,23 +31,23 @@ #define DATABLOCKSIZE 1 #define STRK_BLOCK_SIZE 97 -static int colors[] = { - 0x000000, // Black - 0x00008b, // DarkRed - 0x006400, // DarkGreen - 0x00d7ff, // Gold - 0x8b0000, // DarkBlue - 0x8b008b, // DarkMagenta - 0x8b8b00, // DarkCyan - 0xd3d3d3, // LightGray - 0xa9a9a9, // DarkGray - 0x0000ff, // Red - 0x00ff00, // Green - 0x00ffff, // Yellow - 0xff0000, // Blue - 0xff00ff, // Magenta - 0xffff00, // Cyan - 0xffffff // White +static int colors[] = { + 0x000000, // Black + 0x00008b, // DarkRed + 0x006400, // DarkGreen + 0x00d7ff, // Gold + 0x8b0000, // DarkBlue + 0x8b008b, // DarkMagenta + 0x8b8b00, // DarkCyan + 0xd3d3d3, // LightGray + 0xa9a9a9, // DarkGray + 0x0000ff, // Red + 0x00ff00, // Green + 0x00ffff, // Yellow + 0xff0000, // Blue + 0xff00ff, // Magenta + 0xffff00, // Cyan + 0xffffff // White }; static gbfile *fin; @@ -57,11 +57,11 @@ static char *opt_trk_header = NULL; static arglist_t format_garmin_xt_args[] = { - {"ftype", &opt_xt_ftype, "Garmin Mobile XT ([ATRK]/STRK)", "ATRK", ARGTYPE_STRING | ARGTYPE_REQUIRED, ARG_NOMINMAX}, - // TODO: SHIFT - can't test behaviour, do not have appropriate files - //{"trk_header_opt", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign/2-sht)", "0", ARGTYPE_INT, ARG_NOMINMAX}, - {"trk_header", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign)", "0", ARGTYPE_INT, ARG_NOMINMAX}, - ARG_TERMINATOR + {"ftype", &opt_xt_ftype, "Garmin Mobile XT ([ATRK]/STRK)", "ATRK", ARGTYPE_STRING | ARGTYPE_REQUIRED, ARG_NOMINMAX}, + // TODO: SHIFT - can't test behaviour, do not have appropriate files + //{"trk_header_opt", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign/2-sht)", "0", ARGTYPE_INT, ARG_NOMINMAX}, + {"trk_header", &opt_trk_header, "Track name processing option ([0]-nrm/1-ign)", "0", ARGTYPE_INT, ARG_NOMINMAX}, + ARG_TERMINATOR }; /******************************************************************************* @@ -74,78 +74,76 @@ arglist_t format_garmin_xt_args[] = { static void format_garmin_xt_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void format_garmin_xt_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static gbuint16 format_garmin_xt_rd_st_attrs(char *p_trk_name, gbuint8 *p_track_color) { - int method = 0; - gbuint16 trackbytes = 0, TrackPoints = 0; - gbuint8 spam = 0; - gbint32 TrackMaxLat = 0, TrackMaxLon = 0, TrackMinLat = 0, TrackMinLon = 0; - char trk_name[30]=""; - // TODO: SHIFT - can't test behaviour, do not have appropriate files - //int ii; - - // get the option for the processing the track name - if ( opt_trk_header ) - { - method = atoi(opt_trk_header); - // if method is out of range set to default - if ((method < 0) || (method > 1)) - { - method = 0; - } - } - // set to RED if not specified - *p_track_color=9; - - trackbytes = gbfgetuint16(fin); - TrackPoints = gbfgetuint16(fin); - - switch (method) - { - case 1: break; // IGNORE - /* TODO: SHIFT - can't test behaviour, do not have appropriate files - case 2: { // SHIFTED method - spam = gbfgetc(fin); - gbfread(&trk_name, 30, DATABLOCKSIZE, fin); - gbfseek(fin, -1, SEEK_CUR); - for (ii = 0; ii<29; ii++) - { - trk_name[ii] = (trk_name[ii] >> 2) + ( trk_name[ii+1] % 4 ) * 64; - } - } - break; - */ - default: { // NORMAL - spam = gbfgetc(fin); - gbfread(&trk_name, 30, DATABLOCKSIZE, fin); - gbfseek(fin, -1, SEEK_CUR); - } - break; - } - spam = gbfgetc(fin); - - gbfread(&TrackMaxLat, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMaxLon, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMinLat, 3, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - gbfread(&TrackMinLon, 3, DATABLOCKSIZE, fin); - gbfread(p_track_color, 1, DATABLOCKSIZE, fin); - gbfread(&spam, 1, DATABLOCKSIZE, fin); - - strcpy( p_trk_name, trk_name ); - return trackbytes; + int method = 0; + gbuint16 trackbytes = 0, TrackPoints = 0; + gbuint8 spam = 0; + gbint32 TrackMaxLat = 0, TrackMaxLon = 0, TrackMinLat = 0, TrackMinLon = 0; + char trk_name[30]=""; + // TODO: SHIFT - can't test behaviour, do not have appropriate files + //int ii; + + // get the option for the processing the track name + if (opt_trk_header) { + method = atoi(opt_trk_header); + // if method is out of range set to default + if ((method < 0) || (method > 1)) { + method = 0; + } + } + // set to RED if not specified + *p_track_color=9; + + trackbytes = gbfgetuint16(fin); + TrackPoints = gbfgetuint16(fin); + + switch (method) { + case 1: + break; // IGNORE + /* TODO: SHIFT - can't test behaviour, do not have appropriate files + case 2: { // SHIFTED method + spam = gbfgetc(fin); + gbfread(&trk_name, 30, DATABLOCKSIZE, fin); + gbfseek(fin, -1, SEEK_CUR); + for (ii = 0; ii<29; ii++) + { + trk_name[ii] = (trk_name[ii] >> 2) + ( trk_name[ii+1] % 4 ) * 64; + } + } + break; + */ + default: { // NORMAL + spam = gbfgetc(fin); + gbfread(&trk_name, 30, DATABLOCKSIZE, fin); + gbfseek(fin, -1, SEEK_CUR); + } + break; + } + spam = gbfgetc(fin); + + gbfread(&TrackMaxLat, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMaxLon, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMinLat, 3, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + gbfread(&TrackMinLon, 3, DATABLOCKSIZE, fin); + gbfread(p_track_color, 1, DATABLOCKSIZE, fin); + gbfread(&spam, 1, DATABLOCKSIZE, fin); + + strcpy(p_trk_name, trk_name); + return trackbytes; } /* @@ -154,19 +152,16 @@ format_garmin_xt_rd_st_attrs(char *p_trk_name, gbuint8 *p_track_color) static void format_garmin_xt_decrypt_trk_blk(int Count, gbuint8 TrackBlock[]) { - gbuint8 i,j = 12; - while (j<(Count-1)) - { - for ( i = j; i < Count; i++) - { - TrackBlock[i] = TrackBlock[i] >> 1; - if (i<(Count)) - { - TrackBlock[i] = TrackBlock[i] + (TrackBlock[i+1] % 2) * 128; - } - } - j+=12; - } + gbuint8 i,j = 12; + while (j<(Count-1)) { + for (i = j; i < Count; i++) { + TrackBlock[i] = TrackBlock[i] >> 1; + if (i<(Count)) { + TrackBlock[i] = TrackBlock[i] + (TrackBlock[i+1] % 2) * 128; + } + } + j+=12; + } } /* @@ -174,49 +169,47 @@ format_garmin_xt_decrypt_trk_blk(int Count, gbuint8 TrackBlock[]) */ static void format_garmin_xt_decomp_trk_blk(gbuint8 ii, gbuint8 TrackBlock[], double *Ele, double *Lat, double *Lon, gbuint32 *Time) -{ - gbuint32 LatLW = 0, LonLW = 0, TimeLW = 0; - double LatF = 0, LonF = 0; - gbuint16 PrevEleW; - - //printf("%d %d %d %d %d %d\n", TrackBlock[0], TrackBlock[1], TrackBlock[2], TrackBlock[3], TrackBlock[4], TrackBlock[5]); - PrevEleW = TrackBlock[ ( ii - 1 ) * 12 + 1 ]; - PrevEleW = PrevEleW << 8; - PrevEleW = PrevEleW + TrackBlock[ ( ii - 1 ) * 12 ]; - *Ele = (double)PrevEleW * GARMIN_XT_ELE - 1500; - - LatLW = TrackBlock[(ii - 1) * 12 + 4]; - LatLW = LatLW << 8; - LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 3]; - LatLW = LatLW << 8; - LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 2]; - LatF = (double)LatLW; - if (LatF > 8388608) - { - LatF = LatF - 16777216; - } - *Lat = LatF * 360 / 16777216; - - LonLW = TrackBlock[(ii-1)*12+7]; - LonLW = LonLW << 8; - LonLW = LonLW+TrackBlock[(ii-1)*12+6]; - LonLW = LonLW << 8; - LonLW = LonLW+TrackBlock[(ii-1)*12+5]; - LonF = (double)LonLW; - if (LonF>8388608) - { - LonF = LonF - 16777216; - } - *Lon = LonF * 360 / 16777216; - - TimeLW = TrackBlock[(ii - 1) * 12 + 11]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 10]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 9]; - TimeLW = TimeLW << 8; - TimeLW = TimeLW + TrackBlock[(ii - 1) * 12 + 8]; - *Time = TimeLW + 631065600; +{ + gbuint32 LatLW = 0, LonLW = 0, TimeLW = 0; + double LatF = 0, LonF = 0; + gbuint16 PrevEleW; + + //printf("%d %d %d %d %d %d\n", TrackBlock[0], TrackBlock[1], TrackBlock[2], TrackBlock[3], TrackBlock[4], TrackBlock[5]); + PrevEleW = TrackBlock[(ii - 1) * 12 + 1 ]; + PrevEleW = PrevEleW << 8; + PrevEleW = PrevEleW + TrackBlock[(ii - 1) * 12 ]; + *Ele = (double)PrevEleW * GARMIN_XT_ELE - 1500; + + LatLW = TrackBlock[(ii - 1) * 12 + 4]; + LatLW = LatLW << 8; + LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 3]; + LatLW = LatLW << 8; + LatLW = LatLW + TrackBlock[(ii - 1) * 12 + 2]; + LatF = (double)LatLW; + if (LatF > 8388608) { + LatF = LatF - 16777216; + } + *Lat = LatF * 360 / 16777216; + + LonLW = TrackBlock[(ii-1)*12+7]; + LonLW = LonLW << 8; + LonLW = LonLW+TrackBlock[(ii-1)*12+6]; + LonLW = LonLW << 8; + LonLW = LonLW+TrackBlock[(ii-1)*12+5]; + LonF = (double)LonLW; + if (LonF>8388608) { + LonF = LonF - 16777216; + } + *Lon = LonF * 360 / 16777216; + + TimeLW = TrackBlock[(ii - 1) * 12 + 11]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 10]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW+TrackBlock[(ii - 1) * 12 + 9]; + TimeLW = TimeLW << 8; + TimeLW = TimeLW + TrackBlock[(ii - 1) * 12 + 8]; + *Time = TimeLW + 631065600; } /* @@ -225,12 +218,12 @@ format_garmin_xt_decomp_trk_blk(gbuint8 ii, gbuint8 TrackBlock[], double *Ele, d static void format_garmin_xt_decomp_last_ele(gbuint8 ii, double *PrevEle, gbuint8 TrackBlock[]) { - gbuint16 PrevEleW; + gbuint16 PrevEleW; - PrevEleW = TrackBlock[ii - 1]; - PrevEleW = PrevEleW << 8; - PrevEleW = PrevEleW + TrackBlock[ii - 2]; - *PrevEle = (double)PrevEleW * GARMIN_XT_ELE - 1500; + PrevEleW = TrackBlock[ii - 1]; + PrevEleW = PrevEleW << 8; + PrevEleW = PrevEleW + TrackBlock[ii - 2]; + *PrevEle = (double)PrevEleW * GARMIN_XT_ELE - 1500; } /* @@ -239,211 +232,205 @@ format_garmin_xt_decomp_last_ele(gbuint8 ii, double *PrevEle, gbuint8 TrackBlock static void format_garmin_xt_proc_strk(void) { - int Count = 0; // Used to obtain number of read bytes - int NumberOfTracks = 0, TracksCompleted = 0; // Number of tracks in the file and number of processed tracks - gbuint16 trackbytes = 0; // Bytes in track - gbuint8 TrackBlock[STRK_BLOCK_SIZE]; // File Block - gbuint8 ii; // temp variable - double Lat = 0, Lon = 0; // wpt data - double PrevLat = 0, PrevLon = 0, PrevEle = 0; // wpt data - gbuint32 Time = 0, PrevTime =0; // wpt data - int FirstCoo; - gbuint8 trk_color = 0xff; - - // Skip 12 bytes from the BOF - gbfseek(fin, 12, SEEK_SET); - - // read # of tracks - NumberOfTracks = gbfgetuint16(fin); - - // Skip 2 bytes - gbfseek(fin, 2, SEEK_CUR); - - // Process all tracks one by one - while ((TracksCompleted < NumberOfTracks) && (!gbfeof( fin ) ) ) - { - route_head *tmp_track; - waypoint *wpt; - char *trk_name; - trk_name = xmalloc(30); - - // Generate Track Header - trackbytes = format_garmin_xt_rd_st_attrs(trk_name, &trk_color) - 50; - - tmp_track = route_head_alloc(); - // update track color - tmp_track->line_color.bbggrr = colors[trk_color]; - tmp_track->line_color.opacity = 255; - // update track name - tmp_track->rte_name = trk_name; - track_add_head(tmp_track); - - // This is the 1st coordinate of the track - FirstCoo = TRUE; - while (trackbytes>0) - { - if (trackbytes>=STRK_BLOCK_SIZE) - { - Count = gbfread(&TrackBlock, DATABLOCKSIZE, STRK_BLOCK_SIZE, fin); - trackbytes -= STRK_BLOCK_SIZE; - } - else - { - Count = gbfread(&TrackBlock, DATABLOCKSIZE, trackbytes, fin); - trackbytes = 0; - } - - // decrypt loaded track block (Count - size of loaded TrackBlock) - format_garmin_xt_decrypt_trk_blk(Count, TrackBlock); - - // process each track point in the loaded TrackBlock - for (ii=1; ii <= ((Count-1) / 12); ii++) - { - // decompose loaded track block part (track point) - format_garmin_xt_decomp_trk_blk(ii, TrackBlock, &PrevEle, &Lat, &Lon, &Time); - - // Add point to the track if not the first point - if (!FirstCoo) - { - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = PrevLat; /* Degrees */ - wpt->longitude = PrevLon; /* Degrees */ - wpt->altitude = PrevEle; /* Meters. */ - wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ - - // add way point to the track - track_add_wpt(tmp_track, wpt); - } - else - { - FirstCoo = FALSE; - } - PrevLat = Lat; - PrevLon = Lon; - PrevTime = Time; - } - } - - // decompose elevation for the last point - if (Count > 12) - { - Count--; - } - format_garmin_xt_decomp_last_ele(Count, &PrevEle, TrackBlock); - - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = PrevLat; /* Degrees */ - wpt->longitude = PrevLon; /* Degrees */ - wpt->altitude = PrevEle; /* Meters. */ - wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ - - // add way point to the track - track_add_wpt(tmp_track, wpt); - - // update completed tracks counter - TracksCompleted++; - } + int Count = 0; // Used to obtain number of read bytes + int NumberOfTracks = 0, TracksCompleted = 0; // Number of tracks in the file and number of processed tracks + gbuint16 trackbytes = 0; // Bytes in track + gbuint8 TrackBlock[STRK_BLOCK_SIZE]; // File Block + gbuint8 ii; // temp variable + double Lat = 0, Lon = 0; // wpt data + double PrevLat = 0, PrevLon = 0, PrevEle = 0; // wpt data + gbuint32 Time = 0, PrevTime =0; // wpt data + int FirstCoo; + gbuint8 trk_color = 0xff; + + // Skip 12 bytes from the BOF + gbfseek(fin, 12, SEEK_SET); + + // read # of tracks + NumberOfTracks = gbfgetuint16(fin); + + // Skip 2 bytes + gbfseek(fin, 2, SEEK_CUR); + + // Process all tracks one by one + while ((TracksCompleted < NumberOfTracks) && (!gbfeof(fin))) { + route_head *tmp_track; + waypoint *wpt; + char *trk_name; + trk_name = xmalloc(30); + + // Generate Track Header + trackbytes = format_garmin_xt_rd_st_attrs(trk_name, &trk_color) - 50; + + tmp_track = route_head_alloc(); + // update track color + tmp_track->line_color.bbggrr = colors[trk_color]; + tmp_track->line_color.opacity = 255; + // update track name + tmp_track->rte_name = trk_name; + track_add_head(tmp_track); + + // This is the 1st coordinate of the track + FirstCoo = TRUE; + while (trackbytes>0) { + if (trackbytes>=STRK_BLOCK_SIZE) { + Count = gbfread(&TrackBlock, DATABLOCKSIZE, STRK_BLOCK_SIZE, fin); + trackbytes -= STRK_BLOCK_SIZE; + } else { + Count = gbfread(&TrackBlock, DATABLOCKSIZE, trackbytes, fin); + trackbytes = 0; + } + + // decrypt loaded track block (Count - size of loaded TrackBlock) + format_garmin_xt_decrypt_trk_blk(Count, TrackBlock); + + // process each track point in the loaded TrackBlock + for (ii=1; ii <= ((Count-1) / 12); ii++) { + // decompose loaded track block part (track point) + format_garmin_xt_decomp_trk_blk(ii, TrackBlock, &PrevEle, &Lat, &Lon, &Time); + + // Add point to the track if not the first point + if (!FirstCoo) { + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = PrevLat; /* Degrees */ + wpt->longitude = PrevLon; /* Degrees */ + wpt->altitude = PrevEle; /* Meters. */ + wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ + + // add way point to the track + track_add_wpt(tmp_track, wpt); + } else { + FirstCoo = FALSE; + } + PrevLat = Lat; + PrevLon = Lon; + PrevTime = Time; + } + } + + // decompose elevation for the last point + if (Count > 12) { + Count--; + } + format_garmin_xt_decomp_last_ele(Count, &PrevEle, TrackBlock); + + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = PrevLat; /* Degrees */ + wpt->longitude = PrevLon; /* Degrees */ + wpt->altitude = PrevEle; /* Meters. */ + wpt->creation_time = Time; /* Unix Time adjusted to Garmin time */ + + // add way point to the track + track_add_wpt(tmp_track, wpt); + + // update completed tracks counter + TracksCompleted++; + } } static void format_garmin_xt_proc_atrk(void) { - gbuint16 block=0, uu=0; - gbuint32 Lat=0, Lon=0; - gbuint32 Tim=0; - double LatF = 0, LonF = 0, AltF = 0; - waypoint *wpt; - int method = 0; - unsigned char buf[3]; - gbint32 num_trackpoints; - - // get the option for the processing the track name - if ( opt_trk_header ) - { - method = atoi(opt_trk_header); - } - - if (! track) { - track = route_head_alloc(); - // header option was not set to ignore - if ( method !=1 ) - { - track->rte_name = xstrdup("ATRK XT"); - } - track_add_head(track); - } - - // We think the word at offset 0xc is the trackpoint count. - gbfseek(fin, 12, SEEK_SET); - num_trackpoints = gbfgetuint32(fin); - - while (num_trackpoints--) { - block = gbfgetuint16(fin); - if (block != 0x0c) - break; - - gbfread(&buf, 3, DATABLOCKSIZE, fin); //1. Lat - Lat = buf[0] | (buf[1] << 8) | (buf[2] << 16); - gbfread(&buf, 3, DATABLOCKSIZE, fin); //2. Lon - Lon = buf[0] | (buf[1] << 8) | (buf[2] << 16); - - uu = gbfgetuint16(fin); - Tim = gbfgetuint32(fin); - - Tim += 631065600; // adjustment to UnixTime - LatF = Lat; - if (LatF>8388608) {LatF -= 16777216;}; - LonF = Lon; - if (LonF>8388608) {LonF -= 16777216;}; - AltF = (double)uu * GARMIN_XT_ELE - 1500; - - //create new waypoint - wpt = waypt_new(); - - //populate wpt; - wpt->latitude = LatF*180/16777216; /* Degrees */ - wpt->longitude = LonF*360/16777216; /* Degrees */ - wpt->altitude = AltF; /* Meters. */ - wpt->creation_time = Tim; /* Unix Time adjusted to Garmin time */ - - track_add_wpt(track, wpt); - } + gbuint16 block=0, uu=0; + gbuint32 Lat=0, Lon=0; + gbuint32 Tim=0; + double LatF = 0, LonF = 0, AltF = 0; + waypoint *wpt; + int method = 0; + unsigned char buf[3]; + gbint32 num_trackpoints; + + // get the option for the processing the track name + if (opt_trk_header) { + method = atoi(opt_trk_header); + } + + if (! track) { + track = route_head_alloc(); + // header option was not set to ignore + if (method !=1) { + track->rte_name = xstrdup("ATRK XT"); + } + track_add_head(track); + } + + // We think the word at offset 0xc is the trackpoint count. + gbfseek(fin, 12, SEEK_SET); + num_trackpoints = gbfgetuint32(fin); + + while (num_trackpoints--) { + block = gbfgetuint16(fin); + if (block != 0x0c) { + break; + } + + gbfread(&buf, 3, DATABLOCKSIZE, fin); //1. Lat + Lat = buf[0] | (buf[1] << 8) | (buf[2] << 16); + gbfread(&buf, 3, DATABLOCKSIZE, fin); //2. Lon + Lon = buf[0] | (buf[1] << 8) | (buf[2] << 16); + + uu = gbfgetuint16(fin); + Tim = gbfgetuint32(fin); + + Tim += 631065600; // adjustment to UnixTime + LatF = Lat; + if (LatF>8388608) { + LatF -= 16777216; + }; + LonF = Lon; + if (LonF>8388608) { + LonF -= 16777216; + }; + AltF = (double)uu * GARMIN_XT_ELE - 1500; + + //create new waypoint + wpt = waypt_new(); + + //populate wpt; + wpt->latitude = LatF*180/16777216; /* Degrees */ + wpt->longitude = LonF*360/16777216; /* Degrees */ + wpt->altitude = AltF; /* Meters. */ + wpt->creation_time = Tim; /* Unix Time adjusted to Garmin time */ + + track_add_wpt(track, wpt); + } } static void format_garmin_xt_read(void) { - // Saved Tracks file - if ( strcmp(opt_xt_ftype, "STRK") == 0 ) - format_garmin_xt_proc_strk(); - else // Active Track file - format_garmin_xt_proc_atrk(); + // Saved Tracks file + if (strcmp(opt_xt_ftype, "STRK") == 0) { + format_garmin_xt_proc_strk(); + } else { // Active Track file + format_garmin_xt_proc_atrk(); + } } /**************************************************************************/ ff_vecs_t format_garmin_xt_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - format_garmin_xt_rd_init, - NULL, - format_garmin_xt_rd_deinit, - NULL, - format_garmin_xt_read, - NULL, - NULL, - format_garmin_xt_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + format_garmin_xt_rd_init, + NULL, + format_garmin_xt_rd_deinit, + NULL, + format_garmin_xt_read, + NULL, + NULL, + format_garmin_xt_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/gbfile.c b/gpsbabel/gbfile.c index c970d083b..be19f3815 100644 --- a/gpsbabel/gbfile.c +++ b/gpsbabel/gbfile.c @@ -65,175 +65,185 @@ static gbfile * gzapi_open(gbfile *self, const char *mode) { - char openmode[32]; + char openmode[32]; - self->gzapi = 1; + self->gzapi = 1; - /* under non-posix systems files MUST be opened in binary mode */ + /* under non-posix systems files MUST be opened in binary mode */ - strcpy(openmode, mode); - if (strchr(mode, 'b') == NULL) - strncat(openmode, "b", sizeof(openmode)); + strcpy(openmode, mode); + if (strchr(mode, 'b') == NULL) { + strncat(openmode, "b", sizeof(openmode)); + } - if (self->is_pipe) { - FILE *fd; - if (self->mode == 'r') - fd = stdin; - else - fd = stdout; - SET_BINARY_MODE(fd); - self->handle.gz = gzdopen(fileno(fd), openmode); - } - else - self->handle.gz = gzopen(self->name, openmode); + if (self->is_pipe) { + FILE *fd; + if (self->mode == 'r') { + fd = stdin; + } else { + fd = stdout; + } + SET_BINARY_MODE(fd); + self->handle.gz = gzdopen(fileno(fd), openmode); + } else { + self->handle.gz = gzopen(self->name, openmode); + } - if (self->handle.gz == NULL) { - fatal("%s: Cannot %s file '%s'!\n", - self->module, - (self->mode == 'r') ? "open" : "create", - self->name); - } + if (self->handle.gz == NULL) { + fatal("%s: Cannot %s file '%s'!\n", + self->module, + (self->mode == 'r') ? "open" : "create", + self->name); + } - return self; + return self; } static int gzapi_close(gbfile *self) { - return gzclose(self->handle.gz); + return gzclose(self->handle.gz); } static int gzapi_seek(gbfile *self, gbint32 offset, int whence) { - int result; + int result; - assert(whence != SEEK_END); + assert(whence != SEEK_END); - if ((whence == SEEK_CUR) && (self->back != -1)) offset--; - result = gzseek(self->handle.gz, offset, whence); - self->back = -1; + if ((whence == SEEK_CUR) && (self->back != -1)) { + offset--; + } + result = gzseek(self->handle.gz, offset, whence); + self->back = -1; - if (result < 0) { - if (self->is_pipe) - fatal("%s: This format cannot be used in piped commands!\n", self->module); - fatal("%s: online compression not yet supported for this format!", self->module); - } - return 0; + if (result < 0) { + if (self->is_pipe) { + fatal("%s: This format cannot be used in piped commands!\n", self->module); + } + fatal("%s: online compression not yet supported for this format!", self->module); + } + return 0; } static gbsize_t gzapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - int result = 0; - char *target = buf; - int count = size * members; + int result = 0; + char *target = buf; + int count = size * members; - if (self->back != -1) { - *target++ = self->back; - count--; - result++; - self->back = -1; - } - result += gzread(self->handle.gz, target, count); + if (self->back != -1) { + *target++ = self->back; + count--; + result++; + self->back = -1; + } + result += gzread(self->handle.gz, target, count); - /* Check for an incomplete READ */ - if ((members == 1) && (size > 1) && (result > 0) && (result < (int)size)) - fatal("%s: Unexpected end of file (EOF)!\n", self->module); + /* Check for an incomplete READ */ + if ((members == 1) && (size > 1) && (result > 0) && (result < (int)size)) { + fatal("%s: Unexpected end of file (EOF)!\n", self->module); + } - result /= size; + result /= size; - if ((result < 0) || ((gbsize_t)result < members)) { - int errnum; - const char *errtxt; + if ((result < 0) || ((gbsize_t)result < members)) { + int errnum; + const char *errtxt; - errtxt = gzerror(self->handle.gz, &errnum); + errtxt = gzerror(self->handle.gz, &errnum); - /* Workaround for zlib bug: buffer error on empty files */ - if ((errnum == Z_BUF_ERROR) && (gztell(self->handle.gz) == 0)) { - return (gbsize_t) 0; - } - if ((errnum != Z_STREAM_END) && (errnum != 0)) - fatal("%s: zlib returned error %d ('%s')!\n", - self->module, errnum, errtxt); - } - return (gbsize_t) result; + /* Workaround for zlib bug: buffer error on empty files */ + if ((errnum == Z_BUF_ERROR) && (gztell(self->handle.gz) == 0)) { + return (gbsize_t) 0; + } + if ((errnum != Z_STREAM_END) && (errnum != 0)) + fatal("%s: zlib returned error %d ('%s')!\n", + self->module, errnum, errtxt); + } + return (gbsize_t) result; } static gbsize_t gzapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - return gzwrite(self->handle.gz, buf, size * members) / size; + return gzwrite(self->handle.gz, buf, size * members) / size; } static int gzapi_flush(gbfile *self) { - return gzflush(self->handle.gz, Z_SYNC_FLUSH); + return gzflush(self->handle.gz, Z_SYNC_FLUSH); } static gbsize_t gzapi_tell(gbfile *self) { - gbsize_t result; + gbsize_t result; - result = gztell(self->handle.gz); - if (self->back != -1) result--; + result = gztell(self->handle.gz); + if (self->back != -1) { + result--; + } - return result; + return result; } static int gzapi_eof(gbfile *self) { - int res = 0; - - if (self->back != -1) return res; - - res = gzeof(self->handle.gz); - if (!res) { - unsigned char test; - int len = gzread(self->handle.gz, &test, 1); - if (len == 1) { - /* No EOF, put the single byte back into stream */ - self->back = test; - } - else { - /* we are at the end of the file */ - if (global_opts.debug_level > 0) { - /* now gzeof() should return 1 */ - is_fatal(!gzeof(self->handle.gz), "zlib gzeof error!\n"); - } - res = 1; - } - } - return res; + int res = 0; + + if (self->back != -1) { + return res; + } + + res = gzeof(self->handle.gz); + if (!res) { + unsigned char test; + int len = gzread(self->handle.gz, &test, 1); + if (len == 1) { + /* No EOF, put the single byte back into stream */ + self->back = test; + } else { + /* we are at the end of the file */ + if (global_opts.debug_level > 0) { + /* now gzeof() should return 1 */ + is_fatal(!gzeof(self->handle.gz), "zlib gzeof error!\n"); + } + res = 1; + } + } + return res; } static int gzapi_ungetc(const int c, gbfile *self) { - if (self->back == -1) - self->back = c; - else - fatal(MYNAME ": Cannot store more than one byte back!\n"); - return c; + if (self->back == -1) { + self->back = c; + } else { + fatal(MYNAME ": Cannot store more than one byte back!\n"); + } + return c; } static void gzapi_clearerr(gbfile *self) { - gzclearerr(self->handle.gz); + gzclearerr(self->handle.gz); } static int gzapi_error(gbfile *self) { - int errnum; + int errnum; - (void)gzerror(self->handle.gz, &errnum); + (void)gzerror(self->handle.gz, &errnum); - return errnum; + return errnum; } #endif // #if !ZLIB_INHIBITED @@ -245,93 +255,99 @@ gzapi_error(gbfile *self) static gbfile * stdapi_open(gbfile *self, const char *mode) { - self->handle.std = xfopen(self->name, mode, self->module); - return self; + self->handle.std = xfopen(self->name, mode, self->module); + return self; } static int stdapi_close(gbfile *self) { - return fclose(self->handle.std); + return fclose(self->handle.std); } static int stdapi_seek(gbfile *self, gbint32 offset, int whence) { - int result; - gbsize_t pos = 0; - - if (whence != SEEK_SET) pos = ftell(self->handle.std); - - result = fseek(self->handle.std, offset, whence); - if (result != 0) { - switch (whence) { - case SEEK_CUR: - case SEEK_END: pos = pos + offset; break; - case SEEK_SET: pos = offset; break; - default: - fatal("%s: Unknown seek operation (%d) for file %s!\n", - self->module, whence, self->name); - } - fatal("%s: Unable to set file (%s) to position (%llu)!\n", - self->module, self->name, (long long unsigned) pos); - } - return 0; + int result; + gbsize_t pos = 0; + + if (whence != SEEK_SET) { + pos = ftell(self->handle.std); + } + + result = fseek(self->handle.std, offset, whence); + if (result != 0) { + switch (whence) { + case SEEK_CUR: + case SEEK_END: + pos = pos + offset; + break; + case SEEK_SET: + pos = offset; + break; + default: + fatal("%s: Unknown seek operation (%d) for file %s!\n", + self->module, whence, self->name); + } + fatal("%s: Unable to set file (%s) to position (%llu)!\n", + self->module, self->name, (long long unsigned) pos); + } + return 0; } static gbsize_t stdapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - int errno; - gbsize_t result = fread(buf, size, members, self->handle.std); + int errno; + gbsize_t result = fread(buf, size, members, self->handle.std); - if ((result < members) && (errno = ferror(self->handle.std))) { - fatal("%s: Error %d occured during read of file '%s'!\n", - self->module, errno, self->name); - } - return result; + if ((result < members) && (errno = ferror(self->handle.std))) { + fatal("%s: Error %d occured during read of file '%s'!\n", + self->module, errno, self->name); + } + return result; } static gbsize_t stdapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - return fwrite(buf, size, members, self->handle.std); + return fwrite(buf, size, members, self->handle.std); } static int stdapi_flush(gbfile *self) { - return fflush(self->handle.std); + return fflush(self->handle.std); } static gbsize_t stdapi_tell(gbfile *self) { - return ftell(self->handle.std); + return ftell(self->handle.std); } static int stdapi_eof(gbfile *self) { - return feof(self->handle.std); + return feof(self->handle.std); } static int stdapi_ungetc(const int c, gbfile *self) { - return ungetc(c, self->handle.std); + return ungetc(c, self->handle.std); } static void stdapi_clearerr(gbfile *self) { - clearerr(self->handle.std); + clearerr(self->handle.std); } static int stdapi_error(gbfile *self) { - return ferror(self->handle.std); + return ferror(self->handle.std); } @@ -342,116 +358,129 @@ stdapi_error(gbfile *self) static gbfile * memapi_open(gbfile *self, const char *mode) { - self->mempos = 0; - self->memsz = 0; - self->handle.mem = NULL; + self->mempos = 0; + self->memsz = 0; + self->handle.mem = NULL; - return self; + return self; } static int memapi_close(gbfile *self) { - if (self->handle.mem) xfree(self->handle.mem); + if (self->handle.mem) { + xfree(self->handle.mem); + } - return 0; + return 0; } static int memapi_seek(gbfile *self, gbint32 offset, int whence) { - long long pos = (int)self->mempos; + long long pos = (int)self->mempos; - switch (whence) { - case SEEK_CUR: - case SEEK_END: pos = pos + offset; break; - case SEEK_SET: pos = offset; break; - } + switch (whence) { + case SEEK_CUR: + case SEEK_END: + pos = pos + offset; + break; + case SEEK_SET: + pos = offset; + break; + } - if ((pos < 0) || (pos > self->memlen)) return -1; + if ((pos < 0) || (pos > self->memlen)) { + return -1; + } - self->mempos = pos; - return 0; + self->mempos = pos; + return 0; } static gbsize_t memapi_read(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - gbsize_t count; - gbsize_t result = (self->memlen - self->mempos) / size; + gbsize_t count; + gbsize_t result = (self->memlen - self->mempos) / size; - if (result > members) result = members; - count = result * size; - if (count) { - memcpy(buf, self->handle.mem + self->mempos, count); - self->mempos += count; - } + if (result > members) { + result = members; + } + count = result * size; + if (count) { + memcpy(buf, self->handle.mem + self->mempos, count); + self->mempos += count; + } - return result; + return result; } static gbsize_t memapi_write(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self) { - gbsize_t count; + gbsize_t count; - if ((size == 0) && (members == 0)) { /* truncate stream */ - self->memlen = self->mempos; - return 0; - } + if ((size == 0) && (members == 0)) { /* truncate stream */ + self->memlen = self->mempos; + return 0; + } - count = size * members; + count = size * members; - if (self->mempos + count > self->memsz) { - self->memsz = ((self->mempos + count + 4095) / 4096) * 4096; - self->handle.mem = xrealloc(self->handle.mem, self->memsz); - } - memcpy(self->handle.mem + self->mempos, buf, count); - self->mempos += count; - if (self->mempos > self->memlen) self->memlen = self->mempos; + if (self->mempos + count > self->memsz) { + self->memsz = ((self->mempos + count + 4095) / 4096) * 4096; + self->handle.mem = xrealloc(self->handle.mem, self->memsz); + } + memcpy(self->handle.mem + self->mempos, buf, count); + self->mempos += count; + if (self->mempos > self->memlen) { + self->memlen = self->mempos; + } - return members; + return members; } static int memapi_flush(gbfile *self) { - return 0; + return 0; } static gbsize_t memapi_tell(gbfile *self) { - return self->mempos; + return self->mempos; } static int memapi_eof(gbfile *self) { - return (self->mempos == self->memlen); + return (self->mempos == self->memlen); } static int memapi_ungetc(const int c, gbfile *self) { - if (self->mempos == 0) return EOF; - else { - self->mempos--; - self->handle.mem[self->mempos] = (unsigned char) c; - return c; - } + if (self->mempos == 0) { + return EOF; + } else { + self->mempos--; + self->handle.mem[self->mempos] = (unsigned char) c; + return c; + } } static void memapi_clearerr(gbfile *self) { - return; + return; } static int memapi_error(gbfile *self) { - return 0; + return 0; } @@ -464,107 +493,105 @@ memapi_error(gbfile *self) gbfile * gbfopen(const char *filename, const char *mode, const char *module) { - gbfile *file; - const char *m; - int len; + gbfile *file; + const char *m; + int len; - file = xcalloc(1, sizeof(*file)); + file = xcalloc(1, sizeof(*file)); - file->module = xstrdup(module); - file->mode = 'r'; // default - file->binary = (strchr(mode, 'b') != NULL); - file->back = -1; - file->memapi = (filename == NULL); + file->module = xstrdup(module); + file->mode = 'r'; // default + file->binary = (strchr(mode, 'b') != NULL); + file->back = -1; + file->memapi = (filename == NULL); - for (m = mode; *m; m++) { - switch(tolower(*m)) { - case 'r': - file->mode = 'r'; + for (m = mode; *m; m++) { + switch (tolower(*m)) { + case 'r': + file->mode = 'r'; #if !ZLIB_INHIBITED - file->gzapi = 1; /* native or transparent */ + file->gzapi = 1; /* native or transparent */ #endif - break; - case 'w': - file->mode = 'w'; - break; - } - } - - if (file->memapi) { - file->gzapi = 0; - file->name = xstrdup("(Memory stream)"); - - file->fileclearerr = memapi_clearerr; - file->fileclose = memapi_close; - file->fileeof = memapi_eof; - file->fileerror = memapi_error; - file->fileflush = memapi_flush; - file->fileopen = memapi_open; - file->fileread = memapi_read; - file->fileseek = memapi_seek; - file->filetell = memapi_tell; - file->fileungetc = memapi_ungetc; - file->filewrite = memapi_write; - } - else { - file->name = xstrdup(filename); - file->is_pipe = (strcmp(filename, "-") == 0); - - /* Do we have a '.gz' extension in the filename ? */ - len = strlen(file->name); - if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { + break; + case 'w': + file->mode = 'w'; + break; + } + } + + if (file->memapi) { + file->gzapi = 0; + file->name = xstrdup("(Memory stream)"); + + file->fileclearerr = memapi_clearerr; + file->fileclose = memapi_close; + file->fileeof = memapi_eof; + file->fileerror = memapi_error; + file->fileflush = memapi_flush; + file->fileopen = memapi_open; + file->fileread = memapi_read; + file->fileseek = memapi_seek; + file->filetell = memapi_tell; + file->fileungetc = memapi_ungetc; + file->filewrite = memapi_write; + } else { + file->name = xstrdup(filename); + file->is_pipe = (strcmp(filename, "-") == 0); + + /* Do we have a '.gz' extension in the filename ? */ + len = strlen(file->name); + if ((len > 3) && (case_ignore_strcmp(&file->name[len-3], ".gz") == 0)) { #if !ZLIB_INHIBITED - /* force gzipped files on output */ - file->gzapi = 1; + /* force gzipped files on output */ + file->gzapi = 1; #else - fatal(NO_ZLIB); + fatal(NO_ZLIB); #endif - } + } - if (file->gzapi) { + if (file->gzapi) { #if !ZLIB_INHIBITED - file->fileclearerr = gzapi_clearerr; - file->fileclose = gzapi_close; - file->fileeof = gzapi_eof; - file->fileerror = gzapi_error; - file->fileflush = gzapi_flush; - file->fileopen = gzapi_open; - file->fileread = gzapi_read; - file->fileseek = gzapi_seek; - file->filetell = gzapi_tell; - file->fileungetc = gzapi_ungetc; - file->filewrite = gzapi_write; + file->fileclearerr = gzapi_clearerr; + file->fileclose = gzapi_close; + file->fileeof = gzapi_eof; + file->fileerror = gzapi_error; + file->fileflush = gzapi_flush; + file->fileopen = gzapi_open; + file->fileread = gzapi_read; + file->fileseek = gzapi_seek; + file->filetell = gzapi_tell; + file->fileungetc = gzapi_ungetc; + file->filewrite = gzapi_write; #else - /* This is the only runtime test we make */ - fatal("%s: Zlib was not included in this build.\n", file->module); + /* This is the only runtime test we make */ + fatal("%s: Zlib was not included in this build.\n", file->module); #endif - } - else { - file->fileclearerr = stdapi_clearerr; - file->fileclose = stdapi_close; - file->fileeof = stdapi_eof; - file->fileerror = stdapi_error; - file->fileflush = stdapi_flush; - file->fileopen = stdapi_open; - file->fileread = stdapi_read; - file->fileseek = stdapi_seek; - file->filetell = stdapi_tell; - file->fileungetc = stdapi_ungetc; - file->filewrite = stdapi_write; - } - } - - file->fileopen(file, mode); + } else { + file->fileclearerr = stdapi_clearerr; + file->fileclose = stdapi_close; + file->fileeof = stdapi_eof; + file->fileerror = stdapi_error; + file->fileflush = stdapi_flush; + file->fileopen = stdapi_open; + file->fileread = stdapi_read; + file->fileseek = stdapi_seek; + file->filetell = stdapi_tell; + file->fileungetc = stdapi_ungetc; + file->filewrite = stdapi_write; + } + } + + file->fileopen(file, mode); #ifdef DEBUG_MEM - file->buffsz = 1; + file->buffsz = 1; #else - file->buffsz = 256; + file->buffsz = 256; #endif - file->buff = xmalloc(file->buffsz); + file->buff = xmalloc(file->buffsz); - return file; + return file; } /* @@ -574,12 +601,12 @@ gbfopen(const char *filename, const char *mode, const char *module) gbfile * gbfopen_be(const char *filename, const char *mode, const char *module) { - gbfile *result; + gbfile *result; - result = gbfopen(filename, mode, module); - result->big_endian = 1; + result = gbfopen(filename, mode, module); + result->big_endian = 1; - return result; + return result; } /* @@ -589,14 +616,16 @@ gbfopen_be(const char *filename, const char *mode, const char *module) void gbfclose(gbfile *file) { - if (!file) return; + if (!file) { + return; + } - file->fileclose(file); + file->fileclose(file); - xfree(file->name); - xfree(file->module); - xfree(file->buff); - xfree(file); + xfree(file->name); + xfree(file->module); + xfree(file->buff); + xfree(file); } /* @@ -606,15 +635,14 @@ gbfclose(gbfile *file) int gbfgetc(gbfile *file) { - unsigned char c; + unsigned char c; - /* errors are caught in gbfread */ - if (gbfread(&c, 1, 1, file) == 0) { - return EOF; - } - else { - return (unsigned int)c; - } + /* errors are caught in gbfread */ + if (gbfread(&c, 1, 1, file) == 0) { + return EOF; + } else { + return (unsigned int)c; + } } /* @@ -624,26 +652,30 @@ gbfgetc(gbfile *file) char * gbfgets(char *buf, int len, gbfile *file) { - char *result = buf; + char *result = buf; - while (--len > 0) { - int c = gbfgetc(file); + while (--len > 0) { + int c = gbfgetc(file); - if (c == EOF) break; + if (c == EOF) { + break; + } - *(unsigned char *)buf = (unsigned char)c; - buf++; + *(unsigned char *)buf = (unsigned char)c; + buf++; - if (c == '\r') { - c = gbfgetc(file); - if ((c != '\n') && (c != EOF)) gbfungetc(c, file); - break; - } - else if (c == '\n') - break; - } - *buf = '\0'; - return (*result != '\0') ? result : NULL; + if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) { + gbfungetc(c, file); + } + break; + } else if (c == '\n') { + break; + } + } + *buf = '\0'; + return (*result != '\0') ? result : NULL; } /* @@ -653,8 +685,10 @@ gbfgets(char *buf, int len, gbfile *file) gbsize_t gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) { - if ((size == 0) || (members == 0)) return 0; - return file->fileread(buf, size, members, file); + if ((size == 0) || (members == 0)) { + return 0; + } + return file->fileread(buf, size, members, file); } /* @@ -663,38 +697,40 @@ gbfread(void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) int gbvfprintf(gbfile *file, const char *format, va_list ap) { - int len; - - for (;;) { - va_list args; - - va_copy(args, ap); - len = vsnprintf(file->buff, file->buffsz, format, args); - va_end(args); - - /* Unambiguous Success */ - if ((len > -1) && (len < file->buffsz)) - break; - - /* First case: C99 behaviour. Len is correctly sized. - * add space for null terminator. Next time through the - * loop we're guaranteed success. - * - * Second case: SUS (and Windows) behaviour. We know it - * doesn't fit, but we don't know how big it has to be. -` * double it and try again. We'll loop until we succeed. - * - * Since we keep the I/O buffer in the file handle, we - * quickly reach a steady state on the size of these buffers. - */ - if (len > -1) - file->buffsz = len + 1; - else - file->buffsz *= 2; - - file->buff = xrealloc(file->buff, file->buffsz); - } - return gbfwrite(file->buff, 1, len, file); + int len; + + for (;;) { + va_list args; + + va_copy(args, ap); + len = vsnprintf(file->buff, file->buffsz, format, args); + va_end(args); + + /* Unambiguous Success */ + if ((len > -1) && (len < file->buffsz)) { + break; + } + + /* First case: C99 behaviour. Len is correctly sized. + * add space for null terminator. Next time through the + * loop we're guaranteed success. + * + * Second case: SUS (and Windows) behaviour. We know it + * doesn't fit, but we don't know how big it has to be. + ` * double it and try again. We'll loop until we succeed. + * + * Since we keep the I/O buffer in the file handle, we + * quickly reach a steady state on the size of these buffers. + */ + if (len > -1) { + file->buffsz = len + 1; + } else { + file->buffsz *= 2; + } + + file->buff = xrealloc(file->buff, file->buffsz); + } + return gbfwrite(file->buff, 1, len, file); } /* @@ -704,14 +740,14 @@ int gbvfprintf(gbfile *file, const char *format, va_list ap) int gbfprintf(gbfile *file, const char *format, ...) { - va_list args; - int result; + va_list args; + int result; - va_start(args, format); - result = gbvfprintf(file, format, args); - va_end(args); + va_start(args, format); + result = gbvfprintf(file, format, args); + va_end(args); - return result; + return result; } /* @@ -721,11 +757,11 @@ gbfprintf(gbfile *file, const char *format, ...) int gbfputc(int c, gbfile *file) { - unsigned char temp = (unsigned int) c; + unsigned char temp = (unsigned int) c; - gbfwrite(&temp, 1, 1, file); + gbfwrite(&temp, 1, 1, file); - return c; + return c; } /* @@ -735,7 +771,7 @@ gbfputc(int c, gbfile *file) int gbfputs(const char *s, gbfile *file) { - return gbfwrite(s, 1, strlen(s), file); + return gbfwrite(s, 1, strlen(s), file); } /* @@ -745,18 +781,18 @@ gbfputs(const char *s, gbfile *file) int gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *file) { - int result; + int result; - result = file->filewrite(buf, size, members, file); - if (result != members) { - fatal("%s: Could not write %lld bytes to %s (result %d)!\n", - file->module, - (long long int) (members - result) * size, - file->name, - result); - } + result = file->filewrite(buf, size, members, file); + if (result != members) { + fatal("%s: Could not write %lld bytes to %s (result %d)!\n", + file->module, + (long long int)(members - result) * size, + file->name, + result); + } - return result; + return result; } /* @@ -766,7 +802,7 @@ gbfwrite(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *f int gbfflush(gbfile *file) { - return file->fileflush(file); + return file->fileflush(file); } /* @@ -776,7 +812,7 @@ gbfflush(gbfile *file) void gbfclearerr(gbfile *file) { - file->fileclearerr(file); + file->fileclearerr(file); } /* @@ -786,7 +822,7 @@ gbfclearerr(gbfile *file) int gbferror(gbfile *file) { - return file->fileerror(file); + return file->fileerror(file); } /* @@ -796,8 +832,8 @@ gbferror(gbfile *file) void gbfrewind(gbfile *file) { - (void) gbfseek(file, 0, SEEK_SET); - gbfclearerr(file); + (void) gbfseek(file, 0, SEEK_SET); + gbfclearerr(file); } /* @@ -807,7 +843,7 @@ gbfrewind(gbfile *file) int gbfseek(gbfile *file, gbint32 offset, int whence) { - return file->fileseek(file, offset, whence); + return file->fileseek(file, offset, whence); } /* @@ -817,11 +853,11 @@ gbfseek(gbfile *file, gbint32 offset, int whence) gbsize_t gbftell(gbfile *file) { - gbsize_t result = file->filetell(file); - if ((signed) result == -1) - fatal("%s: Could not determine position of file '%s'!\n", - file->module, file->name); - return result; + gbsize_t result = file->filetell(file); + if ((signed) result == -1) + fatal("%s: Could not determine position of file '%s'!\n", + file->module, file->name); + return result; } /* @@ -831,7 +867,7 @@ gbftell(gbfile *file) int gbfeof(gbfile *file) { - return file->fileeof(file); + return file->fileeof(file); } /* @@ -841,7 +877,7 @@ gbfeof(gbfile *file) int gbfungetc(const int c, gbfile *file) { - return file->fileungetc(c, file); + return file->fileungetc(c, file); } /* GPSBabel 'file' enhancements */ @@ -853,15 +889,16 @@ gbfungetc(const int c, gbfile *file) gbint32 gbfgetint32(gbfile *file) { - char buf[4]; + char buf[4]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - if (file->big_endian) - return be_read32(buf); - else - return le_read32(buf); + if (file->big_endian) { + return be_read32(buf); + } else { + return le_read32(buf); + } } /* @@ -871,15 +908,16 @@ gbfgetint32(gbfile *file) gbint16 gbfgetint16(gbfile *file) { - char buf[2]; + char buf[2]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - if (file->big_endian) - return be_read16(buf); - else - return le_read16(buf); + if (file->big_endian) { + return be_read16(buf); + } else { + return le_read16(buf); + } } /* @@ -889,12 +927,12 @@ gbfgetint16(gbfile *file) double gbfgetdbl(gbfile *file) { - char buf[8]; + char buf[8]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - return endian_read_double(buf, ! file->big_endian); + return endian_read_double(buf, ! file->big_endian); } /* @@ -904,12 +942,12 @@ gbfgetdbl(gbfile *file) float gbfgetflt(gbfile *file) { - char buf[4]; + char buf[4]; - is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), - "%s: Unexpected end of file (%s)!\n", file->module, file->name); + is_fatal((gbfread(&buf, 1, sizeof(buf), file) != sizeof(buf)), + "%s: Unexpected end of file (%s)!\n", file->module, file->name); - return endian_read_float(buf, ! file->big_endian); + return endian_read_float(buf, ! file->big_endian); } /* @@ -920,29 +958,32 @@ gbfgetflt(gbfile *file) char * gbfgetcstr(gbfile *file) { - char *result; - int len = 0; - char *str = file->buff; + char *result; + int len = 0; + char *str = file->buff; - for (;;) { - int c = gbfgetc(file); + for (;;) { + int c = gbfgetc(file); - if ((c == 0) || (c == EOF)) break; + if ((c == 0) || (c == EOF)) { + break; + } - if (len == file->buffsz) { - file->buffsz += 64; - str = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - str[len] = c; - len++; - } + if (len == file->buffsz) { + file->buffsz += 64; + str = file->buff = xrealloc(file->buff, file->buffsz + 1); + } + str[len] = c; + len++; + } - result = (char *) xmalloc(len + 1); - if (len > 0) - memcpy(result, str, len); - result[len] = '\0'; + result = (char *) xmalloc(len + 1); + if (len > 0) { + memcpy(result, str, len); + } + result[len] = '\0'; - return result; + return result; } /* @@ -953,67 +994,81 @@ gbfgetcstr(gbfile *file) char * gbfgetpstr(gbfile *file) { - int len; - char *result; + int len; + char *result; - len = gbfgetc(file); - result = xmalloc(len + 1); - if (len > 0) { - gbfread(result, 1, len, file); - } - result[len] = '\0'; + len = gbfgetc(file); + result = xmalloc(len + 1); + if (len > 0) { + gbfread(result, 1, len, file); + } + result[len] = '\0'; - return result; + return result; } static char * gbfgetucs2str(gbfile *file) { - int len = 0; - char *result = file->buff; - - for (;;) { - char buff[8]; - int clen; - int c0, c1; - - c0 = gbfgetc(file); - if ((c0 == EOF) && (len == 0)) return NULL; - c1 = gbfgetc(file); - if ((c1 == EOF) && (len == 0)) return NULL; - - if (file->big_endian) c0 = c1 | (c0 << 8); - else c0 = c0 | (c1 << 8); - - if (c0 == '\r') { - - c0 = gbfgetc(file); - if ((c0 == EOF) && (len == 0)) return NULL; - c1 = gbfgetc(file); - if ((c1 == EOF) && (len == 0)) return NULL; - - if (file->big_endian) c0 = c1 | (c0 << 8); - else c0 = c0 | (c1 << 8); - - if (c0 != '\n') - fatal("%s: Invalid unicode (UCS-2/%s endian) line break!\n", - file->module, - file->big_endian ? "Big" : "Little"); - break; - } - - clen = cet_ucs4_to_utf8(buff, sizeof(buff), c0); - - if (len+clen >= file->buffsz) { - file->buffsz += 64; - result = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - memcpy(&result[len], buff, clen); - len += clen; - } - result[len] = '\0'; // terminate resulting string - - return result; + int len = 0; + char *result = file->buff; + + for (;;) { + char buff[8]; + int clen; + int c0, c1; + + c0 = gbfgetc(file); + if ((c0 == EOF) && (len == 0)) { + return NULL; + } + c1 = gbfgetc(file); + if ((c1 == EOF) && (len == 0)) { + return NULL; + } + + if (file->big_endian) { + c0 = c1 | (c0 << 8); + } else { + c0 = c0 | (c1 << 8); + } + + if (c0 == '\r') { + + c0 = gbfgetc(file); + if ((c0 == EOF) && (len == 0)) { + return NULL; + } + c1 = gbfgetc(file); + if ((c1 == EOF) && (len == 0)) { + return NULL; + } + + if (file->big_endian) { + c0 = c1 | (c0 << 8); + } else { + c0 = c0 | (c1 << 8); + } + + if (c0 != '\n') + fatal("%s: Invalid unicode (UCS-2/%s endian) line break!\n", + file->module, + file->big_endian ? "Big" : "Little"); + break; + } + + clen = cet_ucs4_to_utf8(buff, sizeof(buff), c0); + + if (len+clen >= file->buffsz) { + file->buffsz += 64; + result = file->buff = xrealloc(file->buff, file->buffsz + 1); + } + memcpy(&result[len], buff, clen); + len += clen; + } + result[len] = '\0'; // terminate resulting string + + return result; } /* @@ -1024,60 +1079,60 @@ gbfgetucs2str(gbfile *file) char * gbfgetstr(gbfile *file) { - int len = 0; - char *result = file->buff; - - if (file->unicode) return gbfgetucs2str(file); - - for (;;) { - int c = gbfgetc(file); - - if ((c == EOF) || (c == 0x1A)) { - if (len == 0) { - return NULL; - } - break; - } - else if (c == '\r') { - c = gbfgetc(file); - if ((c != '\n') && (c != EOF)) - gbfungetc(c, file); - break; - } - else if (c == '\n') { - break; - } - else if (((c == 0xFE) || (c == 0xFF)) && (! file->unicode_checked)) { - int cx; - int c1 = gbfgetc(file); - if (c1 != EOF) { - cx = c | (c1 << 8); - if (cx == 0xFEFF) { - file->unicode = 1; - file->big_endian = 0; - return gbfgetucs2str(file); - } - else if (cx == 0xFFFE) { - file->unicode = 1; - file->big_endian = 1; - return gbfgetucs2str(file); - } - else gbfungetc(c1, file); - } - } - - file->unicode_checked = 1; - - if ((len + 1) == file->buffsz) { - file->buffsz += 64; - result = file->buff = xrealloc(file->buff, file->buffsz + 1); - } - result[len] = (char)c; - len++; - } - result[len] = '\0'; // terminate resulting string - - return result; + int len = 0; + char *result = file->buff; + + if (file->unicode) { + return gbfgetucs2str(file); + } + + for (;;) { + int c = gbfgetc(file); + + if ((c == EOF) || (c == 0x1A)) { + if (len == 0) { + return NULL; + } + break; + } else if (c == '\r') { + c = gbfgetc(file); + if ((c != '\n') && (c != EOF)) { + gbfungetc(c, file); + } + break; + } else if (c == '\n') { + break; + } else if (((c == 0xFE) || (c == 0xFF)) && (! file->unicode_checked)) { + int cx; + int c1 = gbfgetc(file); + if (c1 != EOF) { + cx = c | (c1 << 8); + if (cx == 0xFEFF) { + file->unicode = 1; + file->big_endian = 0; + return gbfgetucs2str(file); + } else if (cx == 0xFFFE) { + file->unicode = 1; + file->big_endian = 1; + return gbfgetucs2str(file); + } else { + gbfungetc(c1, file); + } + } + } + + file->unicode_checked = 1; + + if ((len + 1) == file->buffsz) { + file->buffsz += 64; + result = file->buff = xrealloc(file->buff, file->buffsz + 1); + } + result[len] = (char)c; + len++; + } + result[len] = '\0'; // terminate resulting string + + return result; } /* @@ -1087,13 +1142,14 @@ gbfgetstr(gbfile *file) int gbfputint16(const gbint16 i, gbfile *file) { - char buf[2]; + char buf[2]; - if (file->big_endian) - be_write16(buf, i); - else - le_write16(buf, i); - return gbfwrite(buf, 1, sizeof(buf), file); + if (file->big_endian) { + be_write16(buf, i); + } else { + le_write16(buf, i); + } + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1103,13 +1159,14 @@ gbfputint16(const gbint16 i, gbfile *file) int gbfputint32(const gbint32 i, gbfile *file) { - char buf[4]; + char buf[4]; - if (file->big_endian) - be_write32(buf, i); - else - le_write32(buf, i); - return gbfwrite(buf, 1, sizeof(buf), file); + if (file->big_endian) { + be_write32(buf, i); + } else { + le_write32(buf, i); + } + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1119,10 +1176,10 @@ gbfputint32(const gbint32 i, gbfile *file) int gbfputdbl(const double d, gbfile *file) { - char buf[8]; + char buf[8]; - endian_write_double(buf, d, ! file->big_endian); - return gbfwrite(buf, 1, sizeof(buf), file); + endian_write_double(buf, d, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1132,10 +1189,10 @@ gbfputdbl(const double d, gbfile *file) int gbfputflt(const float f, gbfile *file) { - char buf[4]; + char buf[4]; - endian_write_float(buf, f, ! file->big_endian); - return gbfwrite(buf, 1, sizeof(buf), file); + endian_write_float(buf, f, ! file->big_endian); + return gbfwrite(buf, 1, sizeof(buf), file); } /* @@ -1146,15 +1203,15 @@ gbfputflt(const float f, gbfile *file) int gbfputcstr(const char *s, gbfile *file) { - int len; + int len; - len = (s == NULL) ? 0 : strlen(s); - if (len > 0) { - return gbfwrite(s, 1, len + 1, file); - } else { - gbfputc(0, file); - return 1; - } + len = (s == NULL) ? 0 : strlen(s); + if (len > 0) { + return gbfwrite(s, 1, len + 1, file); + } else { + gbfputc(0, file); + return 1; + } } /* @@ -1165,15 +1222,17 @@ gbfputcstr(const char *s, gbfile *file) int gbfputpstr(const char *s, gbfile *file) { - int len; + int len; - len = (s == NULL) ? 0 : strlen(s); - if (len > 255) len = 255; /* the maximum size of a standard pascal string */ - gbfputc(len, file); - if (len > 0) { - gbfwrite(s, 1, len, file); - } - return (len + 1); + len = (s == NULL) ? 0 : strlen(s); + if (len > 255) { + len = 255; /* the maximum size of a standard pascal string */ + } + gbfputc(len, file); + if (len > 0) { + gbfwrite(s, 1, len, file); + } + return (len + 1); } /* Much more higher level functions */ @@ -1181,19 +1240,20 @@ gbfputpstr(const char *s, gbfile *file) gbsize_t gbfcopyfrom(gbfile *file, gbfile *src, gbsize_t count) { - char buf[1024]; - gbsize_t copied = 0; - - while (count) { - gbsize_t n = gbfread(buf, 1, (count < sizeof(buf)) ? count : sizeof(buf), src); - if (n > 0) { - gbfwrite(buf, 1, n, file); - count -= n; - copied += n; - } - else break; - } - return copied; + char buf[1024]; + gbsize_t copied = 0; + + while (count) { + gbsize_t n = gbfread(buf, 1, (count < sizeof(buf)) ? count : sizeof(buf), src); + if (n > 0) { + gbfwrite(buf, 1, n, file); + count -= n; + copied += n; + } else { + break; + } + } + return copied; } diff --git a/gpsbabel/gbfile.h b/gpsbabel/gbfile.h index 432c44e6e..2f09a4f9d 100644 --- a/gpsbabel/gbfile.h +++ b/gpsbabel/gbfile.h @@ -32,56 +32,56 @@ struct gbfile_s; typedef struct gbfile_s gbfile; -typedef void (*gbfclearerr_cb) (gbfile *self); -typedef int (*gbfclose_cb) (gbfile *self); -typedef int (*gbfeof_cb) (gbfile *self); -typedef int (*gbferror_cb) (gbfile *self); -typedef int (*gbfflush_cb) (gbfile *self); -typedef gbfile* (*gbfopen_cb) (gbfile *self, const char *mode); -typedef gbsize_t (*gbfread_cb) (void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); -typedef int (*gbfseek_cb) (gbfile *self, gbint32 offset, int whence); -typedef gbsize_t (*gbftell_cb) (gbfile *self); -typedef gbsize_t (*gbfwrite_cb) (const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); -typedef int (*gbfungetc_cb) (const int c, gbfile *self); +typedef void (*gbfclearerr_cb)(gbfile *self); +typedef int (*gbfclose_cb)(gbfile *self); +typedef int (*gbfeof_cb)(gbfile *self); +typedef int (*gbferror_cb)(gbfile *self); +typedef int (*gbfflush_cb)(gbfile *self); +typedef gbfile* (*gbfopen_cb)(gbfile *self, const char *mode); +typedef gbsize_t (*gbfread_cb)(void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); +typedef int (*gbfseek_cb)(gbfile *self, gbint32 offset, int whence); +typedef gbsize_t (*gbftell_cb)(gbfile *self); +typedef gbsize_t (*gbfwrite_cb)(const void *buf, const gbsize_t size, const gbsize_t members, gbfile *self); +typedef int (*gbfungetc_cb)(const int c, gbfile *self); typedef struct gbfile_s { #ifdef DEBUG_MEM - void *dummy; /* ZERO pointer for stdio oop's */ + void *dummy; /* ZERO pointer for stdio oop's */ #endif - union { - FILE *std; - unsigned char *mem; + union { + FILE *std; + unsigned char *mem; #if !ZLIB_INHIBITED - gzFile *gz; + gzFile *gz; #endif - } handle; - char *name; - char *module; - char *buff; /* static growing buffer, primary used by gbprintf */ - int buffsz; - char mode; - int back; - gbsize_t mempos; /* curr. position in memory */ - gbsize_t memlen; /* max. number of written bytes to memory */ - gbsize_t memsz; /* curr. size of allocated memory */ - unsigned char big_endian:1; - unsigned char binary:1; - unsigned char gzapi:1; - unsigned char memapi:1; - unsigned char unicode:1; - unsigned char unicode_checked:1; - unsigned char is_pipe:1; - gbfclearerr_cb fileclearerr; - gbfclose_cb fileclose; - gbfeof_cb fileeof; - gbferror_cb fileerror; - gbfflush_cb fileflush; - gbfopen_cb fileopen; - gbfread_cb fileread; - gbfseek_cb fileseek; - gbftell_cb filetell; - gbfungetc_cb fileungetc; - gbfwrite_cb filewrite; + } handle; + char *name; + char *module; + char *buff; /* static growing buffer, primary used by gbprintf */ + int buffsz; + char mode; + int back; + gbsize_t mempos; /* curr. position in memory */ + gbsize_t memlen; /* max. number of written bytes to memory */ + gbsize_t memsz; /* curr. size of allocated memory */ + unsigned char big_endian:1; + unsigned char binary:1; + unsigned char gzapi:1; + unsigned char memapi:1; + unsigned char unicode:1; + unsigned char unicode_checked:1; + unsigned char is_pipe:1; + gbfclearerr_cb fileclearerr; + gbfclose_cb fileclose; + gbfeof_cb fileeof; + gbferror_cb fileerror; + gbfflush_cb fileflush; + gbfopen_cb fileopen; + gbfread_cb fileread; + gbfseek_cb fileseek; + gbftell_cb filetell; + gbfungetc_cb fileungetc; + gbfwrite_cb filewrite; } gbfile_t; diff --git a/gpsbabel/gbser.c b/gpsbabel/gbser.c index a43777c5a..deefa09aa 100644 --- a/gpsbabel/gbser.c +++ b/gpsbabel/gbser.c @@ -1,6 +1,6 @@ /* Serial interface - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -26,32 +26,38 @@ #include #include -void gbser__db(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vprintf(msg, ap); - } - va_end(ap); +void gbser__db(int l, const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); } /* Set the serial port speed. */ -int gbser_set_speed(void *handle, unsigned speed) { - return gbser_set_port(handle, speed, 8, 0, 1); +int gbser_set_speed(void *handle, unsigned speed) +{ + return gbser_set_port(handle, speed, 8, 0, 1); } -static int parity_letter(char c) { - switch (c) { - case 'N': case 'n': - return 0; - case 'O': case 'o': - return 1; - case 'E': case 'e': - return 2; - default: - return -1; - } +static int parity_letter(char c) +{ + switch (c) { + case 'N': + case 'n': + return 0; + case 'O': + case 'o': + return 1; + case 'E': + case 'e': + return 2; + default: + return -1; + } } /* Set the serial port up by parsing the supplied parameter string. @@ -59,123 +65,141 @@ static int parity_letter(char c) { * insensitive, spaces are allowed around the commas and omitted * trailing fields will default to '8', 'N' and '1' */ -int gbser_setup(void *handle, const char *spec) { - unsigned arg[] = { 4800, 8, 0, 1 }; - int ap; - - for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { - unsigned t = 0; - int pl; - while (isspace(*spec)) { spec++; } - /* Allow 'N', 'O' or 'E' as the parity spec */ - if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { - t = pl; - spec++; - } else { - if (!isdigit(*spec)) { break; } - while (isdigit(*spec)) { t = t * 10 + *spec++ - '0'; } - } - arg[ap] = t; - while (isspace(*spec)) { spec++; } - if (*spec != ',') { break; } - spec++; +int gbser_setup(void *handle, const char *spec) +{ + unsigned arg[] = { 4800, 8, 0, 1 }; + int ap; + + for (ap = 0; ap < sizeof(arg) / sizeof(arg[0]); ap++) { + unsigned t = 0; + int pl; + while (isspace(*spec)) { + spec++; + } + /* Allow 'N', 'O' or 'E' as the parity spec */ + if (ap == 2 && (pl = parity_letter(*spec), pl >= 0)) { + t = pl; + spec++; + } else { + if (!isdigit(*spec)) { + break; + } + while (isdigit(*spec)) { + t = t * 10 + *spec++ - '0'; + } + } + arg[ap] = t; + while (isspace(*spec)) { + spec++; } - - if (*spec != '\0') { - return gbser_ERROR; + if (*spec != ',') { + break; } - - return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); + spec++; + } + + if (*spec != '\0') { + return gbser_ERROR; + } + + return gbser_set_port(handle, arg[0], arg[1], arg[2], arg[3]); } /* Return true if there are characters available on the serial port */ -int gbser_avail(void *handle) { - return gbser__fill_buffer(handle, 1, NULL); +int gbser_avail(void *handle) +{ + return gbser__fill_buffer(handle, 1, NULL); } /* Read as many bytes as are available without blocking. At most |len| * bytes will be read. Returns the number of bytes read or gbser_ERROR if an * error occurs. */ -int gbser_read(void *handle, void *buf, unsigned len) { - int got = 0; - - while (len > 0) { - int rc = gbser__fill_buffer(handle, len, NULL); - if (rc < 0) { - /* error */ - return rc; - } else if (rc == 0) { - /* nothing available */ - break; - } - got += gbser__read_buffer(handle, &buf, &len); - } - - return got; +int gbser_read(void *handle, void *buf, unsigned len) +{ + int got = 0; + + while (len > 0) { + int rc = gbser__fill_buffer(handle, len, NULL); + if (rc < 0) { + /* error */ + return rc; + } else if (rc == 0) { + /* nothing available */ + break; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; } /* Read the specified number of bytes. Block until the requested number * of bytes have been read or the timeout (in ms) is exceeded. */ -int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms) { - int got = 0; - - while (len > 0 && ms != 0) { - int rc; - if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { - return rc; - } - got += gbser__read_buffer(handle, &buf, &len); - } - - return got; +int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms) +{ + int got = 0; + + while (len > 0 && ms != 0) { + int rc; + if (rc = gbser__fill_buffer(handle, len, &ms), rc < 0) { + return rc; + } + got += gbser__read_buffer(handle, &buf, &len); + } + + return got; } /* Read a single character from the port, returning immediately if * none are available. */ -int gbser_readc(void *handle) { - unsigned char buf; - int rc; - - rc = gbser_read(handle, &buf, 1); - if (rc > 0) { - return buf; - } else if (rc == 0) { - return gbser_NOTHING; - } else { - return gbser_ERROR; - } +int gbser_readc(void *handle) +{ + unsigned char buf; + int rc; + + rc = gbser_read(handle, &buf, 1); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } } /* Read a single character from the port, waiting up to |ms| * milliseconds for a character to be available. */ -int gbser_readc_wait(void *handle, unsigned ms) { - unsigned char buf; - int rc; - - rc = gbser_read_wait(handle, &buf, 1, ms); - if (rc > 0) { - return buf; - } else if (rc == 0) { - return gbser_NOTHING; - } else { - return gbser_ERROR; - } +int gbser_readc_wait(void *handle, unsigned ms) +{ + unsigned char buf; + int rc; + + rc = gbser_read_wait(handle, &buf, 1, ms); + if (rc > 0) { + return buf; + } else if (rc == 0) { + return gbser_NOTHING; + } else { + return gbser_ERROR; + } } /* Write a null terminated string in |str| to the serial * port. */ -int gbser_print(void *handle, const char *str) { - return gbser_write(handle, str, (unsigned) strlen(str)); +int gbser_print(void *handle, const char *str) +{ + return gbser_write(handle, str, (unsigned) strlen(str)); } /* Write a single character to the serial port. - */ -int gbser_writec(void *handle, int c) { - return gbser_write(handle, &c, 1); + */ +int gbser_writec(void *handle, int c) +{ + return gbser_write(handle, &c, 1); } diff --git a/gpsbabel/gbser.h b/gpsbabel/gbser.h index 97e871db7..415afb69a 100644 --- a/gpsbabel/gbser.h +++ b/gpsbabel/gbser.h @@ -49,10 +49,10 @@ void gbser_deinit(void *handle); int gbser_set_speed(void *handle, unsigned speed); /* Set the serial port speed, start, parity and stop bits */ -int gbser_set_port(void *handle, unsigned speed, - unsigned bits, - unsigned parity, - unsigned stop); +int gbser_set_port(void *handle, unsigned speed, + unsigned bits, + unsigned parity, + unsigned stop); /* Set the serial port up by parsing the supplied parameter string. * Valid parameter strings look like '4800,8,N,1'. Parsing is case- @@ -81,7 +81,7 @@ int gbser_read_wait(void *handle, void *buf, unsigned len, unsigned ms); * read lines terminated by 0x0A0x0D discarding linefeeds use * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); */ -int gbser_read_line(void *handle, void *buf, +int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, int eol, int discard); @@ -96,7 +96,7 @@ int gbser_readc(void *handle); int gbser_readc_wait(void *handle, unsigned ms); /* Discard any pending input on the serial port. - */ + */ int gbser_flush(void *handle); /* Write |len| bytes from |buf| to the serial port. @@ -109,7 +109,7 @@ int gbser_write(void *handle, const void *buf, unsigned len); int gbser_print(void *handle, const char *str); /* Write a single character to the serial port. - */ + */ int gbser_writec(void *handle, int c); /* Return true if a port name seems to refer to a serial port. @@ -119,10 +119,10 @@ int gbser_writec(void *handle, int c); */ int gbser_is_serial(const char *port_name); -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. diff --git a/gpsbabel/gbser_posix.c b/gpsbabel/gbser_posix.c index ecf1095ad..c3ecbf378 100644 --- a/gpsbabel/gbser_posix.c +++ b/gpsbabel/gbser_posix.c @@ -1,6 +1,6 @@ /* Serial interface for POSIX tty handling. - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -33,77 +33,95 @@ #include typedef struct { - struct termios old_tio; - struct termios new_tio; - int fd; - unsigned vmin, vtime; - unsigned long magic; - - unsigned char inbuf[BUFSIZE]; - unsigned inbuf_used; + struct termios old_tio; + struct termios new_tio; + int fd; + unsigned vmin, vtime; + unsigned long magic; + + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; } gbser_handle; /* Wrapper to safely cast a void * into a gbser_handle */ -static gbser_handle *gbser__get_handle(void *p) { - gbser_handle *h = (gbser_handle *) p; - assert(h->magic == MYMAGIC); - return h; +static gbser_handle *gbser__get_handle(void *p) +{ + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; } -static speed_t mkspeed(unsigned br) { - switch (br) { - case 1200: return B1200; - case 2400: return B2400; - case 4800: return B4800; - case 9600: return B9600; - case 19200: return B19200; - case 38400: return B38400; +static speed_t mkspeed(unsigned br) +{ + switch (br) { + case 1200: + return B1200; + case 2400: + return B2400; + case 4800: + return B4800; + case 9600: + return B9600; + case 19200: + return B19200; + case 38400: + return B38400; #if defined B57600 - case 57600: return B57600; + case 57600: + return B57600; #endif #if defined B115200 - case 115200: return B115200; + case 115200: + return B115200; #endif #if defined B230400 - case 230400: return B230400; + case 230400: + return B230400; #endif - default: - fatal("Unsupported serial speed: %d\n", br); - return 0; /* keep compiler happy */ - } + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } } typedef struct timeval hp_time; -static void get_time(hp_time *tv) { - gettimeofday(tv, NULL); +static void get_time(hp_time *tv) +{ + gettimeofday(tv, NULL); } -static double elapsed(hp_time *tv) { - hp_time now; - double ot = (double) tv->tv_sec * 1000 + - (double) tv->tv_usec / 1000; - double nt; - gettimeofday(&now, NULL); - nt = (double) now.tv_sec * 1000 + - (double) now.tv_usec / 1000; - /*printf("elapsed -> %f\n", nt - ot);*/ - return nt - ot; +static double elapsed(hp_time *tv) +{ + hp_time now; + double ot = (double) tv->tv_sec * 1000 + + (double) tv->tv_usec / 1000; + double nt; + gettimeofday(&now, NULL); + nt = (double) now.tv_sec * 1000 + + (double) now.tv_usec / 1000; + /*printf("elapsed -> %f\n", nt - ot);*/ + return nt - ot; } -static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { - if (vmin > 255) { vmin = 255; } - if (vtime > 255) { vtime = 255; } - if (vmin != h->vmin || vtime != h->vtime) { - h->vmin = h->new_tio.c_cc[VMIN] = vmin; - h->vtime = h->new_tio.c_cc[VTIME] = vtime; - - /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ - - return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; - } else { - return 0; - } +static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) +{ + if (vmin > 255) { + vmin = 255; + } + if (vtime > 255) { + vtime = 255; + } + if (vmin != h->vmin || vtime != h->vtime) { + h->vmin = h->new_tio.c_cc[VMIN] = vmin; + h->vtime = h->new_tio.c_cc[VTIME] = vtime; + + /*printf("VMIN=%d, VTIME=%d\n", h->vmin, h->vtime);*/ + + return tcsetattr(h->fd, TCSANOW, &h->new_tio) ? gbser_ERROR : gbser_OK; + } else { + return 0; + } } /* Open a serial port. |port_name| is the (platform specific) name @@ -111,142 +129,145 @@ static int set_rx_timeout(gbser_handle *h, unsigned vmin, unsigned vtime) { * ('com1:') are translated into the equivalent name required by * WIN32 */ -void *gbser_init(const char *port_name) { - gbser_handle *h; +void *gbser_init(const char *port_name) +{ + gbser_handle *h; - gbser__db(4, "gbser_init(\"%s\")\n", port_name); + gbser__db(4, "gbser_init(\"%s\")\n", port_name); - h = (gbser_handle*) xcalloc(sizeof *h, 1); - h->magic = MYMAGIC; - h->vmin = h->vtime = 0; + h = (gbser_handle*) xcalloc(sizeof *h, 1); + h->magic = MYMAGIC; + h->vmin = h->vtime = 0; - if (0 == strcmp(port_name, "-")) { - h->fd = 0; - return h; - } - else if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { - warning("Failed to open port (%s)\n", strerror(errno)); - goto failed; - } + if (0 == strcmp(port_name, "-")) { + h->fd = 0; + return h; + } else if (h->fd = open(port_name, O_RDWR | O_NOCTTY), h->fd == -1) { + warning("Failed to open port (%s)\n", strerror(errno)); + goto failed; + } - if (!isatty(h->fd)) { - warning("%s is not a TTY\n", port_name); - goto failed; - } + if (!isatty(h->fd)) { + warning("%s is not a TTY\n", port_name); + goto failed; + } - if (gbser_set_port(h, 4800, 8, 0, 1)) { - warning("gbser_set_port() failed\n"); - goto failed; - } + if (gbser_set_port(h, 4800, 8, 0, 1)) { + warning("gbser_set_port() failed\n"); + goto failed; + } - return h; + return h; failed: - if (h->fd != -1) { - close(h->fd); - } - - xfree(h); - - return NULL; + if (h->fd != -1) { + close(h->fd); + } + + xfree(h); + + return NULL; } /* Close a serial port */ -void gbser_deinit(void *handle) { - gbser_handle *h = gbser__get_handle(handle); +void gbser_deinit(void *handle) +{ + gbser_handle *h = gbser__get_handle(handle); - tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); - close(h->fd); + tcsetattr(h->fd, TCSAFLUSH, &h->old_tio); + close(h->fd); - xfree(h); + xfree(h); } -int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { - gbser_handle *h = gbser__get_handle(handle); - speed_t s; - - static unsigned bit_flags[] = { - 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 - }; +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) +{ + gbser_handle *h = gbser__get_handle(handle); + speed_t s; - if (bits < 5 || bits > 8) { - fatal("Unsupported bits setting: %d\n", bits); - } + static unsigned bit_flags[] = { + 0, 0, 0, 0, 0, CS5, CS6, CS7, CS8 + }; - if (parity > 2) { - fatal("Unsupported parity setting: %d\n", parity); - } - - if (stop < 1 || stop > 2) { - fatal("Unsupported stop setting: %d\n", stop); - } + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } - s = mkspeed(speed); + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } - /* TODO: We don't /fully/ initialise the port's stat here... */ + s = mkspeed(speed); - tcgetattr(h->fd, &h->old_tio); + /* TODO: We don't /fully/ initialise the port's stat here... */ - h->new_tio = h->old_tio; + tcgetattr(h->fd, &h->old_tio); - /* clear bits */ + h->new_tio = h->old_tio; + + /* clear bits */ // cfmakeraw(&h->new_tio); - h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP - |INLCR|IGNCR|ICRNL|IXON); - h->new_tio.c_oflag &= ~OPOST; - h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); - h->new_tio.c_cflag &= ~(CSIZE|PARENB); - h->new_tio.c_cflag |= CS8; - - h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | - INLCR | IGNCR | IXON); - h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); - - /* set data bits, */ - h->new_tio.c_cflag |= bit_flags[bits]; - - /* stop bits and... */ - if (stop == 2) { - h->new_tio.c_cflag |= CSTOPB; - } - - /* parity */ - if (parity != 0) { - h->new_tio.c_cflag |= PARENB; - if (parity == 1) { - h->new_tio.c_cflag |= PARODD; - } - } - - h->new_tio.c_oflag = 0; - h->new_tio.c_lflag = 0; - - h->new_tio.c_cc[VMIN] = h->vmin; - h->new_tio.c_cc[VTIME] = h->vtime; - - cfsetospeed(&h->new_tio, s); - cfsetispeed(&h->new_tio, s); - - return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; + h->new_tio.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP + |INLCR|IGNCR|ICRNL|IXON); + h->new_tio.c_oflag &= ~OPOST; + h->new_tio.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + h->new_tio.c_cflag &= ~(CSIZE|PARENB); + h->new_tio.c_cflag |= CS8; + + h->new_tio.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | IXON); + h->new_tio.c_cflag &= ~(CSIZE | PARENB | PARODD | CSTOPB); + + /* set data bits, */ + h->new_tio.c_cflag |= bit_flags[bits]; + + /* stop bits and... */ + if (stop == 2) { + h->new_tio.c_cflag |= CSTOPB; + } + + /* parity */ + if (parity != 0) { + h->new_tio.c_cflag |= PARENB; + if (parity == 1) { + h->new_tio.c_cflag |= PARODD; + } + } + + h->new_tio.c_oflag = 0; + h->new_tio.c_lflag = 0; + + h->new_tio.c_cc[VMIN] = h->vmin; + h->new_tio.c_cc[VTIME] = h->vtime; + + cfsetospeed(&h->new_tio, s); + cfsetispeed(&h->new_tio, s); + + return tcsetattr(h->fd, TCSADRAIN, &h->new_tio) ? gbser_ERROR : gbser_OK; } -unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { - gbser_handle *h = gbser__get_handle(handle); - unsigned count = *len; - unsigned char *cp = (unsigned char *) *buf; - if (count > h->inbuf_used) { - count = h->inbuf_used; - } - - memcpy(cp, h->inbuf, count); - memmove(h->inbuf, h->inbuf + count, - h->inbuf_used - count); - h->inbuf_used -= count; - *len -= count; - cp += count; - *buf = (void *) cp; - return count; +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) +{ + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = (unsigned char *) *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; } /* Return when the input buffer contains at least |want| bytes or |*ms| @@ -255,111 +276,114 @@ unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { * be updated to indicate the remaining time on exit. * Returns the number of bytes available (>=0) or an error code (<0). */ -int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { - int rc; - gbser_handle *h = gbser__get_handle(handle); - - if (want > BUFSIZE) { - want = BUFSIZE; - } +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) +{ + int rc; + gbser_handle *h = gbser__get_handle(handle); + + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } - /* Already got enough bytes? */ - if (h->inbuf_used >= want) { - return h->inbuf_used; + if (NULL == ms || 0 == *ms) { + if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; } + h->inbuf_used += rc; + /*printf("Got %d bytes\n", rc);*/ + } else { + double time_left = *ms; + hp_time tv; + get_time(&tv); - if (NULL == ms || 0 == *ms) { - if ((rc = set_rx_timeout(h, 0, 0), rc < 0) || - (rc = read(h->fd, h->inbuf + h->inbuf_used, - want - h->inbuf_used), rc < 0)) { - return gbser_ERROR; + for (;;) { + fd_set rec; + struct timeval t; + + time_left = *ms - elapsed(&tv); + if (time_left <= 0 || h->inbuf_used >= want) { + break; + } + + FD_ZERO(&rec); + FD_SET(h->fd, &rec); + + t.tv_sec = (time_t) time_left / 1000; + t.tv_usec = ((unsigned) time_left % 1000) * 1000; + + if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { + return gbser_ERROR; + } + + time_left = *ms - elapsed(&tv); + + if (FD_ISSET(h->fd, &rec)) { + unsigned vmin = 0, vtime = 0; + if (time_left >= 100) { + vmin = want - h->inbuf_used; + vtime = (unsigned) time_left / 100; + } + // The commented out call to set_rx_timeout here is totally + // legal by POSIX standards but does result in a flurry of + // of tcsetattrs that slightly tweak VMIN/VTIME while there + // is incoming data. This has been shown to trigger driver + // bugs in the Prolific drivers for Mac and in certain Linux + // kernels, thought the latter has since been fixed. + // So althogh removing this means that the timeout behaviour + // is actually different on POSIX and WIN32, it triggers + // fewer buts this way. 2/12/2008 RJL + if (/* (rc = set_rx_timeout(h, vmin, vtime), rc < 0) || */ + (rc = read(h->fd, h->inbuf + h->inbuf_used, + want - h->inbuf_used), rc < 0)) { + return gbser_ERROR; } h->inbuf_used += rc; /*printf("Got %d bytes\n", rc);*/ - } else { - double time_left = *ms; - hp_time tv; - get_time(&tv); - - for (;;) { - fd_set rec; - struct timeval t; - - time_left = *ms - elapsed(&tv); - if (time_left <= 0 || h->inbuf_used >= want) { - break; - } - - FD_ZERO(&rec); - FD_SET(h->fd, &rec); - - t.tv_sec = (time_t) time_left / 1000; - t.tv_usec = ((unsigned) time_left % 1000) * 1000; - - if (select(h->fd + 1, &rec, NULL, NULL, &t) < 0) { - return gbser_ERROR; - } - - time_left = *ms - elapsed(&tv); - - if (FD_ISSET(h->fd, &rec)) { - unsigned vmin = 0, vtime = 0; - if (time_left >= 100) { - vmin = want - h->inbuf_used; - vtime = (unsigned) time_left / 100; - } - // The commented out call to set_rx_timeout here is totally - // legal by POSIX standards but does result in a flurry of - // of tcsetattrs that slightly tweak VMIN/VTIME while there - // is incoming data. This has been shown to trigger driver - // bugs in the Prolific drivers for Mac and in certain Linux - // kernels, thought the latter has since been fixed. - // So althogh removing this means that the timeout behaviour - // is actually different on POSIX and WIN32, it triggers - // fewer buts this way. 2/12/2008 RJL - if (/* (rc = set_rx_timeout(h, vmin, vtime), rc < 0) || */ - (rc = read(h->fd, h->inbuf + h->inbuf_used, - want - h->inbuf_used), rc < 0)) { - return gbser_ERROR; - } - h->inbuf_used += rc; - /*printf("Got %d bytes\n", rc);*/ - } - } - *ms = (time_left < 0) ? 0 : time_left; + } } + *ms = (time_left < 0) ? 0 : time_left; + } - return h->inbuf_used; + return h->inbuf_used; } /* Discard any pending input on the serial port. - */ -int gbser_flush(void *handle) { - gbser_handle *h = gbser__get_handle(handle); - h->inbuf_used = 0; - if (tcflush(h->fd, TCIFLUSH)) { - return gbser_ERROR; - } - - return gbser_OK; + */ +int gbser_flush(void *handle) +{ + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (tcflush(h->fd, TCIFLUSH)) { + return gbser_ERROR; + } + + return gbser_OK; } /* Write |len| bytes from |buf| to the serial port. */ -int gbser_write(void *handle, const void *buf, unsigned len) { - gbser_handle *h = gbser__get_handle(handle); - const char *bp = (const char *) buf; - int rc; - while (len > 0) { - /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ - if (rc = write(h->fd, bp, len), rc < 0) { - printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); - return gbser_ERROR; - } - len -= rc; - bp += rc; +int gbser_write(void *handle, const void *buf, unsigned len) +{ + gbser_handle *h = gbser__get_handle(handle); + const char *bp = (const char *) buf; + int rc; + while (len > 0) { + /*printf("write(%d, %p, %d)\n", h->fd, bp, len);*/ + if (rc = write(h->fd, bp, len), rc < 0) { + printf("rc = %d, errno = %d (%s)\n", rc, errno, strerror(errno)); + return gbser_ERROR; } - return gbser_OK; + len -= rc; + bp += rc; + } + return gbser_OK; } /* Return true if a port name seems to refer to a serial port. @@ -368,26 +392,27 @@ int gbser_write(void *handle, const void *buf, unsigned len) { * isatty() */ -int gbser_is_serial(const char *port_name) { - int fd; - int is_port = 0; +int gbser_is_serial(const char *port_name) +{ + int fd; + int is_port = 0; - if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { - gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); - return 0; - } + if (fd = open(port_name, O_RDWR | O_NOCTTY), fd == -1) { + gbser__db(1, "Failed to open port (%s) to check its type\n", strerror(errno)); + return 0; + } - is_port = isatty(fd); + is_port = isatty(fd); - close(fd); + close(fd); - return is_port; + return is_port; } -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. @@ -396,15 +421,17 @@ int gbser_is_serial(const char *port_name) { * call to this function. */ -const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len) { - strncpy(obuf, comname, len); - return obuf; +const char *fix_win_serial_name_r(const char *comname, char *obuf, size_t len) +{ + strncpy(obuf, comname, len); + return obuf; } static char gb_com_buffer[100]; -const char *fix_win_serial_name(const char *comname) { - return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); +const char *fix_win_serial_name(const char *comname) +{ + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); } /* Read from the serial port until the specified |eol| character is @@ -414,28 +441,29 @@ const char *fix_win_serial_name(const char *comname) { * The terminating character and any discarded characters are not * stored in the buffer. */ -int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, int eol, int discard) { - char *bp = buf; - unsigned pos = 0; - hp_time tv; - get_time(&tv); - bp[pos] = '\0'; - for (;;) { - signed time_left = ms - elapsed(&tv); - int c; - - if (time_left <= 0) { - return gbser_TIMEOUT; - } - c = gbser_readc_wait(handle, time_left); - if (c == gbser_ERROR) { - return c; - } else if (c == eol) { - return gbser_OK; - } - if (c != gbser_NOTHING && c != discard && pos < len - 1) { - bp[pos++] = c; - bp[pos] = '\0'; - } +int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, int eol, int discard) +{ + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; } + } } diff --git a/gpsbabel/gbser_private.h b/gpsbabel/gbser_private.h index 318455e80..0681c6576 100644 --- a/gpsbabel/gbser_private.h +++ b/gpsbabel/gbser_private.h @@ -1,6 +1,6 @@ /* Serial interface - private header for gbser*.c - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify diff --git a/gpsbabel/gbser_win.c b/gpsbabel/gbser_win.c index 26bf5d068..7b7f84850 100644 --- a/gpsbabel/gbser_win.c +++ b/gpsbabel/gbser_win.c @@ -1,6 +1,6 @@ /* Serial interface - Windows layer. - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -30,89 +30,102 @@ #include typedef struct { - HANDLE comport; - DWORD timeout; - unsigned long magic; + HANDLE comport; + DWORD timeout; + unsigned long magic; - unsigned char inbuf[BUFSIZE]; - unsigned inbuf_used; + unsigned char inbuf[BUFSIZE]; + unsigned inbuf_used; } gbser_handle; #define DEV_PREFIX "\\\\.\\\\" /* Wrapper to safely cast a void * into a gbser_handle */ -static gbser_handle *gbser__get_handle(void *p) { - gbser_handle *h = (gbser_handle *) p; - assert(h->magic == MYMAGIC); - return h; +static gbser_handle *gbser__get_handle(void *p) +{ + gbser_handle *h = (gbser_handle *) p; + assert(h->magic == MYMAGIC); + return h; } -static DWORD mkspeed(unsigned br) { - switch (br) { - case 1200: return CBR_1200; - case 2400: return CBR_2400; - case 4800: return CBR_4800; - case 9600: return CBR_9600; - case 19200: return CBR_19200; - case 38400: return CBR_38400; - case 57600: return CBR_57600; - case 115200: return CBR_115200; - default: - fatal("Unsupported serial speed: %d\n", br); - return 0; /* keep compiler happy */ - } +static DWORD mkspeed(unsigned br) +{ + switch (br) { + case 1200: + return CBR_1200; + case 2400: + return CBR_2400; + case 4800: + return CBR_4800; + case 9600: + return CBR_9600; + case 19200: + return CBR_19200; + case 38400: + return CBR_38400; + case 57600: + return CBR_57600; + case 115200: + return CBR_115200; + default: + fatal("Unsupported serial speed: %d\n", br); + return 0; /* keep compiler happy */ + } } typedef LARGE_INTEGER hp_time; -static void get_time(hp_time *tv) { - QueryPerformanceCounter(tv); +static void get_time(hp_time *tv) +{ + QueryPerformanceCounter(tv); } -static double elapsed(hp_time *tv) { - hp_time now; - LARGE_INTEGER tps; +static double elapsed(hp_time *tv) +{ + hp_time now; + LARGE_INTEGER tps; - QueryPerformanceFrequency(&tps); - QueryPerformanceCounter(&now); + QueryPerformanceFrequency(&tps); + QueryPerformanceCounter(&now); - return ((double) (now.QuadPart - tv->QuadPart) / - (double) tps.QuadPart) * 1000; + return ((double)(now.QuadPart - tv->QuadPart) / + (double) tps.QuadPart) * 1000; } -static int set_rx_timeout(gbser_handle *h, DWORD timeout) { - if (timeout != h->timeout) { - COMMTIMEOUTS to; +static int set_rx_timeout(gbser_handle *h, DWORD timeout) +{ + if (timeout != h->timeout) { + COMMTIMEOUTS to; - if (!GetCommTimeouts(h->comport, &to)) { - return gbser_ERROR; - } - - to.ReadIntervalTimeout = timeout; - to.ReadTotalTimeoutMultiplier = 0; - to.ReadTotalTimeoutConstant = timeout; - to.WriteTotalTimeoutMultiplier = 0; - to.WriteTotalTimeoutConstant = 0; - - if (!SetCommTimeouts(h->comport, &to)) { - return gbser_ERROR; - } else { - h->timeout = timeout; - return gbser_OK; - } + if (!GetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; + } + + to.ReadIntervalTimeout = timeout; + to.ReadTotalTimeoutMultiplier = 0; + to.ReadTotalTimeoutConstant = timeout; + to.WriteTotalTimeoutMultiplier = 0; + to.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts(h->comport, &to)) { + return gbser_ERROR; } else { - return gbser_OK; + h->timeout = timeout; + return gbser_OK; } + } else { + return gbser_OK; + } } -/* This isn't part of the above abstraction; it's just a helper for +/* This isn't part of the above abstraction; it's just a helper for * the other serial modules in the tree. * - * Windows does a weird thing with serial ports. + * Windows does a weird thing with serial ports. * COM ports 1 - 9 are "COM1:" through "COM9:" * The one after that is \\.\\com10 - this function tries to plaster over * that. - * + * * Worse still, Win98 and ME fail the open if you rename com1 to be \\.\\com1: * * It returns a pointer to a staticly allocated buffer and is therefore not @@ -121,30 +134,30 @@ static int set_rx_timeout(gbser_handle *h, DWORD timeout) { */ const char * -fix_win_serial_name_r(const char *comname, char *obuf, size_t len) +fix_win_serial_name_r(const char *comname, char *obuf, size_t len) { - if (!gbser_is_serial(comname) || - ((strlen(comname) == 5) && (comname[4] == ':')) || - ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) - ) { - strncpy(obuf, comname, len); - } else { - size_t l; - snprintf(obuf, len, DEV_PREFIX "%s", comname); - l = strlen(obuf); - if (obuf[l - 1] == ':') { - obuf[l - 1] = '\0'; - } - } - - return obuf; + if (!gbser_is_serial(comname) || + ((strlen(comname) == 5) && (comname[4] == ':')) || + ((strlen(comname) == 4) && (case_ignore_strncmp(comname, "com", 3) == 0)) + ) { + strncpy(obuf, comname, len); + } else { + size_t l; + snprintf(obuf, len, DEV_PREFIX "%s", comname); + l = strlen(obuf); + if (obuf[l - 1] == ':') { + obuf[l - 1] = '\0'; + } + } + + return obuf; } static char gb_com_buffer[100]; -const char *fix_win_serial_name(const char *comname) +const char *fix_win_serial_name(const char *comname) { - return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); + return fix_win_serial_name_r(comname, gb_com_buffer, sizeof(gb_com_buffer)); } /* Open a serial port. |port_name| is the (platform specific) name @@ -152,110 +165,113 @@ const char *fix_win_serial_name(const char *comname) * ('com1:') are translated into the equivalent name required by * WIN32 */ -void *gbser_init(const char *port_name) +void *gbser_init(const char *port_name) { - HANDLE comport; - gbser_handle* h = xcalloc(1, sizeof(*h)); - const char *xname = fix_win_serial_name(port_name); - - gbser__db(2, "Translated port name: \"%s\"\n", xname); - - h->magic = MYMAGIC; - - comport = CreateFileA(xname, GENERIC_READ | GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL); - - if (comport == INVALID_HANDLE_VALUE) { - goto failed; - } - - h->comport = comport; - h->timeout = 1; - if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { - goto failed; - } - - return h; - + HANDLE comport; + gbser_handle* h = xcalloc(1, sizeof(*h)); + const char *xname = fix_win_serial_name(port_name); + + gbser__db(2, "Translated port name: \"%s\"\n", xname); + + h->magic = MYMAGIC; + + comport = CreateFileA(xname, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + goto failed; + } + + h->comport = comport; + h->timeout = 1; + if (gbser_set_port(h, 4800, 8, 0, 1) || set_rx_timeout(h, 0)) { + goto failed; + } + + return h; + failed: - if (comport) { - CloseHandle(h->comport); - } - xfree(h); - - return NULL; + if (comport) { + CloseHandle(h->comport); + } + xfree(h); + + return NULL; } /* Close a serial port */ -void gbser_deinit(void *handle) { - gbser_handle *h = gbser__get_handle(handle); +void gbser_deinit(void *handle) +{ + gbser_handle *h = gbser__get_handle(handle); - CloseHandle(h->comport); + CloseHandle(h->comport); - xfree(h); + xfree(h); } -int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) { - gbser_handle *h = gbser__get_handle(handle); - DCB tio; - - if (bits < 5 || bits > 8) { - fatal("Unsupported bits setting: %d\n", bits); - } - - if (parity > 2) { - fatal("Unsupported parity setting: %d\n", parity); - } - - if (stop < 1 || stop > 2) { - fatal("Unsupported stop setting: %d\n", stop); - } - - tio.DCBlength = sizeof(DCB); - GetCommState(h->comport, &tio); - - tio.BaudRate = mkspeed(speed); - tio.fBinary = TRUE; - tio.fParity = TRUE; - tio.fOutxCtsFlow = FALSE; - tio.fOutxDsrFlow = FALSE; - tio.fDtrControl = DTR_CONTROL_ENABLE; - tio.fDsrSensitivity = FALSE; - tio.fTXContinueOnXoff = TRUE; - tio.fOutX = FALSE; - tio.fInX = FALSE; - tio.fErrorChar = FALSE; - tio.fNull = FALSE; - tio.fRtsControl = RTS_CONTROL_ENABLE; - tio.fAbortOnError = FALSE; - tio.ByteSize = bits; - tio.Parity = parity == 0 ? NOPARITY : - (parity == 1 ? ODDPARITY : EVENPARITY); - tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; - - if (!SetCommState(h->comport, &tio)) { - return gbser_ERROR; - } - return gbser_OK; +int gbser_set_port(void *handle, unsigned speed, unsigned bits, unsigned parity, unsigned stop) +{ + gbser_handle *h = gbser__get_handle(handle); + DCB tio; + + if (bits < 5 || bits > 8) { + fatal("Unsupported bits setting: %d\n", bits); + } + + if (parity > 2) { + fatal("Unsupported parity setting: %d\n", parity); + } + + if (stop < 1 || stop > 2) { + fatal("Unsupported stop setting: %d\n", stop); + } + + tio.DCBlength = sizeof(DCB); + GetCommState(h->comport, &tio); + + tio.BaudRate = mkspeed(speed); + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = bits; + tio.Parity = parity == 0 ? NOPARITY : + (parity == 1 ? ODDPARITY : EVENPARITY); + tio.StopBits = stop == 1 ? ONESTOPBIT : TWOSTOPBITS; + + if (!SetCommState(h->comport, &tio)) { + return gbser_ERROR; + } + return gbser_OK; } -unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { - gbser_handle *h = gbser__get_handle(handle); - unsigned count = *len; - unsigned char *cp = *buf; - if (count > h->inbuf_used) { - count = h->inbuf_used; - } - - memcpy(cp, h->inbuf, count); - memmove(h->inbuf, h->inbuf + count, - h->inbuf_used - count); - h->inbuf_used -= count; - *len -= count; - cp += count; - *buf = (void *) cp; - return count; +unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) +{ + gbser_handle *h = gbser__get_handle(handle); + unsigned count = *len; + unsigned char *cp = *buf; + if (count > h->inbuf_used) { + count = h->inbuf_used; + } + + memcpy(cp, h->inbuf, count); + memmove(h->inbuf, h->inbuf + count, + h->inbuf_used - count); + h->inbuf_used -= count; + *len -= count; + cp += count; + *buf = (void *) cp; + return count; } /* Return when the input buffer contains at least |want| bytes or |*ms| @@ -264,90 +280,93 @@ unsigned gbser__read_buffer(void *handle, void **buf, unsigned *len) { * be updated to indicate the remaining time on exit. * Returns the number of bytes available (>=0) or an error code (<0). */ -int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) { - int rc; - gbser_handle *h = gbser__get_handle(handle); - - if (want > BUFSIZE) { - want = BUFSIZE; - } +int gbser__fill_buffer(void *handle, unsigned want, unsigned *ms) +{ + int rc; + gbser_handle *h = gbser__get_handle(handle); - /* Already got enough bytes? */ - if (h->inbuf_used >= want) { - return h->inbuf_used; - } - - if (NULL == ms || 0 == *ms) { - DWORD err, nread; - COMSTAT stat; - ClearCommError(h->comport, &err, &stat); - if (stat.cbInQue > 0) { - DWORD count = want - h->inbuf_used; - if (count > stat.cbInQue) { - count = stat.cbInQue; - } - if (rc = set_rx_timeout(h, 1), rc) { - return rc; - } - if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, - count, &nread, NULL)) { - err = GetLastError(); - if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { - return gbser_ERROR; - } - } - h->inbuf_used += nread; - } - } else { - hp_time tv; - double time_left; - DWORD err, nread; - get_time(&tv); - if (rc = set_rx_timeout(h, *ms), rc) { - return rc; + if (want > BUFSIZE) { + want = BUFSIZE; + } + + /* Already got enough bytes? */ + if (h->inbuf_used >= want) { + return h->inbuf_used; + } + + if (NULL == ms || 0 == *ms) { + DWORD err, nread; + COMSTAT stat; + ClearCommError(h->comport, &err, &stat); + if (stat.cbInQue > 0) { + DWORD count = want - h->inbuf_used; + if (count > stat.cbInQue) { + count = stat.cbInQue; + } + if (rc = set_rx_timeout(h, 1), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + count, &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; } - if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, - want - h->inbuf_used, - &nread, NULL)) { - err = GetLastError(); - if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { - return gbser_ERROR; - } - } - h->inbuf_used += nread; - time_left = *ms - elapsed(&tv); - *ms = time_left < 0 ? 0 : (unsigned) time_left; + } + h->inbuf_used += nread; } + } else { + hp_time tv; + double time_left; + DWORD err, nread; + get_time(&tv); + if (rc = set_rx_timeout(h, *ms), rc) { + return rc; + } + if (!ReadFile(h->comport, h->inbuf + h->inbuf_used, + want - h->inbuf_used, + &nread, NULL)) { + err = GetLastError(); + if (err != ERROR_COUNTER_TIMEOUT && err != ERROR_TIMEOUT) { + return gbser_ERROR; + } + } + h->inbuf_used += nread; + time_left = *ms - elapsed(&tv); + *ms = time_left < 0 ? 0 : (unsigned) time_left; + } - return h->inbuf_used; + return h->inbuf_used; } /* Discard any pending input on the serial port. - */ -int gbser_flush(void *handle) { - gbser_handle *h = gbser__get_handle(handle); - h->inbuf_used = 0; - if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { - return gbser_ERROR; - } - return gbser_OK; + */ +int gbser_flush(void *handle) +{ + gbser_handle *h = gbser__get_handle(handle); + h->inbuf_used = 0; + if (!PurgeComm(h->comport, PURGE_RXCLEAR)) { + return gbser_ERROR; + } + return gbser_OK; } /* Write |len| bytes from |buf| to the serial port. */ -int gbser_write(void *handle, const void *buf, unsigned len) { - gbser_handle *h = gbser__get_handle(handle); - DWORD nwritten; - const char *bp = buf; - /* Not sure we need to spin here - but this'll work even if we don't */ - while (len > 0) { - if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { - return gbser_ERROR; - } - len -= nwritten; - bp += nwritten; +int gbser_write(void *handle, const void *buf, unsigned len) +{ + gbser_handle *h = gbser__get_handle(handle); + DWORD nwritten; + const char *bp = buf; + /* Not sure we need to spin here - but this'll work even if we don't */ + while (len > 0) { + if (!WriteFile(h->comport, bp, len, &nwritten, NULL)) { + return gbser_ERROR; } - return gbser_OK; + len -= nwritten; + bp += nwritten; + } + return gbser_OK; } /* Return true if a port name seems to refer to a serial port. @@ -356,45 +375,46 @@ int gbser_write(void *handle, const void *buf, unsigned len) { * isatty() */ -int gbser_is_serial(const char *port_name) { - const char *pfx = DEV_PREFIX; - size_t pfx_l = strlen(pfx); - const char *com = "COM"; - size_t com_l = strlen(com); - unsigned digits; - - if (NULL == port_name) { - return 0; - } - - /* Skip any prefix */ - if (memcmp(port_name, pfx, pfx_l) == 0) { - port_name += pfx_l; - } - - if (case_ignore_strncmp(port_name, com, com_l) != 0) { - return 0; - } - - port_name += com_l; - for (digits = 0; isdigit(*port_name); port_name++, digits++) { - /* do nothing */ - } - - if (digits == 0) { - return 0; - } - - if (*port_name == ':') { - port_name++; - } - - if (*port_name != '\0') { - return 0; - } - - /* Success! */ - return 1; +int gbser_is_serial(const char *port_name) +{ + const char *pfx = DEV_PREFIX; + size_t pfx_l = strlen(pfx); + const char *com = "COM"; + size_t com_l = strlen(com); + unsigned digits; + + if (NULL == port_name) { + return 0; + } + + /* Skip any prefix */ + if (memcmp(port_name, pfx, pfx_l) == 0) { + port_name += pfx_l; + } + + if (case_ignore_strncmp(port_name, com, com_l) != 0) { + return 0; + } + + port_name += com_l; + for (digits = 0; isdigit(*port_name); port_name++, digits++) { + /* do nothing */ + } + + if (digits == 0) { + return 0; + } + + if (*port_name == ':') { + port_name++; + } + + if (*port_name != '\0') { + return 0; + } + + /* Success! */ + return 1; } /* Read from the serial port until the specified |eol| character is @@ -402,29 +422,30 @@ int gbser_is_serial(const char *port_name) { * read lines terminated by 0x0A0x0D discarding linefeeds use * gbser_read_line(h, buf, len, 1000, 0x0D, 0x0A); */ -int gbser_read_line(void *handle, void *buf, +int gbser_read_line(void *handle, void *buf, unsigned len, unsigned ms, - int eol, int discard) { - char *bp = buf; - unsigned pos = 0; - hp_time tv; - get_time(&tv); - bp[pos] = '\0'; - for (;;) { - signed time_left = ms - elapsed(&tv); - int c; - if (time_left <= 0) { - return gbser_TIMEOUT; - } - c = gbser_readc_wait(handle, time_left); - if (c == gbser_ERROR) { - return c; - } else if (c == eol) { - return gbser_OK; - } - if (c != gbser_NOTHING && c != discard && pos < len - 1) { - bp[pos++] = c; - bp[pos] = '\0'; - } + int eol, int discard) +{ + char *bp = buf; + unsigned pos = 0; + hp_time tv; + get_time(&tv); + bp[pos] = '\0'; + for (;;) { + signed time_left = ms - elapsed(&tv); + int c; + if (time_left <= 0) { + return gbser_TIMEOUT; + } + c = gbser_readc_wait(handle, time_left); + if (c == gbser_ERROR) { + return c; + } else if (c == eol) { + return gbser_OK; + } + if (c != gbser_NOTHING && c != discard && pos < len - 1) { + bp[pos++] = c; + bp[pos] = '\0'; } + } } diff --git a/gpsbabel/gbsleep.c b/gpsbabel/gbsleep.c index 63f1fa0ba..5a26dffec 100644 --- a/gpsbabel/gbsleep.c +++ b/gpsbabel/gbsleep.c @@ -28,7 +28,7 @@ void gb_sleep(unsigned long microseconds) { - Sleep(microseconds/1000 + 1); + Sleep(microseconds/1000 + 1); } #elif defined HAVE_NANOSLEEP @@ -37,10 +37,10 @@ gb_sleep(unsigned long microseconds) void gb_sleep(unsigned long microseconds) { - struct timespec req; - req.tv_sec = microseconds / 1000000; - req.tv_nsec = (microseconds * 1000) % 1000000000; - nanosleep(&req, NULL); + struct timespec req; + req.tv_sec = microseconds / 1000000; + req.tv_nsec = (microseconds * 1000) % 1000000000; + nanosleep(&req, NULL); } #elif defined HAVE_SLEEP /* Amazingly underachieving, but probably "good enough" */ @@ -48,6 +48,6 @@ gb_sleep(unsigned long microseconds) void gb_sleep(unsigned long microseconds) { - sleep(microseconds / 1000000); + sleep(microseconds / 1000000); } #endif diff --git a/gpsbabel/gcdb.c b/gpsbabel/gcdb.c index a3c782b28..a110105a0 100644 --- a/gpsbabel/gcdb.c +++ b/gpsbabel/gcdb.c @@ -28,23 +28,23 @@ #define MYCREATOR 0x42726174 /* Brat */ #define MAXRECSZ 500 /* This is overkill as the records seem to be around 100 - bytes a piece, but being conservative and dealing - with realloc issues just doesn't seem worth it. */ +bytes a piece, but being conservative and dealing +with realloc issues just doesn't seem worth it. */ typedef enum { - RECTYPE_TEXT = 0, - RECTYPE_DATE = 2 +RECTYPE_TEXT = 0, +RECTYPE_DATE = 2 } gcdb_rectype; struct dbfld { - char fldname[4]; - pdb_16 fldtype; - pdb_16 fldlen; +char fldname[4]; +pdb_16 fldtype; +pdb_16 fldlen; }; struct dbrec { - pdb_16 nflds; - struct dbfld dbfld[1]; +pdb_16 nflds; +struct dbfld dbfld[1]; }; static pdbfile *file_in, *file_out; @@ -57,264 +57,255 @@ static char *tbufp = NULL; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); +file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); +pdb_close(file_in); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; +file_out = pdb_create(fname, MYNAME); +out_fname = fname; +ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( tbuf ) - xfree(tbuf); +pdb_close(file_out); +if (tbuf) { +xfree(tbuf); +} } static void data_read(void) { - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a GeocachingDB file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt = waypt_new(); - struct dbrec *rec = (struct dbrec *) pdb_rec->data; - int nflds; - int length; - int type; - int i; - char *recdata; - int lat_dir = 0; - int lat_deg = 0; - float lat_min = 0.0; - int lon_dir = 0; - int lon_deg = 0; - float lon_min = 0.0; - - nflds = be_read16(&rec->nflds); - recdata = (char *) &rec->dbfld[nflds]; - - for (i = 0; i < nflds; i++) { - length = (unsigned short) be_read16(&rec->dbfld[i].fldlen); - type = be_read16(&rec->dbfld[i].fldtype); - - switch(type) { - case RECTYPE_TEXT: /* Text */ - if (!strncmp("gcid", rec->dbfld[i].fldname,4)) { - wpt->shortname = xstrdup(recdata); - } else - if (!strncmp("gcna", rec->dbfld[i].fldname,4)) { - wpt->description = xstrdup(recdata); - } else - if (!strncmp("lat0", rec->dbfld[i].fldname,4)) { - lat_dir = *recdata == 'N' ? 1 : -1; - } else - if (!strncmp("lat1", rec->dbfld[i].fldname,4)) { - lat_deg = atoi(recdata); - } else - if (!strncmp("lat2", rec->dbfld[i].fldname,4)) { - lat_min = atof(recdata); - } - if (!strncmp("lon0", rec->dbfld[i].fldname,4)) { - lon_dir = *recdata == 'E' ? 1 : -1; - } else - if (!strncmp("lon1", rec->dbfld[i].fldname,4)) { - lon_deg = atoi(recdata); - } else - if (!strncmp("lon2", rec->dbfld[i].fldname,4)) { - lon_min = atof(recdata); - } else - if (!strncmp("take", rec->dbfld[i].fldname,4)) { - wpt->notes = xstrappend(wpt->notes, " Took "); - wpt->notes = xstrappend(wpt->notes, recdata); - } else - if (!strncmp("left", rec->dbfld[i].fldname,4)) { - wpt->notes = xstrappend(wpt->notes, " Left "); - wpt->notes = xstrappend(wpt->notes, recdata); - } else - if (!strncmp("diff", rec->dbfld[i].fldname,4)) { - waypt_alloc_gc_data(wpt)->diff = 10 * atof(recdata); - } else - if (!strncmp("terr", rec->dbfld[i].fldname,4)) { - waypt_alloc_gc_data(wpt)->terr = 10 * atof(recdata); - } - break; +pdbrec_t *pdb_rec; + +if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { +fatal(MYNAME ": Not a GeocachingDB file.\n"); +} + +for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { +waypoint *wpt = waypt_new(); +struct dbrec *rec = (struct dbrec *) pdb_rec->data; +int nflds; +int length; +int type; +int i; +char *recdata; +int lat_dir = 0; +int lat_deg = 0; +float lat_min = 0.0; +int lon_dir = 0; +int lon_deg = 0; +float lon_min = 0.0; + +nflds = be_read16(&rec->nflds); +recdata = (char *) &rec->dbfld[nflds]; + +for (i = 0; i < nflds; i++) { +length = (unsigned short) be_read16(&rec->dbfld[i].fldlen); +type = be_read16(&rec->dbfld[i].fldtype); + +switch (type) { +case RECTYPE_TEXT: /* Text */ +if (!strncmp("gcid", rec->dbfld[i].fldname,4)) { +wpt->shortname = xstrdup(recdata); +} else if (!strncmp("gcna", rec->dbfld[i].fldname,4)) { +wpt->description = xstrdup(recdata); +} else if (!strncmp("lat0", rec->dbfld[i].fldname,4)) { +lat_dir = *recdata == 'N' ? 1 : -1; +} else if (!strncmp("lat1", rec->dbfld[i].fldname,4)) { +lat_deg = atoi(recdata); +} else if (!strncmp("lat2", rec->dbfld[i].fldname,4)) { +lat_min = atof(recdata); +} +if (!strncmp("lon0", rec->dbfld[i].fldname,4)) { +lon_dir = *recdata == 'E' ? 1 : -1; +} else if (!strncmp("lon1", rec->dbfld[i].fldname,4)) { +lon_deg = atoi(recdata); +} else if (!strncmp("lon2", rec->dbfld[i].fldname,4)) { +lon_min = atof(recdata); +} else if (!strncmp("take", rec->dbfld[i].fldname,4)) { +wpt->notes = xstrappend(wpt->notes, " Took "); +wpt->notes = xstrappend(wpt->notes, recdata); +} else if (!strncmp("left", rec->dbfld[i].fldname,4)) { +wpt->notes = xstrappend(wpt->notes, " Left "); +wpt->notes = xstrappend(wpt->notes, recdata); +} else if (!strncmp("diff", rec->dbfld[i].fldname,4)) { +waypt_alloc_gc_data(wpt)->diff = 10 * atof(recdata); +} else if (!strncmp("terr", rec->dbfld[i].fldname,4)) { +waypt_alloc_gc_data(wpt)->terr = 10 * atof(recdata); +} +break; #if 0 - /* This really is the date of the find, - * not the cache creation date. - */ - case RECTYPE_DATE: - if (!strncmp("date", rec->dbfld[i].fldname,4)) { - time_t tm; - tm = be_read32(recdata) * 24 * 3600; - tm -= EPOCH_1904; - wpt->creation_time = tm; - warning( "date %d\n", tm); - } - break; +/* This really is the date of the find, +* not the cache creation date. +*/ +case RECTYPE_DATE: +if (!strncmp("date", rec->dbfld[i].fldname,4)) { +time_t tm; +tm = be_read32(recdata) * 24 * 3600; +tm -= EPOCH_1904; +wpt->creation_time = tm; +warning("date %d\n", tm); +} +break; #endif - } - recdata += (length + 1) & (~1); - } - wpt->latitude = lat_dir * (lat_deg + lat_min/60); - wpt->longitude = lon_dir * (lon_deg + lon_min/60); - waypt_add(wpt); - } +} +recdata += (length + 1) & (~1); +} +wpt->latitude = lat_dir * (lat_deg + lat_min/60); +wpt->longitude = lon_dir * (lon_deg + lon_min/60); +waypt_add(wpt); +} } -static int +static int gcdb_add_to_rec(struct dbrec *rec, const char *fldname, gcdb_rectype rectype, void *data) { - int length; - static int rec_cnt; - - if (!tbuf) { - tbuf = xcalloc(MAXRECSZ, 1); - tbufp = tbuf; - } - - if (fldname == NULL) { - length = tbufp - tbuf; - be_write16(&rec->nflds, rec_cnt); - memcpy(&rec->dbfld[rec_cnt],tbuf, length); - tbufp = tbuf; - length += 4 + sizeof(struct dbfld) * rec_cnt; - rec_cnt = 0; - return length; - } - - be_write16(&rec->dbfld[rec_cnt].fldtype,rectype); - strncpy(rec->dbfld[rec_cnt].fldname, fldname, 4); - - switch (rectype) { - case RECTYPE_TEXT: - length = 1 + strlen(data); - be_write16(&rec->dbfld[rec_cnt].fldlen, length); - strcpy(tbufp, data); - tbufp += (length + 1) & (~1); - break; - case RECTYPE_DATE: - length = 4; - be_write16(&rec->dbfld[rec_cnt].fldlen, length); - be_write32(tbufp, ((time_t)data - EPOCH_1904)/ (3600 * 24)); - tbufp += length; - break; - default: - abort(); - } - rec_cnt++; - - return length; +int length; +static int rec_cnt; + +if (!tbuf) { +tbuf = xcalloc(MAXRECSZ, 1); +tbufp = tbuf; +} + +if (fldname == NULL) { +length = tbufp - tbuf; +be_write16(&rec->nflds, rec_cnt); +memcpy(&rec->dbfld[rec_cnt],tbuf, length); +tbufp = tbuf; +length += 4 + sizeof(struct dbfld) * rec_cnt; +rec_cnt = 0; +return length; +} + +be_write16(&rec->dbfld[rec_cnt].fldtype,rectype); +strncpy(rec->dbfld[rec_cnt].fldname, fldname, 4); + +switch (rectype) { +case RECTYPE_TEXT: +length = 1 + strlen(data); +be_write16(&rec->dbfld[rec_cnt].fldlen, length); +strcpy(tbufp, data); +tbufp += (length + 1) & (~1); +break; +case RECTYPE_DATE: +length = 4; +be_write16(&rec->dbfld[rec_cnt].fldlen, length); +be_write32(tbufp, ((time_t)data - EPOCH_1904)/ (3600 * 24)); +tbufp += length; +break; +default: +abort(); +} +rec_cnt++; + +return length; } static void gcdb_write_wpt(const waypoint *wpt) { - struct dbrec *rec; - int reclen; - char tbuf[100]; +struct dbrec *rec; +int reclen; +char tbuf[100]; - /* - * We don't really know how many fields we'll have or how long - * they'll be so we'll just lazily create a huge place to hold them. - */ - rec = xcalloc(sizeof(*rec) + 500, 1); +/* +* We don't really know how many fields we'll have or how long +* they'll be so we'll just lazily create a huge place to hold them. +*/ +rec = xcalloc(sizeof(*rec) + 500, 1); - gcdb_add_to_rec(rec, "gcna", RECTYPE_TEXT, wpt->description); - gcdb_add_to_rec(rec, "gcid", RECTYPE_TEXT, wpt->shortname); +gcdb_add_to_rec(rec, "gcna", RECTYPE_TEXT, wpt->description); +gcdb_add_to_rec(rec, "gcid", RECTYPE_TEXT, wpt->shortname); - gcdb_add_to_rec(rec, "lat0", RECTYPE_TEXT, - wpt->latitude < 0 ? "S" : "N"); +gcdb_add_to_rec(rec, "lat0", RECTYPE_TEXT, +wpt->latitude < 0 ? "S" : "N"); - sprintf(tbuf, "%d", (int) wpt->latitude); - gcdb_add_to_rec(rec, "lat1", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%d", (int) wpt->latitude); +gcdb_add_to_rec(rec, "lat1", RECTYPE_TEXT, tbuf); - sprintf(tbuf, "%f", 60 * (wpt->latitude - - (int) wpt->latitude)); - gcdb_add_to_rec(rec, "lat2", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%f", 60 * (wpt->latitude - +(int) wpt->latitude)); +gcdb_add_to_rec(rec, "lat2", RECTYPE_TEXT, tbuf); - gcdb_add_to_rec(rec, "lon0", RECTYPE_TEXT, - wpt->longitude < 0 ? "W" : "E"); +gcdb_add_to_rec(rec, "lon0", RECTYPE_TEXT, +wpt->longitude < 0 ? "W" : "E"); - sprintf(tbuf, "%d", (int) wpt->longitude); - gcdb_add_to_rec(rec, "lon1", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%d", (int) wpt->longitude); +gcdb_add_to_rec(rec, "lon1", RECTYPE_TEXT, tbuf); - sprintf(tbuf, "%f", 60 * (wpt->longitude - - (int) wpt->longitude)); - gcdb_add_to_rec(rec, "lon2", RECTYPE_TEXT, tbuf); +sprintf(tbuf, "%f", 60 * (wpt->longitude - +(int) wpt->longitude)); +gcdb_add_to_rec(rec, "lon2", RECTYPE_TEXT, tbuf); - if (wpt->gc_data->diff) { - sprintf(tbuf, "%f", wpt->gc_data->diff / 10.0); - gcdb_add_to_rec(rec, "diff", RECTYPE_TEXT, tbuf); - } +if (wpt->gc_data->diff) { +sprintf(tbuf, "%f", wpt->gc_data->diff / 10.0); +gcdb_add_to_rec(rec, "diff", RECTYPE_TEXT, tbuf); +} - if (wpt->gc_data->terr) { - sprintf(tbuf, "%f", wpt->gc_data->terr / 10.0); - gcdb_add_to_rec(rec, "terr", RECTYPE_TEXT, tbuf); - } +if (wpt->gc_data->terr) { +sprintf(tbuf, "%f", wpt->gc_data->terr / 10.0); +gcdb_add_to_rec(rec, "terr", RECTYPE_TEXT, tbuf); +} #if 0 - /* This really is the date of the find, - * not the cache creation date. - */ - if (wpt->creation_time) { - gcdb_add_to_rec(rec, "date", RECTYPE_DATE, (void *) wpt->creation_time); - } +/* This really is the date of the find, +* not the cache creation date. +*/ +if (wpt->creation_time) { +gcdb_add_to_rec(rec, "date", RECTYPE_DATE, (void *) wpt->creation_time); +} #endif - /* - * We're done. Build the record. - */ - reclen = gcdb_add_to_rec(rec, NULL, 0, NULL); +/* +* We're done. Build the record. +*/ +reclen = gcdb_add_to_rec(rec, NULL, 0, NULL); - pdb_write_rec(file_out, 0, 2, ct++, rec, reclen); - xfree(rec); +pdb_write_rec(file_out, 0, 2, ct++, rec, reclen); +xfree(rec); } static void data_write(void) { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - strncpy(file_out->name, "GeocachingDB", PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - waypt_disp_all(gcdb_write_wpt); + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + strncpy(file_out->name, "GeocachingDB", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + waypt_disp_all(gcdb_write_wpt); } ff_vecs_t gcdb_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gdb.c b/gpsbabel/gdb.c index 022b14756..c1b932d1b 100644 --- a/gpsbabel/gdb.c +++ b/gpsbabel/gdb.c @@ -1,10 +1,10 @@ /* Garmin GPS Database Reader/Writer - + Copyright (C) 2005-2008 Olaf Klein, o.b.klein@gpsbabel.org Mainly based on mapsource.c, Copyright (C) 2005 Robert Lipe, robertlipe@usa.net - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,7 +23,7 @@ /* History: - + 2005/06/27: initial release (reader only) 2005/07/26: added write support 2005/07/27: replaced "tricky code" in route reader @@ -143,15 +143,16 @@ static int trk_ct; /* informational: total number of tracks in/out */ static void gdb_flush_waypt_queue(queue *Q) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(Q, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - dequeue(elem); - if (wpt->extra_data) - xfree(wpt->extra_data); - waypt_free(wpt); - } + queue *elem, *tmp; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + dequeue(elem); + if (wpt->extra_data) { + xfree(wpt->extra_data); + } + waypt_free(wpt); + } } @@ -159,26 +160,32 @@ gdb_flush_waypt_queue(queue *Q) static void disp_summary(const gbfile *f) { - int i, len; - - len = strlen(f->name); - - warning(MYNAME ": ====================="); - for (i = 0; i < len; i++) warning("="); - warning("\n" MYNAME ": %s summary for \"%s\"\n", - (f->mode == 'r') ? "Reader" : "Writer", f->name); - - warning(MYNAME ": ---------------------"); - for (i = 0; i < len; i++) warning("-"); - - warning("\n" MYNAME ": %d waypoint(s)\n", waypt_ct - waypth_ct); - warning(MYNAME ": %d hidden waypoint(s)\n", waypth_ct); - warning(MYNAME ": %d route(s) with total %d point(s)\n", rte_ct, rtept_ct); - warning(MYNAME ": %d track(s) with total %d point(s)\n", trk_ct, trkpt_ct); - warning(MYNAME ": ---------------------"); - - for (i = 0; i < len; i++) warning("-"); - warning("\n"); + int i, len; + + len = strlen(f->name); + + warning(MYNAME ": ====================="); + for (i = 0; i < len; i++) { + warning("="); + } + warning("\n" MYNAME ": %s summary for \"%s\"\n", + (f->mode == 'r') ? "Reader" : "Writer", f->name); + + warning(MYNAME ": ---------------------"); + for (i = 0; i < len; i++) { + warning("-"); + } + + warning("\n" MYNAME ": %d waypoint(s)\n", waypt_ct - waypth_ct); + warning(MYNAME ": %d hidden waypoint(s)\n", waypth_ct); + warning(MYNAME ": %d route(s) with total %d point(s)\n", rte_ct, rtept_ct); + warning(MYNAME ": %d track(s) with total %d point(s)\n", trk_ct, trkpt_ct); + warning(MYNAME ": ---------------------"); + + for (i = 0; i < len; i++) { + warning("-"); + } + warning("\n"); } #else #define disp_summary(a) @@ -201,146 +208,162 @@ disp_summary(const gbfile *f) static char * nice(const char *str) { - char *res, *env; - cet_cs_vec_t *vec; - - if (!(str && *str)) return ""; - - env = getenv("LANG"); - if (env == NULL) return (char *)str; - - if ((res = strchr(env, '.'))) env = ++res; - vec = cet_find_cs_by_name(env); - - if ((vec != NULL) && (vec != global_opts.charset)) { - static char buf[128]; - res = cet_str_any_to_any(str, global_opts.charset, vec); - strncpy(buf, res, sizeof(buf)); - xfree(res); - return buf; - } - else return (char *)str; + char *res, *env; + cet_cs_vec_t *vec; + + if (!(str && *str)) { + return ""; + } + + env = getenv("LANG"); + if (env == NULL) { + return (char *)str; + } + + if ((res = strchr(env, '.'))) { + env = ++res; + } + vec = cet_find_cs_by_name(env); + + if ((vec != NULL) && (vec != global_opts.charset)) { + static char buf[128]; + res = cet_str_any_to_any(str, global_opts.charset, vec); + strncpy(buf, res, sizeof(buf)); + xfree(res); + return buf; + } else { + return (char *)str; + } } -#endif +#endif static char * gdb_fread_cstr(gbfile *fin) { - char *result = gbfgetcstr(fin); - - if (result && (*result == '\0')) { - xfree(result); - result = NULL; - } - return result; + char *result = gbfgetcstr(fin); + + if (result && (*result == '\0')) { + xfree(result); + result = NULL; + } + return result; } static int gdb_fread_str(char *buf, int size, gbfile *fin) { - char c; - int res = 0; - - while (size--) { - gbfread(&c, 1, 1, fin); - buf[res] = c; - if (c == '\0') return res; - res++; - } - buf[res] = '\0'; - return res; + char c; + int res = 0; + + while (size--) { + gbfread(&c, 1, 1, fin); + buf[res] = c; + if (c == '\0') { + return res; + } + res++; + } + buf[res] = '\0'; + return res; } static char * gdb_fread_strlist(void) { - char *res = NULL; - int count; - - count = FREAD_i32; - - while (count > 0) { - char *str = FREAD_CSTR; - if (str != NULL) { - if (*str && (res == NULL)) res = str; - else xfree(str); - } - count--; - } - - return res; + char *res = NULL; + int count; + + count = FREAD_i32; + + while (count > 0) { + char *str = FREAD_CSTR; + if (str != NULL) { + if (*str && (res == NULL)) { + res = str; + } else { + xfree(str); + } + } + count--; + } + + return res; } static waypoint * gdb_find_wayptq(const queue *Q, const waypoint *wpt, const char exact) { - queue *elem, *tmp; - const char *name = wpt->shortname; - - QUEUE_FOR_EACH(Q, elem, tmp) { - waypoint *tmp = (waypoint *)elem; - if (case_ignore_strcmp(name, tmp->shortname) == 0) { - - if (! exact) return tmp; - - if ((tmp->latitude == wpt->latitude) && - (tmp->longitude == wpt->longitude)) - return tmp; - } - } - return NULL; + queue *elem, *tmp; + const char *name = wpt->shortname; + + QUEUE_FOR_EACH(Q, elem, tmp) { + waypoint *tmp = (waypoint *)elem; + if (case_ignore_strcmp(name, tmp->shortname) == 0) { + + if (! exact) { + return tmp; + } + + if ((tmp->latitude == wpt->latitude) && + (tmp->longitude == wpt->longitude)) { + return tmp; + } + } + } + return NULL; } static waypoint * gdb_reader_find_waypt(const waypoint *wpt, const char exact) { - waypoint *res; - res = gdb_find_wayptq(&wayptq_in, wpt, exact); - if (res == NULL) - res = gdb_find_wayptq(&wayptq_in_hidden, wpt, exact); - return res; + waypoint *res; + res = gdb_find_wayptq(&wayptq_in, wpt, exact); + if (res == NULL) { + res = gdb_find_wayptq(&wayptq_in_hidden, wpt, exact); + } + return res; } static waypoint * gdb_add_route_waypt(route_head *rte, waypoint *ref, const int wpt_class) { - waypoint *tmp, *res; - int turn_point; - - tmp = gdb_reader_find_waypt(ref, 1); - if (tmp == NULL) { - double dist; - - tmp = find_waypt_by_name(ref->shortname); - if (tmp == NULL) { - route_add_wpt(rte, ref); - return ref; - } - - /* At this point we have found a waypoint with same name, - but probably from another data stream. Check coordinates! - */ - dist = radtometers(gcdist( - RAD(ref->latitude), RAD(ref->longitude), - RAD(tmp->latitude), RAD(tmp->longitude))); - - if (fabs(dist) > 100) { - warning(MYNAME ": Route point mismatch!\n"); - warning(MYNAME ": \"%s\" from waypoints differs to \"%s\"\n", - tmp->shortname, ref->shortname); - fatal(MYNAME ": from route table by more than %0.1f meters!\n", - dist); - - } - } - res = NULL; - turn_point = (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && tmp->description); - if (turn_point || (gdb_via == 0) || (wpt_class < gt_waypt_class_map_point)) { - res = waypt_dupe(tmp); - route_add_wpt(rte, res); - } - waypt_free(ref); - return res; + waypoint *tmp, *res; + int turn_point; + + tmp = gdb_reader_find_waypt(ref, 1); + if (tmp == NULL) { + double dist; + + tmp = find_waypt_by_name(ref->shortname); + if (tmp == NULL) { + route_add_wpt(rte, ref); + return ref; + } + + /* At this point we have found a waypoint with same name, + but probably from another data stream. Check coordinates! + */ + dist = radtometers(gcdist( + RAD(ref->latitude), RAD(ref->longitude), + RAD(tmp->latitude), RAD(tmp->longitude))); + + if (fabs(dist) > 100) { + warning(MYNAME ": Route point mismatch!\n"); + warning(MYNAME ": \"%s\" from waypoints differs to \"%s\"\n", + tmp->shortname, ref->shortname); + fatal(MYNAME ": from route table by more than %0.1f meters!\n", + dist); + + } + } + res = NULL; + turn_point = (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && tmp->description); + if (turn_point || (gdb_via == 0) || (wpt_class < gt_waypt_class_map_point)) { + res = waypt_dupe(tmp); + route_add_wpt(rte, res); + } + waypt_free(ref); + return res; } /*******************************************************************************/ @@ -360,32 +383,34 @@ gdb_add_route_waypt(route_head *rte, waypoint *ref, const int wpt_class) static void gdb_write_cstr_list(const char *str) { - if NOT_EMPTY(str) { - gbfputint32(1, fout); - gbfputcstr(str, fout); - } else - gbfputint32(0, fout); + if NOT_EMPTY(str) { + gbfputint32(1, fout); + gbfputcstr(str, fout); + } else { + gbfputint32(0, fout); + } } static void gdb_write_dbl(const double value, const double def) { - if (value == def) gbfputc(0, fout); - else { - gbfputc(1, fout); - gbfputdbl(value, fout); - } + if (value == def) { + gbfputc(0, fout); + } else { + gbfputc(1, fout); + gbfputdbl(value, fout); + } } static void gdb_write_time(const int time) { - if (time > 0) { - gbfputc(1, fout); - gbfputint32(time, fout); - } - else - gbfputc(0, fout); + if (time > 0) { + gbfputc(1, fout); + gbfputint32(time, fout); + } else { + gbfputc(0, fout); + } } /*******************************************************************************/ @@ -395,44 +420,48 @@ gdb_write_time(const int time) static void read_file_header(void) { - char buf[128]; - int i, reclen; - -/* - We are beginning with a simple binary read. -*/ - FREAD(buf, 6); -/* - A "gbfgetcstr" (FREAD_CSTR) works too, but if we get a wrong file as input, - the file validation my be comes too late. For example a XML base file normally - has no binary zeros inside and produce, if big enought, a buffer overflow. - The following message "local buffer overflow detected..." could be - misinterpreted. -*/ - is_fatal(strcmp(buf, "MsRcf") != 0, MYNAME ": Invalid file \"%s\"!", fin->name); - - reclen = FREAD_i32; - i = FREAD_STR(buf); - is_fatal(buf[0] != 'D', MYNAME ": Invalid file \"%s\"!", fin->name); - - gdb_ver = buf[1] - 'k' + 1; - is_fatal((gdb_ver < GDB_VER_MIN) || (gdb_ver > GDB_VER_MAX), - MYNAME ": Unknown or/and unsupported GDB version (%d.0)!", gdb_ver); - - if (global_opts.verbose_status > 0) - printf(MYNAME ": Reading Garmin GPS Database version %d.0\n", gdb_ver); - - reclen = FREAD_i32; - i = FREAD(buf, reclen + 1); - if (global_opts.verbose_status > 0) { - char *name = buf+2; - if (strstr(name, "SQA") == 0) name = "MapSource"; - else if (strstr(name, "neaderhi") == 0) name = "MapSource BETA"; - warning(MYNAME ": File created with \"%s\"\n", name); - } - - i = FREAD_STR(buf); - is_fatal(!(((i == 9) && (strcmp(buf, "MapSource") == 0)) || ((i == 8) && (strcmp(buf, "BaseCamp") == 0))), MYNAME ": Not a recognized signature in header"); + char buf[128]; + int i, reclen; + + /* + We are beginning with a simple binary read. + */ + FREAD(buf, 6); + /* + A "gbfgetcstr" (FREAD_CSTR) works too, but if we get a wrong file as input, + the file validation my be comes too late. For example a XML base file normally + has no binary zeros inside and produce, if big enought, a buffer overflow. + The following message "local buffer overflow detected..." could be + misinterpreted. + */ + is_fatal(strcmp(buf, "MsRcf") != 0, MYNAME ": Invalid file \"%s\"!", fin->name); + + reclen = FREAD_i32; + i = FREAD_STR(buf); + is_fatal(buf[0] != 'D', MYNAME ": Invalid file \"%s\"!", fin->name); + + gdb_ver = buf[1] - 'k' + 1; + is_fatal((gdb_ver < GDB_VER_MIN) || (gdb_ver > GDB_VER_MAX), + MYNAME ": Unknown or/and unsupported GDB version (%d.0)!", gdb_ver); + + if (global_opts.verbose_status > 0) { + printf(MYNAME ": Reading Garmin GPS Database version %d.0\n", gdb_ver); + } + + reclen = FREAD_i32; + i = FREAD(buf, reclen + 1); + if (global_opts.verbose_status > 0) { + char *name = buf+2; + if (strstr(name, "SQA") == 0) { + name = "MapSource"; + } else if (strstr(name, "neaderhi") == 0) { + name = "MapSource BETA"; + } + warning(MYNAME ": File created with \"%s\"\n", name); + } + + i = FREAD_STR(buf); + is_fatal(!(((i == 9) && (strcmp(buf, "MapSource") == 0)) || ((i == 8) && (strcmp(buf, "BaseCamp") == 0))), MYNAME ": Not a recognized signature in header"); } /*-----------------------------------------------------------------------------*/ @@ -440,243 +469,255 @@ read_file_header(void) static waypoint * read_waypoint(gt_waypt_classes_e *waypt_class_out) { - char buf[128]; /* used for temporary stuff */ - int display, icon, dynamic; - gt_waypt_classes_e wpt_class; - int i; - waypoint *res; - garmin_fs_t *gmsd; - char *str; - char *bufp = buf; + char buf[128]; /* used for temporary stuff */ + int display, icon, dynamic; + gt_waypt_classes_e wpt_class; + int i; + waypoint *res; + garmin_fs_t *gmsd; + char *str; + char *bufp = buf; #ifdef GMSD_EXPERIMENTAL - char subclass[22]; + char subclass[22]; #endif #if GDB_DEBUG - char *sn; + char *sn; #endif - waypt_ct++; - res = waypt_new(); + waypt_ct++; + res = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&res->fs, (format_specific_data *) gmsd); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&res->fs, (format_specific_data *) gmsd); - res->shortname = FREAD_CSTR; + res->shortname = FREAD_CSTR; #if GDB_DEBUG - sn = xstrdup(nice(res->shortname)); + sn = xstrdup(nice(res->shortname)); #endif - wpt_class = FREAD_i32; - GMSD_SET(wpt_class, wpt_class); - if (wpt_class != 0) waypth_ct++; - - FREAD_STR(buf); /* Country code */ - GMSD_SETSTR(cc, bufp); - + wpt_class = FREAD_i32; + GMSD_SET(wpt_class, wpt_class); + if (wpt_class != 0) { + waypth_ct++; + } + + FREAD_STR(buf); /* Country code */ + GMSD_SETSTR(cc, bufp); + #ifdef GMSD_EXPERIMENTAL - FREAD(subclass, sizeof(subclass)); - if (gmsd && (wpt_class >= gt_waypt_class_map_point)) { - memcpy(gmsd->subclass, subclass, sizeof(gmsd->subclass)); - gmsd->flags.subclass = 1; - } + FREAD(subclass, sizeof(subclass)); + if (gmsd && (wpt_class >= gt_waypt_class_map_point)) { + memcpy(gmsd->subclass, subclass, sizeof(gmsd->subclass)); + gmsd->flags.subclass = 1; + } #else - FREAD(buf, 22); + FREAD(buf, 22); #endif - res->latitude = FREAD_LATLON; - res->longitude = FREAD_LATLON; + res->latitude = FREAD_LATLON; + res->longitude = FREAD_LATLON; - if (FREAD_C == 1) { - double alt = FREAD_DBL; - if (alt < 1.0e24) { - res->altitude = alt; + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) { + res->altitude = alt; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Altitude = %.1f\n", - sn, wpt_class, alt); -#endif - } - } + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Altitude = %.1f\n", + sn, wpt_class, alt); +#endif + } + } #if GDB_DEBUG - DBG(GDB_DBG_WPT, 1) - printf(MYNAME "-wpt \"%s\": coordinates = %c%0.6f %c%0.6f\n", - sn, - res->latitude < 0 ? 'S' : 'N', res->latitude, - res->longitude < 0 ? 'W' : 'E', res->longitude); -#endif - res->notes = FREAD_CSTR; + DBG(GDB_DBG_WPT, 1) + printf(MYNAME "-wpt \"%s\": coordinates = %c%0.6f %c%0.6f\n", + sn, + res->latitude < 0 ? 'S' : 'N', res->latitude, + res->longitude < 0 ? 'W' : 'E', res->longitude); +#endif + res->notes = FREAD_CSTR; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, res->notes) { - char *str = gstrsub(res->notes, "\r\n", ", "); - printf(MYNAME "-wpt \"%s\" (%d): notes = %s\n", - sn, wpt_class, nice(str)); - xfree(str); - } + DBG(GDB_DBG_WPTe, res->notes) { + char *str = gstrsub(res->notes, "\r\n", ", "); + printf(MYNAME "-wpt \"%s\" (%d): notes = %s\n", + sn, wpt_class, nice(str)); + xfree(str); + } #endif - if (FREAD_C == 1) { - WAYPT_SET(res, proximity, FREAD_DBL); + if (FREAD_C == 1) { + WAYPT_SET(res, proximity, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Proximity = %.1f\n", - sn, wpt_class, res->proximity / 1000); -#endif - } - i = FREAD_i32; + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Proximity = %.1f\n", + sn, wpt_class, res->proximity / 1000); +#endif + } + i = FREAD_i32; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, i) - printf(MYNAME "-wpt \"%s\" (%d): display = %d\n", - sn, wpt_class, i); + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): display = %d\n", + sn, wpt_class, i); #endif - switch(i) { /* display value */ - case gt_gdb_display_mode_symbol: - display = gt_display_mode_symbol; break; - case gt_gdb_display_mode_symbol_and_comment: - display = gt_display_mode_symbol_and_comment; break; - default: - display = gt_display_mode_symbol_and_name; break; - } - GMSD_SET(display, display); - - FREAD_i32; /* color !not implemented! */ - icon = FREAD_i32; - GMSD_SET(icon, icon); /* icon */ - FREAD_STR(buf); /* city */ - GMSD_SETSTR(city, bufp); - FREAD_STR(buf); /* state */ - GMSD_SETSTR(state, bufp); - FREAD_STR(buf); /* facility */ - GMSD_SETSTR(facility, bufp); - - FREAD(buf, 1); - - if (FREAD_C == 1) { - WAYPT_SET(res, depth, FREAD_DBL); + switch (i) { /* display value */ + case gt_gdb_display_mode_symbol: + display = gt_display_mode_symbol; + break; + case gt_gdb_display_mode_symbol_and_comment: + display = gt_display_mode_symbol_and_comment; + break; + default: + display = gt_display_mode_symbol_and_name; + break; + } + GMSD_SET(display, display); + + FREAD_i32; /* color !not implemented! */ + icon = FREAD_i32; + GMSD_SET(icon, icon); /* icon */ + FREAD_STR(buf); /* city */ + GMSD_SETSTR(city, bufp); + FREAD_STR(buf); /* state */ + GMSD_SETSTR(state, bufp); + FREAD_STR(buf); /* facility */ + GMSD_SETSTR(facility, bufp); + + FREAD(buf, 1); + + if (FREAD_C == 1) { + WAYPT_SET(res, depth, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): Depth = %.1f\n", - sn, wpt_class, res->depth); -#endif - } - - /* VERSION DEPENDENT CODE */ - - if (gdb_ver <= GDB_VER_2) { - char *temp; - - FREAD(buf, 2); /* ?????????????????????????????????? */ - waypt_flag = FREAD_C; - if (waypt_flag == 0) - FREAD(buf, 3); - else - FREAD(buf, 2); - - temp = FREAD_CSTR; /* undocumented & unused string */ + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): Depth = %.1f\n", + sn, wpt_class, res->depth); +#endif + } + + /* VERSION DEPENDENT CODE */ + + if (gdb_ver <= GDB_VER_2) { + char *temp; + + FREAD(buf, 2); /* ?????????????????????????????????? */ + waypt_flag = FREAD_C; + if (waypt_flag == 0) { + FREAD(buf, 3); + } else { + FREAD(buf, 2); + } + + temp = FREAD_CSTR; /* undocumented & unused string */ #if GDB_DEBUG - DBG(GDB_DBG_WPTe, temp) - printf(MYNAME "-wpt \"%s\" (%d): Unknown string = %s\n", - sn, wpt_class, nice(temp)); -#endif - if (temp) xfree(temp); - - res->url = FREAD_CSTR; - if (wpt_class != 0) { - res->description = res->url; - res->url = NULL; - } - } - else { // if (gdb_ver >= GDB_VER_3) - int i, url_ct; - - waypt_flag = 0; - - FREAD_STR(buf); /* street address */ - GMSD_SETSTR(addr, bufp); - - FREAD(buf, 5); /* instruction depended */ - res->description = FREAD_CSTR; /* instruction */ - - url_ct = FREAD_i32; - for (i = url_ct; (i); i--) { - char *str = FREAD_CSTR; - if (str && *str) { - waypt_add_url(res, str, NULL); + DBG(GDB_DBG_WPTe, temp) + printf(MYNAME "-wpt \"%s\" (%d): Unknown string = %s\n", + sn, wpt_class, nice(temp)); +#endif + if (temp) { + xfree(temp); + } + + res->url = FREAD_CSTR; + if (wpt_class != 0) { + res->description = res->url; + res->url = NULL; + } + } else { // if (gdb_ver >= GDB_VER_3) + int i, url_ct; + + waypt_flag = 0; + + FREAD_STR(buf); /* street address */ + GMSD_SETSTR(addr, bufp); + + FREAD(buf, 5); /* instruction depended */ + res->description = FREAD_CSTR; /* instruction */ + + url_ct = FREAD_i32; + for (i = url_ct; (i); i--) { + char *str = FREAD_CSTR; + if (str && *str) { + waypt_add_url(res, str, NULL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): url(%d) = %s\n", - sn, wpt_class, url_ct - i, str); + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): url(%d) = %s\n", + sn, wpt_class, url_ct - i, str); #endif - } - } - } + } + } + } #if GDB_DEBUG - DBG(GDB_DBG_WPTe, res->description) - printf(MYNAME "-wpt \"%s\" (%d): description = %s\n", - sn, wpt_class, nice(res->description)); - DBG(GDB_DBG_WPTe, res->url) - printf(MYNAME "-wpt \"%s\" (%d): url = %s\n", - sn, wpt_class, nice(res->url)); + DBG(GDB_DBG_WPTe, res->description) + printf(MYNAME "-wpt \"%s\" (%d): description = %s\n", + sn, wpt_class, nice(res->description)); + DBG(GDB_DBG_WPTe, res->url) + printf(MYNAME "-wpt \"%s\" (%d): url = %s\n", + sn, wpt_class, nice(res->url)); #endif - i = FREAD_i16; - if (i != 0) GMSD_SET(category, i); + i = FREAD_i16; + if (i != 0) { + GMSD_SET(category, i); + } #if GDB_DEBUG - DBG(GDB_DBG_WPTe, i) - printf(MYNAME "-wpt \"%s\" (%d): category = %d\n", - sn, wpt_class, i); + DBG(GDB_DBG_WPTe, i) + printf(MYNAME "-wpt \"%s\" (%d): category = %d\n", + sn, wpt_class, i); #endif - - if (FREAD_C == 1) { - WAYPT_SET(res, temperature, FREAD_DBL); + + if (FREAD_C == 1) { + WAYPT_SET(res, temperature, FREAD_DBL); #if GDB_DEBUG - DBG(GDB_DBG_WPTe, 1) - printf(MYNAME "-wpt \"%s\" (%d): temperature = %.1f\n", - sn, wpt_class, res->temperature); + DBG(GDB_DBG_WPTe, 1) + printf(MYNAME "-wpt \"%s\" (%d): temperature = %.1f\n", + sn, wpt_class, res->temperature); #endif - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - if (waypt_flag != 0) FREAD(buf, 1); - } - if (FREAD_C == 1) { - res->creation_time = FREAD_i32; - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - if (FREAD_i32 == 1) { - FREAD_STR(buf); /* phone number */ - GMSD_SETSTR(phone_nr, bufp); - FREAD_STR(buf); /* ?? fax / mobile ?? */ - } - FREAD_STR(buf); /* country */ - GMSD_SETSTR(country, bufp); - FREAD_STR(buf); /* postal code */ - GMSD_SETSTR(postal_code, bufp); - } - - res->icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); - res->wpt_flags.icon_descr_is_dynamic = dynamic; + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + if (waypt_flag != 0) { + FREAD(buf, 1); + } + } + if (FREAD_C == 1) { + res->creation_time = FREAD_i32; + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + if (FREAD_i32 == 1) { + FREAD_STR(buf); /* phone number */ + GMSD_SETSTR(phone_nr, bufp); + FREAD_STR(buf); /* ?? fax / mobile ?? */ + } + FREAD_STR(buf); /* country */ + GMSD_SETSTR(country, bufp); + FREAD_STR(buf); /* postal code */ + GMSD_SETSTR(postal_code, bufp); + } + + res->icon_descr = gt_find_desc_from_icon_number(icon, GDB, &dynamic); + res->wpt_flags.icon_descr_is_dynamic = dynamic; #if GDB_DEBUG - DBG(GDB_DBG_WPTe, icon != GDB_DEF_ICON) - printf(MYNAME "-wpt \"%s\" (%d): icon = \"%s\" (MapSource symbol %d)\n", - sn, wpt_class, nice(res->icon_descr), icon); + DBG(GDB_DBG_WPTe, icon != GDB_DEF_ICON) + printf(MYNAME "-wpt \"%s\" (%d): icon = \"%s\" (MapSource symbol %d)\n", + sn, wpt_class, nice(res->icon_descr), icon); #endif - if ((str = GMSD_GET(cc, NULL))) { - if (! GMSD_HAS(country)) - GMSD_SETSTR(country, gt_get_icao_country(str)); - } - - if (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && res->description) { - wpt_class = gt_waypt_class_user_waypoint; - GMSD_SET(wpt_class, wpt_class); + if ((str = GMSD_GET(cc, NULL))) { + if (! GMSD_HAS(country)) { + GMSD_SETSTR(country, gt_get_icao_country(str)); + } + } + + if (gdb_roadbook && (wpt_class > gt_waypt_class_map_point) && res->description) { + wpt_class = gt_waypt_class_user_waypoint; + GMSD_SET(wpt_class, wpt_class); #ifdef GMSD_EXPERIMENTAL - GMSD_UNSET(subclass); + GMSD_UNSET(subclass); #endif - } + } #if GDB_DEBUG - xfree(sn); + xfree(sn); #endif - *waypt_class_out = wpt_class; - return res; + *waypt_class_out = wpt_class; + return res; } /*-----------------------------------------------------------------------------*/ @@ -684,202 +725,215 @@ read_waypoint(gt_waypt_classes_e *waypt_class_out) static route_head * read_route(void) { - route_head *rte; - int points, warnings, links, i; - char buf[128]; - bounds bounds; - int color_idx; - - rte_ct++; - warnings = 0; - - rte = route_head_alloc(); - rte->rte_name = FREAD_CSTR; - FREAD(buf, 1); /* display/autoname - 1 byte */ - - if (FREAD_C == 0) { /* max. data flag */ - /* maxlat = */ (void) FREAD_i32; - /* maxlon = */ (void) FREAD_i32; - if (FREAD_C == 1) /* maxalt = */ FREAD_DBL; - /* minlat = */ (void) FREAD_i32; - /* minlon = */ (void) FREAD_i32; - if (FREAD_C == 1) /* minalt = */ FREAD_DBL; - } - - links = 0; - points = FREAD_i32; - + route_head *rte; + int points, warnings, links, i; + char buf[128]; + bounds bounds; + int color_idx; + + rte_ct++; + warnings = 0; + + rte = route_head_alloc(); + rte->rte_name = FREAD_CSTR; + FREAD(buf, 1); /* display/autoname - 1 byte */ + + if (FREAD_C == 0) { /* max. data flag */ + /* maxlat = */ (void) FREAD_i32; + /* maxlon = */ + (void) FREAD_i32; + if (FREAD_C == 1) { /* maxalt = */ + FREAD_DBL; + } + /* minlat = */ (void) FREAD_i32; + /* minlon = */ + (void) FREAD_i32; + if (FREAD_C == 1) { /* minalt = */ + FREAD_DBL; + } + } + + links = 0; + points = FREAD_i32; + #if GDB_DEBUG - DBG(GDB_DBG_RTE, 1) - printf(MYNAME "-rte \"%s\": loading route with %d point(s)...\n", - nice(rte->rte_name), points); + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte \"%s\": loading route with %d point(s)...\n", + nice(rte->rte_name), points); #endif - for (i = 0; i < points; i++) { - int wpt_class, j; - char buf[128]; - garmin_ilink_t *il_root, *il_anchor; - - waypoint *wpt; - - wpt = waypt_new(); - rtept_ct++; - - wpt->shortname = FREAD_CSTR; /* shortname */ - wpt_class = FREAD_i32; /* waypoint class */ - FREAD_STR(buf); /* country code */ - FREAD(buf, 18 + 4); /* subclass part 1-3 / unknown */ - - if (FREAD_C != 0) { - FREAD(buf, 8); /* aviation data (?); only seen with class "1" (Airport) */ - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) - FREAD(buf, 8); /* a second block since V3 */ - } - - FREAD(buf, 18); /* unknown 18 bytes; but first should be 0x01 or 0x03 */ - /* seen also 0 with VER3 */ - if ((buf[0] != 0x00) && (buf[0] != 0x01) && (buf[0] != 0x03)) { - int i; - - warnings++; - if (warnings > 3) - fatal(MYNAME "-rte_pt \"%s\": too many warnings!\n", wpt->shortname); - warning(MYNAME "-rte_pt \"%s\" (class %d): possible error in route.\n", wpt->shortname, wpt_class); - warning(MYNAME "-rte_pt (dump):"); - for (i = 0; i < 18; i++) { - warning(" %02x", (unsigned char)buf[i]); - } - warning("\n"); - } - - links = FREAD_i32; - il_anchor = NULL; - il_root = NULL; + for (i = 0; i < points; i++) { + int wpt_class, j; + char buf[128]; + garmin_ilink_t *il_root, *il_anchor; + + waypoint *wpt; + + wpt = waypt_new(); + rtept_ct++; + + wpt->shortname = FREAD_CSTR; /* shortname */ + wpt_class = FREAD_i32; /* waypoint class */ + FREAD_STR(buf); /* country code */ + FREAD(buf, 18 + 4); /* subclass part 1-3 / unknown */ + + if (FREAD_C != 0) { + FREAD(buf, 8); /* aviation data (?); only seen with class "1" (Airport) */ + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + FREAD(buf, 8); /* a second block since V3 */ + } + } + + FREAD(buf, 18); /* unknown 18 bytes; but first should be 0x01 or 0x03 */ + /* seen also 0 with VER3 */ + if ((buf[0] != 0x00) && (buf[0] != 0x01) && (buf[0] != 0x03)) { + int i; + + warnings++; + if (warnings > 3) { + fatal(MYNAME "-rte_pt \"%s\": too many warnings!\n", wpt->shortname); + } + warning(MYNAME "-rte_pt \"%s\" (class %d): possible error in route.\n", wpt->shortname, wpt_class); + warning(MYNAME "-rte_pt (dump):"); + for (i = 0; i < 18; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + warning("\n"); + } + + links = FREAD_i32; + il_anchor = NULL; + il_root = NULL; #if GDB_DEBUG - DBG(GDB_DBG_RTE, links) - printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n", - nice(wpt->shortname), wpt_class, links); -#endif - for (j = 0; j < links; j++) { - garmin_ilink_t *il_step = xmalloc(sizeof(*il_step)); - - il_step->ref_count = 1; - - il_step->lat = FREAD_LATLON; - il_step->lon = FREAD_LATLON; - if (FREAD_C == 1) il_step->alt = FREAD_DBL; - else il_step->alt = unknown_alt; - - if (j == 0) { - wpt->latitude = il_step->lat; - wpt->longitude = il_step->lon; - wpt->altitude = il_step->alt; - } - - il_step->next = NULL; - if (il_anchor == NULL) - il_root = il_step; - else - il_anchor->next = il_step; - il_anchor = il_step; + DBG(GDB_DBG_RTE, links) + printf(MYNAME "-rte_pt \"%s\" (%d): %d interlink step(s)\n", + nice(wpt->shortname), wpt_class, links); +#endif + for (j = 0; j < links; j++) { + garmin_ilink_t *il_step = xmalloc(sizeof(*il_step)); + + il_step->ref_count = 1; + + il_step->lat = FREAD_LATLON; + il_step->lon = FREAD_LATLON; + if (FREAD_C == 1) { + il_step->alt = FREAD_DBL; + } else { + il_step->alt = unknown_alt; + } + + if (j == 0) { + wpt->latitude = il_step->lat; + wpt->longitude = il_step->lon; + wpt->altitude = il_step->alt; + } + + il_step->next = NULL; + if (il_anchor == NULL) { + il_root = il_step; + } else { + il_anchor->next = il_step; + } + il_anchor = il_step; #if GDB_DEBUG - DBG(GDB_DBG_RTEe, 1) { - printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n", - nice(wpt->shortname), j + 1, links, - il_step->lat < 0 ? 'S' : 'N', il_step->lat, - il_step->lon < 0 ? 'W' : 'E', il_step->lon); - } -#endif - } - - waypt_init_bounds(&bounds); - - if (FREAD_C == 0) { /* interlink bounds */ - bounds.max_lat = FREAD_LATLON; - bounds.max_lon = FREAD_LATLON; - if (FREAD_C == 1) - bounds.max_alt = FREAD_DBL; - bounds.min_lat = FREAD_LATLON; - bounds.min_lat = FREAD_LATLON; - if (FREAD_C == 1) - bounds.min_alt = FREAD_DBL; - } - - if (links == 0) { - /* Without links we need all informations from wpt */ - waypoint *tmp = gdb_reader_find_waypt(wpt, 0); - if (tmp != NULL) { - waypt_free(wpt); - wpt = waypt_dupe(tmp); - } - else { - if (waypt_bounds_valid(&bounds)) - warning(MYNAME ": (has bounds)\n"); - - warning(MYNAME ": Data corruption detected!\n"); - fatal(MYNAME ": Sleeping route point without coordinates!\n"); - } - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_2) { - FREAD(buf, 8); - if (gdb_ver >= GDB_VER_3) { - FREAD(buf, 2); - } - } + DBG(GDB_DBG_RTEe, 1) { + printf(MYNAME "-rte_il \"%s\" (%d of %d): %c%0.6f %c%0.6f\n", + nice(wpt->shortname), j + 1, links, + il_step->lat < 0 ? 'S' : 'N', il_step->lat, + il_step->lon < 0 ? 'W' : 'E', il_step->lon); + } +#endif + } + + waypt_init_bounds(&bounds); + + if (FREAD_C == 0) { /* interlink bounds */ + bounds.max_lat = FREAD_LATLON; + bounds.max_lon = FREAD_LATLON; + if (FREAD_C == 1) { + bounds.max_alt = FREAD_DBL; + } + bounds.min_lat = FREAD_LATLON; + bounds.min_lat = FREAD_LATLON; + if (FREAD_C == 1) { + bounds.min_alt = FREAD_DBL; + } + } + + if (links == 0) { + /* Without links we need all informations from wpt */ + waypoint *tmp = gdb_reader_find_waypt(wpt, 0); + if (tmp != NULL) { + waypt_free(wpt); + wpt = waypt_dupe(tmp); + } else { + if (waypt_bounds_valid(&bounds)) { + warning(MYNAME ": (has bounds)\n"); + } + + warning(MYNAME ": Data corruption detected!\n"); + fatal(MYNAME ": Sleeping route point without coordinates!\n"); + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FREAD(buf, 8); + if (gdb_ver >= GDB_VER_3) { + FREAD(buf, 2); + } + } #if GDB_DEBUG - DBG(GDB_DBG_RTE, 1) - printf(MYNAME "-rte_pt \"%s\": coordinates = %c%0.6f, %c%0.6f\n", - nice(wpt->shortname), - wpt->latitude < 0 ? 'S' : 'N', wpt->latitude, - wpt->longitude < 0 ? 'W' : 'E', wpt->longitude); -#endif - wpt = gdb_add_route_waypt(rte, wpt, wpt_class); - if (wpt != NULL) { - garmin_fs_t *gmsd = GMSD_FIND(wpt); - if (gmsd == NULL) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - GMSD_SET(wpt_class, wpt_class); - gmsd->ilinks = il_root; - il_root = NULL; - } - - while (il_root) { - garmin_ilink_t *il = il_root; - il_root = il_root->next; - xfree(il); - } - } /* ENDFOR: for (i = 0; i < points; i++) */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - rte->rte_url = FREAD_CSTR; - } - else { - rte->rte_url = gdb_fread_strlist(); - - color_idx = FREAD_i32; - rte->line_color.bbggrr = gt_color_value(color_idx); - FREAD(buf, 1); /* ?????????????????????????????????? */ - - rte->rte_desc = FREAD_CSTR; + DBG(GDB_DBG_RTE, 1) + printf(MYNAME "-rte_pt \"%s\": coordinates = %c%0.6f, %c%0.6f\n", + nice(wpt->shortname), + wpt->latitude < 0 ? 'S' : 'N', wpt->latitude, + wpt->longitude < 0 ? 'W' : 'E', wpt->longitude); +#endif + wpt = gdb_add_route_waypt(rte, wpt, wpt_class); + if (wpt != NULL) { + garmin_fs_t *gmsd = GMSD_FIND(wpt); + if (gmsd == NULL) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + GMSD_SET(wpt_class, wpt_class); + gmsd->ilinks = il_root; + il_root = NULL; + } + + while (il_root) { + garmin_ilink_t *il = il_root; + il_root = il_root->next; + xfree(il); + } + } /* ENDFOR: for (i = 0; i < points; i++) */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + rte->rte_url = FREAD_CSTR; + } else { + rte->rte_url = gdb_fread_strlist(); + + color_idx = FREAD_i32; + rte->line_color.bbggrr = gt_color_value(color_idx); + FREAD(buf, 1); /* ?????????????????????????????????? */ + + rte->rte_desc = FREAD_CSTR; #if 0 - /* replace CRLF's with ", " */ - if (rte->rte_desc) { - char *c = rte->rte_desc; - while ((c = strstr(c, "\r\n"))) { - *c++ = ','; - *c++ = ' '; - } - } + /* replace CRLF's with ", " */ + if (rte->rte_desc) { + char *c = rte->rte_desc; + while ((c = strstr(c, "\r\n"))) { + *c++ = ','; + *c++ = ' '; + } + } #endif - } - return rte; + } + return rte; } /*-----------------------------------------------------------------------------*/ @@ -887,61 +941,61 @@ read_route(void) static route_head * read_track(void) { - route_head *res; - int points, index; - char dummy; - int color_idx; + route_head *res; + int points, index; + char dummy; + int color_idx; - trk_ct++; + trk_ct++; - res = route_head_alloc(); - res->rte_name = FREAD_CSTR; + res = route_head_alloc(); + res->rte_name = FREAD_CSTR; // res->rte_num = trk_ct; - FREAD(&dummy, 1); /* display - 1 byte */ - color_idx = FREAD_i32; /* color - 1 dword */ - res->line_color.bbggrr = gt_color_value(color_idx); - - points = FREAD_i32; - - for (index = 0; index < points; index++) - { - waypoint *wpt = waypt_new(); - - trkpt_ct++; - - wpt->latitude = FREAD_LATLON; - wpt->longitude = FREAD_LATLON; - if (FREAD_C == 1) { - double alt = FREAD_DBL; - if (alt < 1.0e24) wpt->altitude = alt; - } - if (FREAD_C == 1) { - wpt->creation_time = FREAD_i32; - } - if (FREAD_C == 1) { - WAYPT_SET(wpt, depth, FREAD_DBL); - } - if (FREAD_C == 1) { - WAYPT_SET(wpt, temperature, FREAD_DBL); - } - - track_add_wpt(res, wpt); - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - res->rte_url = gdb_fread_strlist(); - } - else /* if (gdb_ver <= GDB_VER_2) */ { - res->rte_url = FREAD_CSTR; - } + FREAD(&dummy, 1); /* display - 1 byte */ + color_idx = FREAD_i32; /* color - 1 dword */ + res->line_color.bbggrr = gt_color_value(color_idx); + + points = FREAD_i32; + + for (index = 0; index < points; index++) { + waypoint *wpt = waypt_new(); + + trkpt_ct++; + + wpt->latitude = FREAD_LATLON; + wpt->longitude = FREAD_LATLON; + if (FREAD_C == 1) { + double alt = FREAD_DBL; + if (alt < 1.0e24) { + wpt->altitude = alt; + } + } + if (FREAD_C == 1) { + wpt->creation_time = FREAD_i32; + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, depth, FREAD_DBL); + } + if (FREAD_C == 1) { + WAYPT_SET(wpt, temperature, FREAD_DBL); + } + + track_add_wpt(res, wpt); + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + res->rte_url = gdb_fread_strlist(); + } else { /* if (gdb_ver <= GDB_VER_2) */ + res->rte_url = FREAD_CSTR; + } #if GDB_DEBUG - DBG(GDB_DBG_TRK, res->rte_url) - printf(MYNAME "-trk \"%s\": url = %s\n", - res->rte_name, res->rte_url); + DBG(GDB_DBG_TRK, res->rte_url) + printf(MYNAME "-trk \"%s\": url = %s\n", + res->rte_name, res->rte_url); #endif - return res; + return res; } /*******************************************************************************/ @@ -949,135 +1003,146 @@ read_track(void) static void gdb_rd_init(const char *fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - ftmp = gbfopen_le(NULL, "wb", MYNAME); - read_file_header(); - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_UTF8) - cet_convert_init(CET_CHARSET_UTF8, 1); - - QUEUE_INIT(&wayptq_in); - QUEUE_INIT(&wayptq_in_hidden); - - gdb_via = (gdb_opt_via && *gdb_opt_via) ? atoi(gdb_opt_via) : 0; - gdb_roadbook = (gdb_opt_roadbook && *gdb_opt_roadbook) ? atoi(gdb_opt_roadbook) : 0; - if (gdb_roadbook) /* higher priority */ gdb_via = 1; - - waypt_ct = 0; - waypth_ct = 0; - rtept_ct = 0; - trkpt_ct = 0; - rte_ct = 0; - trk_ct = 0; + fin = gbfopen_le(fname, "rb", MYNAME); + ftmp = gbfopen_le(NULL, "wb", MYNAME); + read_file_header(); + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_UTF8) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + QUEUE_INIT(&wayptq_in); + QUEUE_INIT(&wayptq_in_hidden); + + gdb_via = (gdb_opt_via && *gdb_opt_via) ? atoi(gdb_opt_via) : 0; + gdb_roadbook = (gdb_opt_roadbook && *gdb_opt_roadbook) ? atoi(gdb_opt_roadbook) : 0; + if (gdb_roadbook) { /* higher priority */ + gdb_via = 1; + } + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; } static void gdb_rd_deinit(void) { - disp_summary(fin); - gdb_flush_waypt_queue(&wayptq_in); - gdb_flush_waypt_queue(&wayptq_in_hidden); - gbfclose(ftmp); - gbfclose(fin); + disp_summary(fin); + gdb_flush_waypt_queue(&wayptq_in); + gdb_flush_waypt_queue(&wayptq_in_hidden); + gbfclose(ftmp); + gbfclose(fin); } static void read_data(void) { - gbfile *fsave; - int incomplete = 0; /* number of incomplete reads */ - - for (;;) { - int len, delta; - char typ, dump; - gt_waypt_classes_e wpt_class; - waypoint *wpt; - route_head *trk, *rte; - - len = FREAD_i32; - if (FREAD(&typ, 1) < 1) { - fatal(MYNAME ": Attempt to read past EOF."); - } - if (typ == 'V') break; /* break the loop */ - - gbfrewind(ftmp); - gbfwrite(NULL, 0, 0, ftmp); /* truncate */ - gbfcopyfrom(ftmp, fin, len); - gbfrewind(ftmp); - - fsave = fin; /* swap standard 'fin' with cached input */ - fin = ftmp; - - dump = 1; - wpt_class = GDB_DEF_CLASS; - - switch(typ) { - case 'W': - wpt = read_waypoint(&wpt_class); - if ((gdb_via == 0) || (wpt_class == 0)) { - waypoint *dupe; - waypt_add(wpt); - dupe = waypt_dupe(wpt); - ENQUEUE_TAIL(&wayptq_in, &dupe->Q); - } - else - ENQUEUE_TAIL(&wayptq_in_hidden, &wpt->Q); - break; - case 'R': - rte = read_route(); - if (rte) route_add_head(rte); - break; - case 'T': - trk = read_track(); - if (trk) track_add_head(trk); - break; - default: - dump = 0; /* make a dump only for main types */ - break; - } - - fin = fsave; - delta = len - gbftell(ftmp); - is_fatal(delta > 1000000, "Internal consistency error. Delta too big"); - - // Avoid finite loop on bogus beta files from '06. - // THe 100000 is totally pulled from my hat. - // is_fatal((delta > 1000000) || (delta < 0), "Internal GDB error; invalid delta."); - - if (dump && delta) { - if (! incomplete++) { - warning(MYNAME ":==========================================\n"); - warning(MYNAME ":=== W A R N I N G ===\n"); - } - if (typ == 'W') - warning(MYNAME ":(%d%c-%02d): delta = %d (flag=%3d/%02x)-", - gdb_ver, typ, wpt_class, delta, waypt_flag, waypt_flag); - else - warning(MYNAME ":(%d%c): delta = %d -", gdb_ver, typ, delta); - if (delta > 0) { - int i; - char *buf = xmalloc(delta); - if (FREAD(buf, delta) < 1) - fatal(MYNAME ": Attempt to read past EOF.\n"); - for (i = 0; i < delta; i++) { - warning(" %02x", (unsigned char)buf[i]); - } - xfree(buf); - } - warning("\n"); - } - } - - - if (incomplete) { - warning(MYNAME ":------------------------------------------\n"); - warning(MYNAME ": \"%s\"\n", fin->name); - warning(MYNAME ":------------------------------------------\n"); - warning(MYNAME ": Please mail this information\n"); - warning(MYNAME " and, if you can, the used GDB file\n"); - warning(MYNAME ": to gpsbabel-misc@lists.sourceforge.net\n"); - warning(MYNAME ":==========================================\n"); - } + gbfile *fsave; + int incomplete = 0; /* number of incomplete reads */ + + for (;;) { + int len, delta; + char typ, dump; + gt_waypt_classes_e wpt_class; + waypoint *wpt; + route_head *trk, *rte; + + len = FREAD_i32; + if (FREAD(&typ, 1) < 1) { + fatal(MYNAME ": Attempt to read past EOF."); + } + if (typ == 'V') { + break; /* break the loop */ + } + + gbfrewind(ftmp); + gbfwrite(NULL, 0, 0, ftmp); /* truncate */ + gbfcopyfrom(ftmp, fin, len); + gbfrewind(ftmp); + + fsave = fin; /* swap standard 'fin' with cached input */ + fin = ftmp; + + dump = 1; + wpt_class = GDB_DEF_CLASS; + + switch (typ) { + case 'W': + wpt = read_waypoint(&wpt_class); + if ((gdb_via == 0) || (wpt_class == 0)) { + waypoint *dupe; + waypt_add(wpt); + dupe = waypt_dupe(wpt); + ENQUEUE_TAIL(&wayptq_in, &dupe->Q); + } else { + ENQUEUE_TAIL(&wayptq_in_hidden, &wpt->Q); + } + break; + case 'R': + rte = read_route(); + if (rte) { + route_add_head(rte); + } + break; + case 'T': + trk = read_track(); + if (trk) { + track_add_head(trk); + } + break; + default: + dump = 0; /* make a dump only for main types */ + break; + } + + fin = fsave; + delta = len - gbftell(ftmp); + is_fatal(delta > 1000000, "Internal consistency error. Delta too big"); + + // Avoid finite loop on bogus beta files from '06. + // THe 100000 is totally pulled from my hat. + // is_fatal((delta > 1000000) || (delta < 0), "Internal GDB error; invalid delta."); + + if (dump && delta) { + if (! incomplete++) { + warning(MYNAME ":==========================================\n"); + warning(MYNAME ":=== W A R N I N G ===\n"); + } + if (typ == 'W') + warning(MYNAME ":(%d%c-%02d): delta = %d (flag=%3d/%02x)-", + gdb_ver, typ, wpt_class, delta, waypt_flag, waypt_flag); + else { + warning(MYNAME ":(%d%c): delta = %d -", gdb_ver, typ, delta); + } + if (delta > 0) { + int i; + char *buf = xmalloc(delta); + if (FREAD(buf, delta) < 1) { + fatal(MYNAME ": Attempt to read past EOF.\n"); + } + for (i = 0; i < delta; i++) { + warning(" %02x", (unsigned char)buf[i]); + } + xfree(buf); + } + warning("\n"); + } + } + + + if (incomplete) { + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": \"%s\"\n", fin->name); + warning(MYNAME ":------------------------------------------\n"); + warning(MYNAME ": Please mail this information\n"); + warning(MYNAME " and, if you can, the used GDB file\n"); + warning(MYNAME ": to gpsbabel-misc@lists.sourceforge.net\n"); + warning(MYNAME ":==========================================\n"); + } } /*******************************************************************************/ @@ -1088,18 +1153,19 @@ read_data(void) static void reset_short_handle(const char *defname) { - if (short_h != NULL) - mkshort_del_handle(&short_h); - - short_h = mkshort_new_handle(); - - setshort_length(short_h, GDB_NAME_BUFFERLEN); - setshort_badchars(short_h, "\r\n\t"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - setshort_defname(short_h, defname); + if (short_h != NULL) { + mkshort_del_handle(&short_h); + } + + short_h = mkshort_new_handle(); + + setshort_length(short_h, GDB_NAME_BUFFERLEN); + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, defname); } /* ----------------------------------------------------------------------------*/ @@ -1107,381 +1173,406 @@ reset_short_handle(const char *defname) static void write_header(void) { - char buff[128], tbuff[32]; - char *c; - int len; - struct tm tm; - - FWRITE_CSTR("MsRcf"); - FWRITE_i32(2); - - strncpy(buff, "Dx", sizeof(buff)); - buff[1] = 'k' - 1 + gdb_ver; - FWRITE_CSTR(buff); - + char buff[128], tbuff[32]; + char *c; + int len; + struct tm tm; + + FWRITE_CSTR("MsRcf"); + FWRITE_i32(2); + + strncpy(buff, "Dx", sizeof(buff)); + buff[1] = 'k' - 1 + gdb_ver; + FWRITE_CSTR(buff); + #if 0 - /* Take this if anything is wrong with our self generated watermark */ - strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ + /* Take this if anything is wrong with our self generated watermark */ + strncpy(buff, "A].SQA*Dec 27 2004*17:40:51", sizeof(buff)); /* MapSource V6.5 */ #else - /* This is our "Watermark" to show this file was created by GPSbabel */ - - /* history: - - "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00" - gpsbabel V1.2.7 BETA - "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00" - gpsbabel 1.2.8-beta01182006_clyde - "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00" - gpsbabel 1.2.8-beta20060405 - "A].GPSBabel-1.3*Jul 02 2006*20:13:00" - gpsbabel 1.3.0 - "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00" - gpsbabel 1.3.1 - "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 - - New since 11/01/2006: - version: version and release of gpsbabel (defined in configure.in) - timestamp: date and time of gdb.c (handled by CVS) - - "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 - "A].GPSBabel-beta20061125*Feb 06 2007*23:24:14" gpsbabel beta20061125 - "A].GPSBabel-1.3.3*Feb 20 2007*20:51:15" - gpsbabel 1.3.3 - - */ - - memset(&tm, 0, sizeof(tm)); - sscanf(gdb_release_date+7, "%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - tm.tm_year -= 1900; - tm.tm_mon -= 1; - strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); - snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); + /* This is our "Watermark" to show this file was created by GPSbabel */ + + /* history: + + "A].GPSBabel_1.2.7-beta*Sep 13 2005*20:10:00" - gpsbabel V1.2.7 BETA + "A].GPSBabel_1.2.8-beta*Jan 18 2006*20:11:00" - gpsbabel 1.2.8-beta01182006_clyde + "A].GPSBabel_1.2.8-beta*Apr 18 2006*20:12:00" - gpsbabel 1.2.8-beta20060405 + "A].GPSBabel-1.3*Jul 02 2006*20:13:00" - gpsbabel 1.3.0 + "A].GPSBabel-1.3.1*Sep 03 2006*20:14:00" - gpsbabel 1.3.1 + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + + New since 11/01/2006: + version: version and release of gpsbabel (defined in configure.in) + timestamp: date and time of gdb.c (handled by CVS) + + "A].GPSBabel-1.3.2*Nov 01 2006*22:23:39" - gpsbabel 1.3.2 + "A].GPSBabel-beta20061125*Feb 06 2007*23:24:14" gpsbabel beta20061125 + "A].GPSBabel-1.3.3*Feb 20 2007*20:51:15" - gpsbabel 1.3.3 + + */ + + memset(&tm, 0, sizeof(tm)); + sscanf(gdb_release_date+7, "%d/%d/%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + tm.tm_year -= 1900; + tm.tm_mon -= 1; + strftime(tbuff, sizeof(tbuff), "%b %d %Y*%H:%M:%S", &tm); + snprintf(buff, sizeof(buff), "A].GPSBabel-%s*%s", gpsbabel_version, tbuff); #endif - len = strlen(buff); - buff[2] = 2; + len = strlen(buff); + buff[2] = 2; - c = buff; - while ((c = strchr(c, '*'))) *c++ = '\0'; + c = buff; + while ((c = strchr(c, '*'))) { + *c++ = '\0'; + } - FWRITE_i32(len); - FWRITE(buff, len + 1); - FWRITE_CSTR("MapSource"); /* MapSource magic */ + FWRITE_i32(len); + FWRITE(buff, len + 1); + FWRITE_CSTR("MapSource"); /* MapSource magic */ } /*-----------------------------------------------------------------------------*/ /* - * gdb_check_waypt: As implemented in waypt_add, but we have some leaks where + * gdb_check_waypt: As implemented in waypt_add, but we have some leaks where * waypoints are modified after waypt_add. Maybe we need a data check * after each input module. */ - + static void gdb_check_waypt(waypoint *wpt) { - double lat_orig = wpt->latitude; - double lon_orig = wpt->longitude; - - if (wpt->latitude < -90) wpt->latitude += 180; - else if (wpt->latitude > +90) wpt->latitude -= 180; - if (wpt->longitude < -180) wpt->longitude += 360; - else if (wpt->longitude > +180) wpt->longitude -= 360; - - if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) - fatal ("Invalid latitude %f in waypoint %s.\n", - lat_orig, wpt->shortname ? wpt->shortname : ""); - if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) - fatal ("Invalid longitude %f in waypoint %s.\n", - lon_orig, wpt->shortname ? wpt->shortname : ""); + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + if (wpt->latitude < -90) { + wpt->latitude += 180; + } else if (wpt->latitude > +90) { + wpt->latitude -= 180; + } + if (wpt->longitude < -180) { + wpt->longitude += 360; + } else if (wpt->longitude > +180) { + wpt->longitude -= 360; + } + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal("Invalid latitude %f in waypoint %s.\n", + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); } /*-----------------------------------------------------------------------------*/ static void write_waypoint( - const waypoint *wpt, const char *shortname, garmin_fs_t *gmsd, - const int icon, const int display) + const waypoint *wpt, const char *shortname, garmin_fs_t *gmsd, + const int icon, const int display) { - char zbuf[32], ffbuf[32]; - int wpt_class; - - waypt_ct++; /* increase informational number of written waypoints */ - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xFF, sizeof(ffbuf)); - - wpt_class = wpt->microseconds; /* trick */ - - FWRITE_CSTR(shortname); /* uniqe (!!!) shortname */ - FWRITE_i32(wpt_class); /* waypoint class */ - FWRITE_CSTR(GMSD_GET(cc, "")); /* country code */ - - if (wpt_class != 0) waypth_ct++; + char zbuf[32], ffbuf[32]; + int wpt_class; + + waypt_ct++; /* increase informational number of written waypoints */ + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_CSTR(shortname); /* uniqe (!!!) shortname */ + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country code */ + + if (wpt_class != 0) { + waypth_ct++; + } #ifdef GMSD_EXPERIMENTAL - if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { - FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); - } - else + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + } else #endif - { - FWRITE(zbuf, 4); /* subclass part 1 */ - FWRITE(ffbuf, 12); /* subclass part 2 */ - FWRITE(zbuf, 2); /* subclass part 3 */ - FWRITE(ffbuf, 4); /* unknown */ - } - - FWRITE_LATLON(wpt->latitude); /* latitude */ - FWRITE_LATLON(wpt->longitude); /* longitude */ - FWRITE_DBL(wpt->altitude, unknown_alt); /* altitude */ - if (wpt->notes) - FWRITE_CSTR(wpt->notes); - else - FWRITE_CSTR(wpt->description); - FWRITE_DBL(WAYPT_GET(wpt, proximity, unknown_alt), unknown_alt); /* proximity */ - FWRITE_i32(display); /* display */ - FWRITE_i32(0); /* color */ - FWRITE_i32(icon); /* icon */ - FWRITE_CSTR(GMSD_GET(city, "")); /* city */ - FWRITE_CSTR(GMSD_GET(state, "")); /* state */ - FWRITE_CSTR(GMSD_GET(facility, "")); /* facility */ - FWRITE_C(0); /* unknown */ - FWRITE_DBL(WAYPT_GET(wpt, depth, unknown_alt), unknown_alt); /* depth */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - char *descr; - - FWRITE(zbuf, 3); - FWRITE(zbuf, 4); - descr = (wpt_class < gt_waypt_class_map_point) ? - wpt->url : wpt->description; - if ((descr != NULL) && (wpt_class >= gt_waypt_class_map_point) && \ - (strcmp(descr, wpt->shortname) == 0)) - descr = NULL; - FWRITE_CSTR(descr); - } - else /* if (gdb_ver > GDB_VER_3) */ { - int cnt; - url_link *url_next; - const char *str; - - if (wpt_class < gt_waypt_class_map_point) /* street address */ - str = GMSD_GET(addr, ""); - else - str = ""; - FWRITE_CSTR(str); - FWRITE(zbuf, 5); /* instruction dependend */ - - /* GBD doesn't have a native description field */ - /* here we misuse the instruction field */ - - str = wpt->description; - if (str && (strcmp(str, wpt->shortname) == 0)) str = NULL; - if (str && wpt->notes && (strcmp(str, wpt->notes) == 0)) str = NULL; - FWRITE_CSTR(str); /* instruction */ - - cnt = 0; - if (wpt->url) cnt++; - for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) - if (url_next->url) cnt++; - FWRITE_i32(cnt); - if (wpt->url) FWRITE_CSTR(wpt->url); - for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) - if (url_next->url) FWRITE_CSTR(url_next->url); - } - - FWRITE_i16(GMSD_GET(category, gdb_category)); - FWRITE_DBL(WAYPT_GET(wpt, temperature, 0), 0); - FWRITE_TIME(wpt->creation_time); - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_3) { - const char *str = GMSD_GET(phone_nr, ""); - if (*str) { - FWRITE_i32(1); - FWRITE_CSTR(str); - FWRITE_CSTR(""); - } - else { - FWRITE_i32(0); - } - FWRITE_CSTR(GMSD_GET(country, "")); - FWRITE_CSTR(GMSD_GET(postal_code, "")); - } + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_LATLON(wpt->latitude); /* latitude */ + FWRITE_LATLON(wpt->longitude); /* longitude */ + FWRITE_DBL(wpt->altitude, unknown_alt); /* altitude */ + if (wpt->notes) { + FWRITE_CSTR(wpt->notes); + } else { + FWRITE_CSTR(wpt->description); + } + FWRITE_DBL(WAYPT_GET(wpt, proximity, unknown_alt), unknown_alt); /* proximity */ + FWRITE_i32(display); /* display */ + FWRITE_i32(0); /* color */ + FWRITE_i32(icon); /* icon */ + FWRITE_CSTR(GMSD_GET(city, "")); /* city */ + FWRITE_CSTR(GMSD_GET(state, "")); /* state */ + FWRITE_CSTR(GMSD_GET(facility, "")); /* facility */ + FWRITE_C(0); /* unknown */ + FWRITE_DBL(WAYPT_GET(wpt, depth, unknown_alt), unknown_alt); /* depth */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + char *descr; + + FWRITE(zbuf, 3); + FWRITE(zbuf, 4); + descr = (wpt_class < gt_waypt_class_map_point) ? + wpt->url : wpt->description; + if ((descr != NULL) && (wpt_class >= gt_waypt_class_map_point) && \ + (strcmp(descr, wpt->shortname) == 0)) { + descr = NULL; + } + FWRITE_CSTR(descr); + } else { /* if (gdb_ver > GDB_VER_3) */ + int cnt; + url_link *url_next; + const char *str; + + if (wpt_class < gt_waypt_class_map_point) { /* street address */ + str = GMSD_GET(addr, ""); + } else { + str = ""; + } + FWRITE_CSTR(str); + FWRITE(zbuf, 5); /* instruction dependend */ + + /* GBD doesn't have a native description field */ + /* here we misuse the instruction field */ + + str = wpt->description; + if (str && (strcmp(str, wpt->shortname) == 0)) { + str = NULL; + } + if (str && wpt->notes && (strcmp(str, wpt->notes) == 0)) { + str = NULL; + } + FWRITE_CSTR(str); /* instruction */ + + cnt = 0; + if (wpt->url) { + cnt++; + } + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) { + cnt++; + } + FWRITE_i32(cnt); + if (wpt->url) { + FWRITE_CSTR(wpt->url); + } + for (url_next = wpt->url_next; (url_next); url_next = url_next->url_next) + if (url_next->url) { + FWRITE_CSTR(url_next->url); + } + } + + FWRITE_i16(GMSD_GET(category, gdb_category)); + FWRITE_DBL(WAYPT_GET(wpt, temperature, 0), 0); + FWRITE_TIME(wpt->creation_time); + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_3) { + const char *str = GMSD_GET(phone_nr, ""); + if (*str) { + FWRITE_i32(1); + FWRITE_CSTR(str); + FWRITE_CSTR(""); + } else { + FWRITE_i32(0); + } + FWRITE_CSTR(GMSD_GET(country, "")); + FWRITE_CSTR(GMSD_GET(postal_code, "")); + } } static void route_compute_bounds(const route_head *rte, bounds *bounds) { - queue *elem, *tmp; - waypt_init_bounds(bounds); - QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - gdb_check_waypt(wpt); - waypt_add_to_bounds(bounds, wpt); - } + queue *elem, *tmp; + waypt_init_bounds(bounds); + QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + gdb_check_waypt(wpt); + waypt_add_to_bounds(bounds, wpt); + } } static void route_write_bounds(bounds *bounds) { - if (waypt_bounds_valid(bounds)) { - FWRITE_C(0); - FWRITE_LATLON(bounds->max_lat); - FWRITE_LATLON(bounds->max_lon); - FWRITE_DBL(bounds->max_alt, unknown_alt); - FWRITE_LATLON(bounds->min_lat); - FWRITE_LATLON(bounds->min_lon); - FWRITE_DBL(bounds->min_alt, -(unknown_alt)); - } - else FWRITE_C(1); + if (waypt_bounds_valid(bounds)) { + FWRITE_C(0); + FWRITE_LATLON(bounds->max_lat); + FWRITE_LATLON(bounds->max_lon); + FWRITE_DBL(bounds->max_alt, unknown_alt); + FWRITE_LATLON(bounds->min_lat); + FWRITE_LATLON(bounds->min_lon); + FWRITE_DBL(bounds->min_alt, -(unknown_alt)); + } else { + FWRITE_C(1); + } } static void write_route(const route_head *rte, const char *rte_name) { - bounds bounds; - int points, index; - queue *elem, *tmp; - char zbuf[32], ffbuf[32]; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xFF, sizeof(ffbuf)); - - FWRITE_CSTR(rte_name); - FWRITE_C(0); /* display/autoname - 1 byte */ - - route_compute_bounds(rte, &bounds); - route_write_bounds(&bounds); - - points = ELEMENTS(rte); - FWRITE_i32(points); - - index = 0; - - QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { - - waypoint *wpt = (waypoint *)elem; - waypoint *next = (waypoint *)tmp; - waypoint *test; - garmin_fs_t *gmsd = NULL; - int wpt_class; - - index++; - rtept_ct++; /* increase informational number of written route points */ - - if (index == 1) gdb_check_waypt(wpt); - if (index < points) gdb_check_waypt(next); - - test = gdb_find_wayptq(&wayptq_out, wpt, 1); - if (test != NULL) wpt = test; - else { - fatal(MYNAME ": Sorry, that should never happen!!!\n"); - } - - gmsd = GMSD_FIND(wpt); - - /* extra_data may contain a modified shortname */ - FWRITE_CSTR((wpt->extra_data) ? (char *)wpt->extra_data : wpt->shortname); - - wpt_class = wpt->microseconds; /* trick */ - - FWRITE_i32(wpt_class); /* waypoint class */ - FWRITE_CSTR(GMSD_GET(cc, "")); /* country */ + bounds bounds; + int points, index; + queue *elem, *tmp; + char zbuf[32], ffbuf[32]; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xFF, sizeof(ffbuf)); + + FWRITE_CSTR(rte_name); + FWRITE_C(0); /* display/autoname - 1 byte */ + + route_compute_bounds(rte, &bounds); + route_write_bounds(&bounds); + + points = ELEMENTS(rte); + FWRITE_i32(points); + + index = 0; + + QUEUE_FOR_EACH((queue *)&rte->waypoint_list, elem, tmp) { + + waypoint *wpt = (waypoint *)elem; + waypoint *next = (waypoint *)tmp; + waypoint *test; + garmin_fs_t *gmsd = NULL; + int wpt_class; + + index++; + rtept_ct++; /* increase informational number of written route points */ + + if (index == 1) { + gdb_check_waypt(wpt); + } + if (index < points) { + gdb_check_waypt(next); + } + + test = gdb_find_wayptq(&wayptq_out, wpt, 1); + if (test != NULL) { + wpt = test; + } else { + fatal(MYNAME ": Sorry, that should never happen!!!\n"); + } + + gmsd = GMSD_FIND(wpt); + + /* extra_data may contain a modified shortname */ + FWRITE_CSTR((wpt->extra_data) ? (char *)wpt->extra_data : wpt->shortname); + + wpt_class = wpt->microseconds; /* trick */ + + FWRITE_i32(wpt_class); /* waypoint class */ + FWRITE_CSTR(GMSD_GET(cc, "")); /* country */ #ifdef GMSD_EXPERIMENTAL - if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) - FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); - else -#endif - { - FWRITE(zbuf, 4); /* subclass part 1 */ - FWRITE(ffbuf, 12); /* subclass part 2 */ - FWRITE(zbuf, 2); /* subclass part 3 */ - FWRITE(ffbuf, 4); /* unknown */ - } - - FWRITE_C(0); /* unknown value or string */ - FWRITE_C(3); /* unknown 18 bytes starting with 0x03 */ - FWRITE(zbuf, 3); - FWRITE(ffbuf, 4); - FWRITE(zbuf, 10); - - if (index == points) { - FWRITE_i32(0); /* no more steps */ - FWRITE_C(1); /* skip bounds */ - } - else /* if (index < points) */ { - FWRITE_i32(2); /* two interstep links */ - - FWRITE_LATLON(wpt->latitude); - FWRITE_LATLON(wpt->longitude); - FWRITE_DBL(wpt->altitude, unknown_alt); - FWRITE_LATLON(next->latitude); - FWRITE_LATLON(next->longitude); - FWRITE_DBL(next->altitude, unknown_alt); - - waypt_init_bounds(&bounds); - waypt_add_to_bounds(&bounds, wpt); - waypt_add_to_bounds(&bounds, next); - route_write_bounds(&bounds); - - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver >= GDB_VER_2) { - FWRITE(ffbuf, 8); - if (gdb_ver >= GDB_VER_3) - FWRITE(zbuf, 2); - } - } - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - FWRITE_CSTR(rte->rte_url); - } - else /* if (gdb_ver >= GDB_VER_3) */ { - FWRITE_CSTR_LIST(rte->rte_url); - /* "Magenta" (14) is MapSource default */ - FWRITE_i32( (rte->line_color.bbggrr < 0) ? 14 : gt_color_index_by_rgb(rte->line_color.bbggrr) ); - FWRITE_C(0); - FWRITE_CSTR(rte->rte_desc); - } + if (gmsd && gmsd->flags.subclass && (wpt_class >= gt_waypt_class_map_point)) { + FWRITE(gmsd->subclass, sizeof(gmsd->subclass)); + } else +#endif + { + FWRITE(zbuf, 4); /* subclass part 1 */ + FWRITE(ffbuf, 12); /* subclass part 2 */ + FWRITE(zbuf, 2); /* subclass part 3 */ + FWRITE(ffbuf, 4); /* unknown */ + } + + FWRITE_C(0); /* unknown value or string */ + FWRITE_C(3); /* unknown 18 bytes starting with 0x03 */ + FWRITE(zbuf, 3); + FWRITE(ffbuf, 4); + FWRITE(zbuf, 10); + + if (index == points) { + FWRITE_i32(0); /* no more steps */ + FWRITE_C(1); /* skip bounds */ + } else { /* if (index < points) */ + FWRITE_i32(2); /* two interstep links */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_LATLON(next->latitude); + FWRITE_LATLON(next->longitude); + FWRITE_DBL(next->altitude, unknown_alt); + + waypt_init_bounds(&bounds); + waypt_add_to_bounds(&bounds, wpt); + waypt_add_to_bounds(&bounds, next); + route_write_bounds(&bounds); + + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver >= GDB_VER_2) { + FWRITE(ffbuf, 8); + if (gdb_ver >= GDB_VER_3) { + FWRITE(zbuf, 2); + } + } + } + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(rte->rte_url); + } else { /* if (gdb_ver >= GDB_VER_3) */ + FWRITE_CSTR_LIST(rte->rte_url); + /* "Magenta" (14) is MapSource default */ + FWRITE_i32((rte->line_color.bbggrr < 0) ? 14 : gt_color_index_by_rgb(rte->line_color.bbggrr)); + FWRITE_C(0); + FWRITE_CSTR(rte->rte_desc); + } } static void write_track(const route_head *trk, const char *trk_name) { - queue *elem, *tmp; - int points = ELEMENTS(trk); - - FWRITE_CSTR(trk_name); - FWRITE_C(0); - /* "Unknown" (0) is MapSource default */ - FWRITE_i32(gt_color_index_by_rgb(trk->line_color.bbggrr)); - - FWRITE_i32(points); /* total number of waypoints in waypoint list */ - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) - { - double d; - waypoint *wpt = (waypoint *)elem; - - trkpt_ct++; /* increase informational number of written route points */ - - FWRITE_LATLON(wpt->latitude); - FWRITE_LATLON(wpt->longitude); - FWRITE_DBL(wpt->altitude, unknown_alt); - FWRITE_TIME(wpt->creation_time); - d = WAYPT_GET(wpt, depth, unknown_alt); - FWRITE_DBL(d, unknown_alt); - d = WAYPT_GET(wpt, temperature, -99999); - FWRITE_DBL(d, -99999); - } - - /* finalize track */ - - /* VERSION DEPENDENT CODE */ - if (gdb_ver <= GDB_VER_2) { - FWRITE_CSTR(trk->rte_url); - } - else /* if (gdb_ver >= GDB_VER_3 */ { - FWRITE_CSTR_LIST(trk->rte_url); - } + queue *elem, *tmp; + int points = ELEMENTS(trk); + + FWRITE_CSTR(trk_name); + FWRITE_C(0); + /* "Unknown" (0) is MapSource default */ + FWRITE_i32(gt_color_index_by_rgb(trk->line_color.bbggrr)); + + FWRITE_i32(points); /* total number of waypoints in waypoint list */ + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + double d; + waypoint *wpt = (waypoint *)elem; + + trkpt_ct++; /* increase informational number of written route points */ + + FWRITE_LATLON(wpt->latitude); + FWRITE_LATLON(wpt->longitude); + FWRITE_DBL(wpt->altitude, unknown_alt); + FWRITE_TIME(wpt->creation_time); + d = WAYPT_GET(wpt, depth, unknown_alt); + FWRITE_DBL(d, unknown_alt); + d = WAYPT_GET(wpt, temperature, -99999); + FWRITE_DBL(d, -99999); + } + + /* finalize track */ + + /* VERSION DEPENDENT CODE */ + if (gdb_ver <= GDB_VER_2) { + FWRITE_CSTR(trk->rte_url); + } else { /* if (gdb_ver >= GDB_VER_3 */ + FWRITE_CSTR_LIST(trk->rte_url); + } } /*-----------------------------------------------------------------------------*/ @@ -1489,17 +1580,17 @@ write_track(const route_head *trk, const char *trk_name) static void finalize_item(gbfile *origin, const char identifier) { - int len = gbftell(fout); - - fout = origin; - gbfseek(ftmp, 0, SEEK_SET); - - FWRITE_i32(len); - FWRITE_C(identifier); - gbfcopyfrom(fout, ftmp, len); - - gbfseek(ftmp, 0, SEEK_SET); /* Truncate memory stream */ - gbfwrite(NULL, 0, 0, ftmp); + int len = gbftell(fout); + + fout = origin; + gbfseek(ftmp, 0, SEEK_SET); + + FWRITE_i32(len); + FWRITE_C(identifier); + gbfcopyfrom(fout, ftmp, len); + + gbfseek(ftmp, 0, SEEK_SET); /* Truncate memory stream */ + gbfwrite(NULL, 0, 0, ftmp); } /*-----------------------------------------------------------------------------*/ @@ -1507,144 +1598,163 @@ finalize_item(gbfile *origin, const char identifier) static char str_not_equal(const char *s1, const char *s2) { - if (s1) { - if (!s2) return 1; - if (strcmp(s1, s2) != 0) return 1; - else return 0; - } - else if (s2) return 1; - else return 0; + if (s1) { + if (!s2) { + return 1; + } + if (strcmp(s1, s2) != 0) { + return 1; + } else { + return 0; + } + } else if (s2) { + return 1; + } else { + return 0; + } } static void write_waypoint_cb(const waypoint *refpt) { - garmin_fs_t *gmsd; - waypoint *test; - gbfile *fsave; - - /* do this when backup always happens in main */ - - rtrim(((waypoint *)refpt)->shortname); - test = gdb_find_wayptq(&wayptq_out, refpt, 1); - - if ((test != NULL) && (route_flag == 0)) { - if ((str_not_equal(test->notes, refpt->notes)) || - (str_not_equal(test->url, refpt->url))) - test = NULL; - } - - if (test == NULL) { - int icon, display, wpt_class; - char *name; - waypoint *wpt = waypt_dupe(refpt); - - gdb_check_waypt(wpt); - ENQUEUE_TAIL(&wayptq_out, &wpt->Q); - - fsave = fout; - fout = ftmp; - - /* prepare the waypoint */ - gmsd = GMSD_FIND(wpt); - - wpt_class = GMSD_GET(wpt_class, -1); - if (wpt_class == -1) - wpt_class = (route_flag) ? GDB_DEF_HIDDEN_CLASS : GDB_DEF_CLASS; - wpt->microseconds = wpt_class; /* trick, we need this for the route(s) */ - - icon = GMSD_GET(icon, -1); - if (icon < 0) { - if (wpt->icon_descr) - icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); - else - icon = GDB_DEF_ICON; - } - - switch(GMSD_GET(display, -1)) { /* display */ - case -1: - if (wpt_class < 8) - display = gt_gdb_display_mode_symbol_and_name; - else - display = gt_gdb_display_mode_symbol; - break; - case gt_display_mode_symbol: - display = gt_gdb_display_mode_symbol; - break; - case gt_display_mode_symbol_and_comment: - display = gt_gdb_display_mode_symbol_and_comment; - break; - default: - display = gt_gdb_display_mode_symbol_and_name; - break; - } - - name = wpt->shortname; - - if (global_opts.synthesize_shortnames || (*name == '\0')) { - name = wpt->notes; - if (!name) name = wpt->description; - if (!name) name = wpt->shortname; - } - - name = mkshort(short_h, name); - wpt->extra_data = (void *)name; - write_waypoint(wpt, name, gmsd, icon, display); - - finalize_item(fsave, 'W'); - } + garmin_fs_t *gmsd; + waypoint *test; + gbfile *fsave; + + /* do this when backup always happens in main */ + + rtrim(((waypoint *)refpt)->shortname); + test = gdb_find_wayptq(&wayptq_out, refpt, 1); + + if ((test != NULL) && (route_flag == 0)) { + if ((str_not_equal(test->notes, refpt->notes)) || + (str_not_equal(test->url, refpt->url))) { + test = NULL; + } + } + + if (test == NULL) { + int icon, display, wpt_class; + char *name; + waypoint *wpt = waypt_dupe(refpt); + + gdb_check_waypt(wpt); + ENQUEUE_TAIL(&wayptq_out, &wpt->Q); + + fsave = fout; + fout = ftmp; + + /* prepare the waypoint */ + gmsd = GMSD_FIND(wpt); + + wpt_class = GMSD_GET(wpt_class, -1); + if (wpt_class == -1) { + wpt_class = (route_flag) ? GDB_DEF_HIDDEN_CLASS : GDB_DEF_CLASS; + } + wpt->microseconds = wpt_class; /* trick, we need this for the route(s) */ + + icon = GMSD_GET(icon, -1); + if (icon < 0) { + if (wpt->icon_descr) { + icon = gt_find_icon_number_from_desc(wpt->icon_descr, GDB); + } else { + icon = GDB_DEF_ICON; + } + } + + switch (GMSD_GET(display, -1)) { /* display */ + case -1: + if (wpt_class < 8) { + display = gt_gdb_display_mode_symbol_and_name; + } else { + display = gt_gdb_display_mode_symbol; + } + break; + case gt_display_mode_symbol: + display = gt_gdb_display_mode_symbol; + break; + case gt_display_mode_symbol_and_comment: + display = gt_gdb_display_mode_symbol_and_comment; + break; + default: + display = gt_gdb_display_mode_symbol_and_name; + break; + } + + name = wpt->shortname; + + if (global_opts.synthesize_shortnames || (*name == '\0')) { + name = wpt->notes; + if (!name) { + name = wpt->description; + } + if (!name) { + name = wpt->shortname; + } + } + + name = mkshort(short_h, name); + wpt->extra_data = (void *)name; + write_waypoint(wpt, name, gmsd, icon, display); + + finalize_item(fsave, 'W'); + } } static void write_route_cb(const route_head *rte) { - gbfile *fsave; - char *name; - char buf[32]; - - if (ELEMENTS(rte) <= 0) return; - - if (rte->rte_name == NULL) { - snprintf(buf, sizeof(buf), "Route%04d", rte->rte_num); - name = mkshort(short_h, buf); - } - else - name = mkshort(short_h, rte->rte_name); - - rte_ct++; /* increase informational number of written routes */ - - fsave = fout; - fout = ftmp; - write_route(rte, name); - finalize_item(fsave, 'R'); - - xfree(name); + gbfile *fsave; + char *name; + char buf[32]; + + if (ELEMENTS(rte) <= 0) { + return; + } + + if (rte->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Route%04d", rte->rte_num); + name = mkshort(short_h, buf); + } else { + name = mkshort(short_h, rte->rte_name); + } + + rte_ct++; /* increase informational number of written routes */ + + fsave = fout; + fout = ftmp; + write_route(rte, name); + finalize_item(fsave, 'R'); + + xfree(name); } static void write_track_cb(const route_head *trk) { - gbfile *fsave; - char *name; - char buf[32]; - - if (ELEMENTS(trk) <= 0) return; - - if (trk->rte_name == NULL) { - snprintf(buf, sizeof(buf), "Track%04d", trk->rte_num); - name = mkshort(short_h, buf); - } - else - name = mkshort(short_h, trk->rte_name); - - trk_ct++; /* increase informational number of written tracks */ - - fsave = fout; - fout = ftmp; - write_track(trk, name); - finalize_item(fsave, 'T'); - - xfree(name); + gbfile *fsave; + char *name; + char buf[32]; + + if (ELEMENTS(trk) <= 0) { + return; + } + + if (trk->rte_name == NULL) { + snprintf(buf, sizeof(buf), "Track%04d", trk->rte_num); + name = mkshort(short_h, buf); + } else { + name = mkshort(short_h, trk->rte_name); + } + + trk_ct++; /* increase informational number of written tracks */ + + fsave = fout; + fout = ftmp; + write_track(trk, name); + finalize_item(fsave, 'T'); + + xfree(name); } /*-----------------------------------------------------------------------------*/ @@ -1652,67 +1762,70 @@ write_track_cb(const route_head *trk) static void gdb_wr_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - ftmp = gbfopen_le(NULL, "wb", MYNAME); - - gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0; - gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0; - - if (gdb_category) { - is_fatal((gdb_category < 1) || (gdb_category > 16), - MYNAME ": cat must be between 1 and 16!"); - gdb_category = 1 << (gdb_category - 1); - } - - if (gdb_opt_bitcategory) { - gdb_category = strtol(gdb_opt_bitcategory, NULL, 0); - } - - if (gdb_ver >= GDB_VER_UTF8) - cet_convert_init(CET_CHARSET_UTF8, 1); - - QUEUE_INIT(&wayptq_out); - short_h = NULL; - - waypt_ct = 0; - waypth_ct = 0; - rtept_ct = 0; - trkpt_ct = 0; - rte_ct = 0; - trk_ct = 0; + fout = gbfopen_le(fname, "wb", MYNAME); + ftmp = gbfopen_le(NULL, "wb", MYNAME); + + gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0; + gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0; + + if (gdb_category) { + is_fatal((gdb_category < 1) || (gdb_category > 16), + MYNAME ": cat must be between 1 and 16!"); + gdb_category = 1 << (gdb_category - 1); + } + + if (gdb_opt_bitcategory) { + gdb_category = strtol(gdb_opt_bitcategory, NULL, 0); + } + + if (gdb_ver >= GDB_VER_UTF8) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + QUEUE_INIT(&wayptq_out); + short_h = NULL; + + waypt_ct = 0; + waypth_ct = 0; + rtept_ct = 0; + trkpt_ct = 0; + rte_ct = 0; + trk_ct = 0; } static void gdb_wr_deinit(void) { - disp_summary(fout); - gdb_flush_waypt_queue(&wayptq_out); - mkshort_del_handle(&short_h); - gbfclose(fout); - gbfclose(ftmp); + disp_summary(fout); + gdb_flush_waypt_queue(&wayptq_out); + mkshort_del_handle(&short_h); + gbfclose(fout); + gbfclose(ftmp); } static void write_data(void) { - if (gdb_opt_ver) gdb_ver = atoi(gdb_opt_ver); - write_header(); - - reset_short_handle("WPT"); - route_flag = 0; - waypt_disp_all(write_waypoint_cb); - route_flag = 1; - route_disp_all(NULL, NULL, write_waypoint_cb); - - reset_short_handle("Route"); - route_disp_all(write_route_cb, NULL, NULL); - - reset_short_handle("Track"); - track_disp_all(write_track_cb, NULL, NULL); - - FWRITE_i32(2); /* finalize gdb with empty map segment */ - FWRITE_CSTR("V"); - FWRITE_C(1); + if (gdb_opt_ver) { + gdb_ver = atoi(gdb_opt_ver); + } + write_header(); + + reset_short_handle("WPT"); + route_flag = 0; + waypt_disp_all(write_waypoint_cb); + route_flag = 1; + route_disp_all(NULL, NULL, write_waypoint_cb); + + reset_short_handle("Route"); + route_disp_all(write_route_cb, NULL, NULL); + + reset_short_handle("Track"); + track_disp_all(write_track_cb, NULL, NULL); + + FWRITE_i32(2); /* finalize gdb with empty map segment */ + FWRITE_CSTR("V"); + FWRITE_C(1); } /*******************************************************************************/ @@ -1724,37 +1837,47 @@ write_data(void) #define GDB_OPT_ROADBOOK "roadbook" static arglist_t gdb_args[] = { - {GDB_OPT_CATEGORY, &gdb_opt_category, - "Default category on output (1..16)", - NULL, ARGTYPE_INT, "1", "16"}, - {GDB_OPT_BITCATEGORY, &gdb_opt_bitcategory, "Bitmap of categories", - NULL, ARGTYPE_INT, "1", "65535"}, - {GDB_OPT_VER, &gdb_opt_ver, - "Version of gdb file to generate (1..3)", - "2", ARGTYPE_INT, "1", "3"}, - {GDB_OPT_VIA, &gdb_opt_via, - "Drop route points that do not have an equivalent waypoint (hidden points)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {GDB_OPT_ROADBOOK, &gdb_opt_roadbook, - "Include major turn points (with description) from calculated route", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - - ARG_TERMINATOR + { + GDB_OPT_CATEGORY, &gdb_opt_category, + "Default category on output (1..16)", + NULL, ARGTYPE_INT, "1", "16" + }, + { + GDB_OPT_BITCATEGORY, &gdb_opt_bitcategory, "Bitmap of categories", + NULL, ARGTYPE_INT, "1", "65535" + }, + { + GDB_OPT_VER, &gdb_opt_ver, + "Version of gdb file to generate (1..3)", + "2", ARGTYPE_INT, "1", "3" + }, + { + GDB_OPT_VIA, &gdb_opt_via, + "Drop route points that do not have an equivalent waypoint (hidden points)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + GDB_OPT_ROADBOOK, &gdb_opt_roadbook, + "Include major turn points (with description) from calculated route", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + + ARG_TERMINATOR }; ff_vecs_t gdb_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gdb_rd_init, - gdb_wr_init, - gdb_rd_deinit, - gdb_wr_deinit, - read_data, - write_data, - NULL, - gdb_args, - CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ - /* because of utf8 strings since GDB V3 */ + ff_type_file, + FF_CAP_RW_ALL, + gdb_rd_init, + gdb_wr_init, + gdb_rd_deinit, + gdb_wr_deinit, + read_data, + write_data, + NULL, + gdb_args, + CET_CHARSET_MS_ANSI, 0 /* O.K.: changed to NON-FIXED */ + /* because of utf8 strings since GDB V3 */ }; /*******************************************************************************/ diff --git a/gpsbabel/geo.c b/gpsbabel/geo.c index 0250dad37..d380d6406 100644 --- a/gpsbabel/geo.c +++ b/gpsbabel/geo.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -28,9 +28,9 @@ static gbfile *ofd; static arglist_t geo_args[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + {"nuke_placer", &nuke_placer, "Omit Placer name", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "geo" @@ -40,7 +40,7 @@ arglist_t geo_args[] = { static void geo_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GEO support because expat was not installed.\n"); } void @@ -54,232 +54,268 @@ static xg_callback wpt_link_s, wpt_link; static xg_callback wpt_name, wpt_name_s, wpt_type, wpt_coord; static xg_callback wpt_diff, wpt_terr, wpt_container; -static +static xg_tag_mapping loc_map[] = { - { wpt_s, cb_start, "/loc/waypoint" }, - { wpt_e, cb_end, "/loc/waypoint" }, - { wpt_name_s, cb_start, "/loc/waypoint/name" }, - { wpt_name, cb_cdata, "/loc/waypoint/name" }, - { wpt_type, cb_cdata, "/loc/waypoint/type" }, - { wpt_link_s, cb_start, "/loc/waypoint/link" }, - { wpt_link, cb_cdata, "/loc/waypoint/link" }, - { wpt_coord, cb_start, "/loc/waypoint/coord" }, - { wpt_diff, cb_cdata, "/loc/waypoint/difficulty" }, - { wpt_terr, cb_cdata, "/loc/waypoint/terrain" }, - { wpt_container,cb_cdata, "/loc/waypoint/container" }, - { NULL, 0, NULL } + { wpt_s, cb_start, "/loc/waypoint" }, + { wpt_e, cb_end, "/loc/waypoint" }, + { wpt_name_s, cb_start, "/loc/waypoint/name" }, + { wpt_name, cb_cdata, "/loc/waypoint/name" }, + { wpt_type, cb_cdata, "/loc/waypoint/type" }, + { wpt_link_s, cb_start, "/loc/waypoint/link" }, + { wpt_link, cb_cdata, "/loc/waypoint/link" }, + { wpt_coord, cb_start, "/loc/waypoint/coord" }, + { wpt_diff, cb_cdata, "/loc/waypoint/difficulty" }, + { wpt_terr, cb_cdata, "/loc/waypoint/terrain" }, + { wpt_container,cb_cdata, "/loc/waypoint/container" }, + { NULL, 0, NULL } }; -void wpt_s(const char *args, const char **unused) -{ - wpt_tmp = waypt_new(); - /* - * 'geo' doesn't really have an 'unknown' and doesn't have any - * concept of alt. Unfortunately, we have many reference files - * that have leaked the 'unknown_alt' value into them, so we paper - * over that here. - */ - wpt_tmp->altitude = 0; +void wpt_s(const char *args, const char **unused) +{ + wpt_tmp = waypt_new(); + /* + * 'geo' doesn't really have an 'unknown' and doesn't have any + * concept of alt. Unfortunately, we have many reference files + * that have leaked the 'unknown_alt' value into them, so we paper + * over that here. + */ + wpt_tmp->altitude = 0; } void wpt_e(const char *args, const char **unused) { - waypt_add(wpt_tmp); + waypt_add(wpt_tmp); } void wpt_name_s(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "id")) { - wpt_tmp->shortname = xstrdup(avp[1]); - } - avp+=2; - } + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "id")) { + wpt_tmp->shortname = xstrdup(avp[1]); + } + avp+=2; + } } void wpt_name(const char *args, const char **unused) { - char *s; - if (!args) return; - - wpt_tmp->description = xstrappend(wpt_tmp->description,args); - s = xstrrstr(wpt_tmp->description, " by "); - if (s) { - waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4); - - if (nuke_placer) { - *s = '\0'; - } - } + char *s; + if (!args) { + return; + } + + wpt_tmp->description = xstrappend(wpt_tmp->description,args); + s = xstrrstr(wpt_tmp->description, " by "); + if (s) { + waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(s + 4); + + if (nuke_placer) { + *s = '\0'; + } + } } void wpt_link_s(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "text")) { - wpt_tmp->url_link_text = xstrdup(avp[1]); - } - avp+=2; - } + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "text")) { + wpt_tmp->url_link_text = xstrdup(avp[1]); + } + avp+=2; + } } void wpt_link(const char *args, const char **attrv) { - wpt_tmp->url = xstrdup(args); + wpt_tmp->url = xstrdup(args); } void wpt_type(const char *args, const char **unused) { - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(args); } void wpt_coord(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } } void wpt_container(const char *args, const char **unused) { - int v; - - if (!args) return; - switch ( atoi(args) ) - { - case 1: v = gc_unknown; break; - case 2: v = gc_micro; break; - case 3: v = gc_regular; break; - case 4: v = gc_large; break; - case 5: v = gc_virtual;; break; - case 6: v = gc_other; break; - case 8: v = gc_small; break; - default: v = gc_unknown; break; - } - waypt_alloc_gc_data(wpt_tmp)->container = v; + int v; + + if (!args) { + return; + } + switch (atoi(args)) { + case 1: + v = gc_unknown; + break; + case 2: + v = gc_micro; + break; + case 3: + v = gc_regular; + break; + case 4: + v = gc_large; + break; + case 5: + v = gc_virtual;; + break; + case 6: + v = gc_other; + break; + case 8: + v = gc_small; + break; + default: + v = gc_unknown; + break; + } + waypt_alloc_gc_data(wpt_tmp)->container = v; } void wpt_diff(const char *args, const char **unused) { - if (!args) return; - waypt_alloc_gc_data(wpt_tmp)->diff = atof(args) * 10; + if (!args) { + return; + } + waypt_alloc_gc_data(wpt_tmp)->diff = atof(args) * 10; } void wpt_terr(const char *args, const char **unused) { - if (!args) return; - waypt_alloc_gc_data(wpt_tmp)->terr = atof(args) * 10; + if (!args) { + return; + } + waypt_alloc_gc_data(wpt_tmp)->terr = atof(args) * 10; } static void geo_rd_init(const char *fname) { - xml_init(fname, loc_map, NULL); + xml_init(fname, loc_map, NULL); } static void geo_read(void) { - xml_read(); + xml_read(); } #endif static void geo_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void geo_wr_init(const char *fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void geo_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void geo_waypt_pr(const waypoint *waypointp) { - char *tmp; - - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "", waypointp->shortname); - gbfprintf(ofd, "", waypointp->description); - gbfprintf(ofd, "\n"); - - gbfprintf(ofd, "", - waypointp->latitude, - waypointp->longitude); - gbfprintf(ofd, "\n"); - - if (waypointp->icon_descr) { - gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); - } - if (waypointp->url) { - tmp = xml_entitize(waypointp->url); - gbfprintf(ofd, "%s\n", - tmp); - xfree(tmp); - } - if (waypointp->gc_data && waypointp->gc_data->diff) - { - int v; - - gbfprintf(ofd, "%.1lf\n", - waypointp->gc_data->diff / 10.0); - gbfprintf(ofd, "%.1lf\n", - waypointp->gc_data->terr / 10.0); - switch (waypointp->gc_data->container) - { - case gc_unknown: v = 1; break; - case gc_micro: v = 2; break; - case gc_regular: v = 3; break; - case gc_large: v = 4; break; - case gc_virtual: v = 5; break; - case gc_other: v = 6; break; - case gc_small: v = 8; break; - default: v = 1; break; - } - gbfprintf(ofd, "%d\n", v); - } - gbfprintf(ofd, "\n"); + char *tmp; + + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "", waypointp->shortname); + gbfprintf(ofd, "", waypointp->description); + gbfprintf(ofd, "\n"); + + gbfprintf(ofd, "", + waypointp->latitude, + waypointp->longitude); + gbfprintf(ofd, "\n"); + + if (waypointp->icon_descr) { + gbfprintf(ofd, "%s\n", deficon ? deficon : waypointp->icon_descr); + } + if (waypointp->url) { + tmp = xml_entitize(waypointp->url); + gbfprintf(ofd, "%s\n", + tmp); + xfree(tmp); + } + if (waypointp->gc_data && waypointp->gc_data->diff) { + int v; + + gbfprintf(ofd, "%.1lf\n", + waypointp->gc_data->diff / 10.0); + gbfprintf(ofd, "%.1lf\n", + waypointp->gc_data->terr / 10.0); + switch (waypointp->gc_data->container) { + case gc_unknown: + v = 1; + break; + case gc_micro: + v = 2; + break; + case gc_regular: + v = 3; + break; + case gc_large: + v = 4; + break; + case gc_virtual: + v = 5; + break; + case gc_other: + v = 6; + break; + case gc_small: + v = 8; + break; + default: + v = 1; + break; + } + gbfprintf(ofd, "%d\n", v); + } + gbfprintf(ofd, "\n"); } static void geo_write(void) { - gbfprintf(ofd, "\n"); - waypt_disp_all(geo_waypt_pr); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + waypt_disp_all(geo_waypt_pr); + gbfprintf(ofd, "\n"); } ff_vecs_t geo_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, - geo_rd_init, - geo_wr_init, - geo_rd_deinit, - geo_wr_deinit, - geo_read, - geo_write, - NULL, - geo_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, + geo_rd_init, + geo_wr_init, + geo_rd_deinit, + geo_wr_deinit, + geo_read, + geo_write, + NULL, + geo_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/geoniche.c b/gpsbabel/geoniche.c index 65f84a9ea..ab0a5e3bb 100644 --- a/gpsbabel/geoniche.c +++ b/gpsbabel/geoniche.c @@ -47,11 +47,15 @@ static char *Arg_category = NULL; static arglist_t Args[] = { - {"dbname", &Arg_dbname, - "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"category", &Arg_category, - "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "dbname", &Arg_dbname, + "Database name (filename)", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "category", &Arg_category, + "Category name (Cache)", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define ARG_FREE(X) do { if (X) { xfree(X); X = NULL; } } while (0) @@ -65,507 +69,545 @@ static int GcOffset = 16 * 31 * 31 * 31 - 65536; static int gid2id(char *gid) { - char *p; - int i, val; - - if (strncmp(gid, "GC", 2) != 0) - return -1; - if (strlen(gid) != 6) - return -1; - gid += 2; - - if (strcmp(gid, "G000") < 0) - return strtol(gid, NULL, 16); - - for (val = i = 0; i < 4; ++i) - { - val *= 31; - p = strchr(GcSet, gid[i]); - if (!p) return -1; - val += p - GcSet; - } - return val - GcOffset; + char *p; + int i, val; + + if (strncmp(gid, "GC", 2) != 0) { + return -1; + } + if (strlen(gid) != 6) { + return -1; + } + gid += 2; + + if (strcmp(gid, "G000") < 0) { + return strtol(gid, NULL, 16); + } + + for (val = i = 0; i < 4; ++i) { + val *= 31; + p = strchr(GcSet, gid[i]); + if (!p) { + return -1; + } + val += p - GcSet; + } + return val - GcOffset; } static void id2gid(char gid[6+1], int id) { - gid[0] = 0; - if (id < 0) - return; - else if (id < 65536) - snprintf(gid, 6+1, "GC%04X", id); - else - { - int i; - - id += GcOffset; - gid[0] = 'G'; - gid[1] = 'C'; - for (i = 5; i >= 2; --i) { - gid[i] = GcSet[id%31]; - id /= 31; - } - gid[6] = 0; - if (id) - gid[0] = 0; - } + gid[0] = 0; + if (id < 0) { return; + } else if (id < 65536) { + snprintf(gid, 6+1, "GC%04X", id); + } else { + int i; + + id += GcOffset; + gid[0] = 'G'; + gid[1] = 'C'; + for (i = 5; i >= 2; --i) { + gid[i] = GcSet[id%31]; + id /= 31; + } + gid[6] = 0; + if (id) { + gid[0] = 0; + } + } + return; } static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - ARG_FREE(Arg_dbname); - ARG_FREE(Arg_category); + pdb_close(file_in); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - FilenameOut = fname; + file_out = pdb_create(fname, MYNAME); + FilenameOut = fname; } static void wr_deinit(void) { - pdb_close(file_out); - ARG_FREE(Arg_dbname); - ARG_FREE(Arg_category); + pdb_close(file_out); + ARG_FREE(Arg_dbname); + ARG_FREE(Arg_category); } static char * field(char **pp, int *lenp) { - int len = *lenp; - char *p = *pp; - char *dp, *dbuf; - int state = 0; - - if (len == 0 || *p == 0) - return NULL; - - dbuf = dp = xmalloc(len); - while (len) - { - char ch; - - ch = *p++; - --len; - if (ch == 0 || len == 0) - break; - switch (state) - { - case 0: - if (ch == '\\') - state = 1; - else if (ch == ',') - goto eof; - else - *dp++ = ch; - break; - default: - *dp++ = ch; - state = 0; - break; - } + int len = *lenp; + char *p = *pp; + char *dp, *dbuf; + int state = 0; + + if (len == 0 || *p == 0) { + return NULL; + } + + dbuf = dp = xmalloc(len); + while (len) { + char ch; + + ch = *p++; + --len; + if (ch == 0 || len == 0) { + break; } + switch (state) { + case 0: + if (ch == '\\') { + state = 1; + } else if (ch == ',') { + goto eof; + } else { + *dp++ = ch; + } + break; + default: + *dp++ = ch; + state = 0; + break; + } + } eof: - *dp++ = 0; - dbuf = xrealloc(dbuf, dp - dbuf); - /* fprintf(stderr, "<%.8s> dbuf=%x, len=%d\n", *pp, dbuf, len); */ - *pp = p; - *lenp = len; - return dbuf; + *dp++ = 0; + dbuf = xrealloc(dbuf, dp - dbuf); + /* fprintf(stderr, "<%.8s> dbuf=%x, len=%d\n", *pp, dbuf, len); */ + *pp = p; + *lenp = len; + return dbuf; } static void geoniche_read_asc(void) { - pdbrec_t *pdb_rec; - - /* Process record 0 */ - pdb_rec = file_in->rec_list; - if (strcmp((char *) pdb_rec->data, Rec0Magic)) - fatal(MYNAME ": Bad record 0, not a GeoNiche file.\n"); - pdb_rec = pdb_rec->next; - - /* Process the rest of the records */ - for (; pdb_rec; pdb_rec = pdb_rec->next) - { - waypoint *wpt; - char *vdata; - int vlen; - char *p; - - int id; - int route_id; - char *title; - char *category; - double lat, lon, alt; - char *datestr, *timestr; - int icon; - char *notes; - char gid[6+1]; - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - wpt = waypt_new(); - if (!wpt) - fatal(MYNAME ": Couldn't allocate waypoint.\n"); - vdata = (char *) pdb_rec->data; - vlen = pdb_rec->size; - - /* Field 1: Target */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); - if (strcmp(p, "Route") == 0) - fatal(MYNAME ": Route record type is not implemented.\n"); - if (strcmp(p, "Target")) - fatal(MYNAME ": Unknown record type '%s'.\n", p); - xfree(p); - - /* Field 2: Import ID number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); - id = atoi(p); - xfree(p); - - /* Field 3: Title */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); - title = p; - - /* Field 4: Route ID number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); - route_id = atoi(p); - xfree(p); - - /* Field 5: Category */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); - category = p; - - /* Field 6: Latitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); - lat = atof(p); - xfree(p); - - /* Field 7: Longitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); - lon = atof(p); - xfree(p); - - /* Field 8: Altitude */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); - alt = atof(p); - xfree(p); - - /* Field 9: Creation date */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); - datestr = p; - - /* Field 10: Creation time */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); - timestr = p; - - /* Field 11: Visited date */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); - xfree(p); - - /* Field 12: Visited time */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); - xfree(p); - - /* Field 13: Icon color (R G B) */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); - xfree(p); - - /* Field 14: icon number */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); - icon = atoi(p); - xfree(p); - - /* Field 15: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); - xfree(p); - - /* Field 16: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); - xfree(p); - - /* Field 17: unused */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); - xfree(p); - - /* Field 18: Notes */ - p = field(&vdata, &vlen); - if (!p) fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); - notes = p; - - sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); - if (tm.tm_year >= 1970) { - wpt->creation_time = mktime(&tm); - } - xfree(datestr); - xfree(timestr); - - id2gid(gid, id); - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; - wpt->icon_descr = category; - wpt->wpt_flags.icon_descr_is_dynamic = 1; - - if (gid[0]) - { - wpt->shortname = xstrdup(gid); - wpt->description = title; - wpt->notes = notes; - } - else - { - wpt->shortname = xstrdup(title); - wpt->description = title; - wpt->notes = notes; - } - - waypt_add(wpt); - } + pdbrec_t *pdb_rec; + + /* Process record 0 */ + pdb_rec = file_in->rec_list; + if (strcmp((char *) pdb_rec->data, Rec0Magic)) { + fatal(MYNAME ": Bad record 0, not a GeoNiche file.\n"); + } + pdb_rec = pdb_rec->next; + + /* Process the rest of the records */ + for (; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt; + char *vdata; + int vlen; + char *p; + + int id; + int route_id; + char *title; + char *category; + double lat, lon, alt; + char *datestr, *timestr; + int icon; + char *notes; + char gid[6+1]; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + if (!wpt) { + fatal(MYNAME ": Couldn't allocate waypoint.\n"); + } + vdata = (char *) pdb_rec->data; + vlen = pdb_rec->size; + + /* Field 1: Target */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 1 (target).\n"); + } + if (strcmp(p, "Route") == 0) { + fatal(MYNAME ": Route record type is not implemented.\n"); + } + if (strcmp(p, "Target")) { + fatal(MYNAME ": Unknown record type '%s'.\n", p); + } + xfree(p); + + /* Field 2: Import ID number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 2 (ID).\n"); + } + id = atoi(p); + xfree(p); + + /* Field 3: Title */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 3 (Title).\n"); + } + title = p; + + /* Field 4: Route ID number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 4 (Route ID).\n"); + } + route_id = atoi(p); + xfree(p); + + /* Field 5: Category */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 5 (Category).\n"); + } + category = p; + + /* Field 6: Latitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 6 (Latitude).\n"); + } + lat = atof(p); + xfree(p); + + /* Field 7: Longitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 7 (Longitude).\n"); + } + lon = atof(p); + xfree(p); + + /* Field 8: Altitude */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 8 (Altitude).\n"); + } + alt = atof(p); + xfree(p); + + /* Field 9: Creation date */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 9 (Creation date).\n"); + } + datestr = p; + + /* Field 10: Creation time */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 10 (Creation time).\n"); + } + timestr = p; + + /* Field 11: Visited date */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 11 (Visited date).\n"); + } + xfree(p); + + /* Field 12: Visited time */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 12 (Visited time).\n"); + } + xfree(p); + + /* Field 13: Icon color (R G B) */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 13 (Icon color).\n"); + } + xfree(p); + + /* Field 14: icon number */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 14 (Icon number).\n"); + } + icon = atoi(p); + xfree(p); + + /* Field 15: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 15 (unused1).\n"); + } + xfree(p); + + /* Field 16: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 16 (unused2).\n"); + } + xfree(p); + + /* Field 17: unused */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 17 (unused3).\n"); + } + xfree(p); + + /* Field 18: Notes */ + p = field(&vdata, &vlen); + if (!p) { + fatal(MYNAME ": Premature EOD processing field 18 (Notes).\n"); + } + notes = p; + + sscanf(datestr, "%d/%d/%d", &tm.tm_mon, &tm.tm_mday, &tm.tm_year); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + sscanf(timestr, "%d:%d:%d", &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + if (tm.tm_year >= 1970) { + wpt->creation_time = mktime(&tm); + } + xfree(datestr); + xfree(timestr); + + id2gid(gid, id); + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->icon_descr = category; + wpt->wpt_flags.icon_descr_is_dynamic = 1; + + if (gid[0]) { + wpt->shortname = xstrdup(gid); + wpt->description = title; + wpt->notes = notes; + } else { + wpt->shortname = xstrdup(title); + wpt->description = title; + wpt->notes = notes; + } + + waypt_add(wpt); + } } static const char *geoniche_icon_map[] = /* MPS */ { - /* 21 */ "Cross", - /* 22 */ "Cross (light)", - /* 23 */ "Cross (little)", - /* 24 */ "Cross (straight)", - /* 25 */ "Cross (light straight)", - /* 26 */ "Cross (little straight)", - /* 27 */ NULL, - /* 28 */ NULL, - /* 29 */ NULL, - /* 2A */ "Flag", - /* 2B */ "Car", /* 56 */ - /* 2C */ "Gas Station", /* 8 */ - /* 2D */ "Observation Point", - /* 2E */ "Scenic Area", /* 48 */ - /* 2F */ "City", - /* 30 */ "Mountains", - /* 31 */ "Park", /* 46 */ - /* 32 */ "Forest", /* 105 */ - /* 33 */ "Campground", /* 38 */ - /* 34 */ NULL, - /* 35 */ "Men", - /* 36 */ "Woman", - /* 37 */ "Hotel", /* 59 */ - /* 38 */ "Residence", /* 10 */ - /* 39 */ "Restaurant", /* 11 */ - /* 3A */ "Cafe", - /* 3B */ NULL, - /* 3C */ "Airport", /* 107 */ - /* 3D */ "Medical Facility", /* 43 */ - /* 3E */ "Ropeway", - /* 3F */ "Sailing Area", - /* 40 */ "Anchor", - /* 41 */ NULL, /* Half Anchor ??? */ - /* 42 */ "Fishing Area", /* 7 */ - /* 43 */ "Stop Sign", - /* 44 */ "Question Sign", - /* 45 */ NULL, - /* 46 */ NULL, - /* 47 */ "Euro Sign", - /* 48 */ "Bank", /* 6 */ - /* 49 */ NULL, - /* 4A */ "Left Arrow", - /* 4B */ "Right Arrow", - /* 4C */ "Traditional Cache", - /* 4D */ "Multi-Cache", /* 86 */ - /* 4E */ "Virtual Cache", /* 48 */ - /* 4F */ "Letterbox Cache", - /* 50 */ "Event Cache", /* 47 */ - /* 51 */ "Webcam Cache", /* 90 */ - /* 52 */ "Mystery or puzzle Cache", + /* 21 */ "Cross", + /* 22 */ "Cross (light)", + /* 23 */ "Cross (little)", + /* 24 */ "Cross (straight)", + /* 25 */ "Cross (light straight)", + /* 26 */ "Cross (little straight)", + /* 27 */ NULL, + /* 28 */ NULL, + /* 29 */ NULL, + /* 2A */ "Flag", + /* 2B */ "Car", /* 56 */ + /* 2C */ "Gas Station", /* 8 */ + /* 2D */ "Observation Point", + /* 2E */ "Scenic Area", /* 48 */ + /* 2F */ "City", + /* 30 */ "Mountains", + /* 31 */ "Park", /* 46 */ + /* 32 */ "Forest", /* 105 */ + /* 33 */ "Campground", /* 38 */ + /* 34 */ NULL, + /* 35 */ "Men", + /* 36 */ "Woman", + /* 37 */ "Hotel", /* 59 */ + /* 38 */ "Residence", /* 10 */ + /* 39 */ "Restaurant", /* 11 */ + /* 3A */ "Cafe", + /* 3B */ NULL, + /* 3C */ "Airport", /* 107 */ + /* 3D */ "Medical Facility", /* 43 */ + /* 3E */ "Ropeway", + /* 3F */ "Sailing Area", + /* 40 */ "Anchor", + /* 41 */ NULL, /* Half Anchor ??? */ + /* 42 */ "Fishing Area", /* 7 */ + /* 43 */ "Stop Sign", + /* 44 */ "Question Sign", + /* 45 */ NULL, + /* 46 */ NULL, + /* 47 */ "Euro Sign", + /* 48 */ "Bank", /* 6 */ + /* 49 */ NULL, + /* 4A */ "Left Arrow", + /* 4B */ "Right Arrow", + /* 4C */ "Traditional Cache", + /* 4D */ "Multi-Cache", /* 86 */ + /* 4E */ "Virtual Cache", /* 48 */ + /* 4F */ "Letterbox Cache", + /* 50 */ "Event Cache", /* 47 */ + /* 51 */ "Webcam Cache", /* 90 */ + /* 52 */ "Mystery or puzzle Cache", }; static const char * geoniche_icon_to_descr(const int no) { - const char *result = NULL; + const char *result = NULL; - if (no >= 0x21) - { - int i = no - 0x21; - if (i <= 49) - { - result = geoniche_icon_map[i]; - } - } - if (result != NULL) - { - result = xstrdup(result); + if (no >= 0x21) { + int i = no - 0x21; + if (i <= 49) { + result = geoniche_icon_map[i]; } - return result; + } + if (result != NULL) { + result = xstrdup(result); + } + return result; } static void geoniche_read_bin(void) { - pdbrec_t *pdb_rec; - - /* Process records */ - - for (pdb_rec = file_in->rec_list; pdb_rec != NULL; pdb_rec = pdb_rec->next) - { - char *vdata = (char *) pdb_rec->data; - struct tm created, visited; - int icon_nr, selected; - int latdeg, londeg; - double lat, lon, altitude; - waypoint *waypt; - - memset(&visited, 0, sizeof(visited)); - memset(&created, 0, sizeof(created)); - - latdeg = be_read16(vdata + 0); - lat = be_read32(vdata + 2); - londeg = be_read16(vdata + 6); - lon = be_read32(vdata + 8); - altitude = (float) be_read32(vdata + 12); - selected = vdata[16]; - created.tm_min = be_read16(vdata + 20); - created.tm_hour = be_read16(vdata + 22); - created.tm_mday = be_read16(vdata + 24); - created.tm_mon = be_read16(vdata + 26); - created.tm_year = be_read16(vdata + 28); - visited.tm_min = be_read16(vdata + 34); - visited.tm_hour = be_read16(vdata + 36); - visited.tm_mday = be_read16(vdata + 38); - visited.tm_mon = be_read16(vdata + 40); - visited.tm_year = be_read16(vdata + 42); + pdbrec_t *pdb_rec; + + /* Process records */ + + for (pdb_rec = file_in->rec_list; pdb_rec != NULL; pdb_rec = pdb_rec->next) { + char *vdata = (char *) pdb_rec->data; + struct tm created, visited; + int icon_nr, selected; + int latdeg, londeg; + double lat, lon, altitude; + waypoint *waypt; + + memset(&visited, 0, sizeof(visited)); + memset(&created, 0, sizeof(created)); + + latdeg = be_read16(vdata + 0); + lat = be_read32(vdata + 2); + londeg = be_read16(vdata + 6); + lon = be_read32(vdata + 8); + altitude = (float) be_read32(vdata + 12); + selected = vdata[16]; + created.tm_min = be_read16(vdata + 20); + created.tm_hour = be_read16(vdata + 22); + created.tm_mday = be_read16(vdata + 24); + created.tm_mon = be_read16(vdata + 26); + created.tm_year = be_read16(vdata + 28); + visited.tm_min = be_read16(vdata + 34); + visited.tm_hour = be_read16(vdata + 36); + visited.tm_mday = be_read16(vdata + 38); + visited.tm_mon = be_read16(vdata + 40); + visited.tm_year = be_read16(vdata + 42); #ifdef GEONICHE_DBG - printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", - created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, - visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); + printf(MYNAME "-date: %04d/%02d/%02d, %02d:%02d (%04d/%02d/%02d, %02d:%02d)\n", + created.tm_year, created.tm_mon, created.tm_mday, created.tm_hour, created.tm_min, + visited.tm_year, visited.tm_mon, visited.tm_mday, visited.tm_hour, visited.tm_min); #endif - icon_nr = vdata[62]; - - latdeg = 89 - latdeg; - lat = lat * (double) 0.0000006; - if (latdeg >= 0) - lat = (double) 60.0 - lat; - else - latdeg++; - - lon = lon * (double) 0.0000006; - while (londeg >= 360) londeg-=360; - if (londeg > 180) - { - lon = (double) 60.0 - lon; - londeg = londeg - 359; - } - - created.tm_year-=1900; - created.tm_mon--; - - waypt = waypt_new(); - - waypt->shortname = xstrdup(vdata + 63); - waypt->altitude = altitude; - waypt->creation_time = mkgmtime(&created); - - GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); - GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); - - waypt->icon_descr = geoniche_icon_to_descr(icon_nr); - if (waypt->icon_descr != NULL) - waypt->wpt_flags.icon_descr_is_dynamic = 1; - - waypt_add(waypt); + icon_nr = vdata[62]; + + latdeg = 89 - latdeg; + lat = lat * (double) 0.0000006; + if (latdeg >= 0) { + lat = (double) 60.0 - lat; + } else { + latdeg++; + } + + lon = lon * (double) 0.0000006; + while (londeg >= 360) { + londeg-=360; + } + if (londeg > 180) { + lon = (double) 60.0 - lon; + londeg = londeg - 359; + } + + created.tm_year-=1900; + created.tm_mon--; + + waypt = waypt_new(); + + waypt->shortname = xstrdup(vdata + 63); + waypt->altitude = altitude; + waypt->creation_time = mkgmtime(&created); + + GPS_Math_DegMin_To_Deg(latdeg, lat, &waypt->latitude); + GPS_Math_DegMin_To_Deg(londeg, lon, &waypt->longitude); + + waypt->icon_descr = geoniche_icon_to_descr(icon_nr); + if (waypt->icon_descr != NULL) { + waypt->wpt_flags.icon_descr_is_dynamic = 1; } + + waypt_add(waypt); + } } static void data_read(void) { - if (file_in->creator != MYCREATOR) - fatal(MYNAME ": Not a GeoNiche file.\n"); - - switch(file_in->type) - { - case MYTYPE_ASC: - geoniche_read_asc(); - break; - case MYTYPE_BIN: - geoniche_read_bin(); - break; - default: - fatal(MYNAME ": Unsupported GeoNiche file.\n"); - } + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a GeoNiche file.\n"); + } + + switch (file_in->type) { + case MYTYPE_ASC: + geoniche_read_asc(); + break; + case MYTYPE_BIN: + geoniche_read_bin(); + break; + default: + fatal(MYNAME ": Unsupported GeoNiche file.\n"); + } } static char * enscape(char *s) { - char *buf, *d; + char *buf, *d; - if (!s) - { - d = xmalloc(1); - *d = 0; - return d; + if (!s) { + d = xmalloc(1); + *d = 0; + return d; + } + buf = d = xmalloc(strlen(s) * 2 + 1); + for (; *s; ++s) { + + /* + * 3 May 06: need to escape single quotes for v1.40 release + */ + + if (*s == '\\' || *s == ',' || *s == '\'') { + *d++ = '\\'; + *d++ = *s; } - buf = d = xmalloc(strlen(s) * 2 + 1); - for (; *s; ++s) - { - -/* - * 3 May 06: need to escape single quotes for v1.40 release - */ - - if (*s == '\\' || *s == ',' || *s == '\'') - { - *d++ = '\\'; - *d++ = *s; - } -/* 3 May 06: stop stripping for better readability - * - * else if ((*s == '\r') || (*s == '\n')) - * *d++ = ' '; - */ - else - *d++ = *s; + /* 3 May 06: stop stripping for better readability + * + * else if ((*s == '\r') || (*s == '\n')) + * *d++ = ' '; + */ + else { + *d++ = *s; } + } - *d = 0; - return buf; + *d = 0; + return buf; } /* @@ -574,206 +616,238 @@ enscape(char *s) static int wpt2icon(const waypoint *wpt) { - const char *desc = wpt->icon_descr; - - if (!desc) return 0; - else if (strstr(desc, "reg")) return 43; - else if (strstr(desc, "trad")) return 43; - else if (strstr(desc, "multi")) return 44; - else if (strstr(desc, "offset")) return 44; - else if (strstr(desc, "virt")) return 45; - else if (strstr(desc, "loca")) return 45; - else if (strstr(desc, "event")) return 46; - else if (strstr(desc, "lett")) return 47; - else if (strstr(desc, "hyb")) return 47; - else if (strstr(desc, "unk")) return 48; - else if (strstr(desc, "cam")) return 49; - - switch (wpt->gc_data->type) { - case gt_traditional: return 43; - case gt_multi: return 44; - case gt_locationless: return 45; - case gt_earth: return 45; - case gt_virtual: return 45; - case gt_letterbox: return 46; - case gt_event: return 47; - case gt_cito: return 47; - case gt_suprise: return 48; - case gt_webcam: return 49; - case gt_unknown: return 0; - case gt_benchmark: return 0; - case gt_ape: return 0; - case gt_mega: return 0; - case gt_wherigo: return 0; - } + const char *desc = wpt->icon_descr; + if (!desc) { return 0; + } else if (strstr(desc, "reg")) { + return 43; + } else if (strstr(desc, "trad")) { + return 43; + } else if (strstr(desc, "multi")) { + return 44; + } else if (strstr(desc, "offset")) { + return 44; + } else if (strstr(desc, "virt")) { + return 45; + } else if (strstr(desc, "loca")) { + return 45; + } else if (strstr(desc, "event")) { + return 46; + } else if (strstr(desc, "lett")) { + return 47; + } else if (strstr(desc, "hyb")) { + return 47; + } else if (strstr(desc, "unk")) { + return 48; + } else if (strstr(desc, "cam")) { + return 49; + } + + switch (wpt->gc_data->type) { + case gt_traditional: + return 43; + case gt_multi: + return 44; + case gt_locationless: + return 45; + case gt_earth: + return 45; + case gt_virtual: + return 45; + case gt_letterbox: + return 46; + case gt_event: + return 47; + case gt_cito: + return 47; + case gt_suprise: + return 48; + case gt_webcam: + return 49; + case gt_unknown: + return 0; + case gt_benchmark: + return 0; + case gt_ape: + return 0; + case gt_mega: + return 0; + case gt_wherigo: + return 0; + } + + return 0; } static char * geoniche_geostuff(const waypoint *wpt) { - char *gs = NULL, *tmp1, *tmp2, *tmp3; - char tbuf[10240]; - - if (!wpt->gc_data->terr) { - return NULL; - } - - snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data->type), wpt->gc_data->placer); - gs = xstrappend(gs, tbuf); - -/* - * 3 May 06: Removed duplicated information - * - * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); - * gs = xstrappend(gs, tbuf); - */ - -/* - * 3 May 06: Added container type - */ - snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data->container), wpt->gc_data->diff/10.0, wpt->gc_data->terr/10.0); - gs = xstrappend(gs, tbuf); - - tmp1 = strip_html(&wpt->gc_data->desc_short); - tmp2 = strip_html(&wpt->gc_data->desc_long); - gs = xstrappend(gs, tmp1); - gs = xstrappend(gs, tmp2); - - tmp3 = rot13(wpt->gc_data->hint); - snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); - gs = xstrappend(gs, tbuf); - - xfree(tmp1); - xfree(tmp2); - xfree(tmp3); - - tmp1 = enscape(gs); - xfree(gs); - - return tmp1; + char *gs = NULL, *tmp1, *tmp2, *tmp3; + char tbuf[10240]; + + if (!wpt->gc_data->terr) { + return NULL; + } + + snprintf(tbuf, sizeof(tbuf), "\n%s by %s\n\n", gs_get_cachetype(wpt->gc_data->type), wpt->gc_data->placer); + gs = xstrappend(gs, tbuf); + + /* + * 3 May 06: Removed duplicated information + * + * snprintf(tbuf, sizeof(tbuf), "Waypoint: %s %s\n", wpt->shortname, wpt->description); + * gs = xstrappend(gs, tbuf); + */ + + /* + * 3 May 06: Added container type + */ + snprintf(tbuf, sizeof(tbuf), "Container: %s\nDifficulty: %3.1f\nTerrain: %3.1f\n\n", gs_get_container(wpt->gc_data->container), wpt->gc_data->diff/10.0, wpt->gc_data->terr/10.0); + gs = xstrappend(gs, tbuf); + + tmp1 = strip_html(&wpt->gc_data->desc_short); + tmp2 = strip_html(&wpt->gc_data->desc_long); + gs = xstrappend(gs, tmp1); + gs = xstrappend(gs, tmp2); + + tmp3 = rot13(wpt->gc_data->hint); + snprintf(tbuf, sizeof(tbuf), "\n\nHint: %s\n", tmp3); + gs = xstrappend(gs, tbuf); + + xfree(tmp1); + xfree(tmp2); + xfree(tmp3); + + tmp1 = enscape(gs); + xfree(gs); + + return tmp1; } static void geoniche_writewpt(const waypoint *wpt) { - int vlen; - char *vdata; - char *title; - struct tm tm; - char datestr[10+1]; - char timestr[8+1]; - char *notes; - int id; - time_t tx; - char *gs; - - if (rec_ct == 0) { - pdb_write_rec(file_out, 0, 0, ct++, Rec0Magic, sizeof(Rec0Magic)); - } - - if ( wpt->description && wpt->description[0] ) - title = enscape(wpt->description); - else - title = enscape(wpt->shortname); - - id = gid2id(wpt->shortname); - if (id < 0) - id = rec_ct; - - tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; - if (tx == 0) { /* maybe zero during testo (freezed time) */ - strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ - strcpy(timestr, "00:00:00"); - } - else { - tm = *localtime(&tx); - strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); - strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); - } - - /* Notes field MUST have soemthing in it */ - if (!wpt->notes || wpt->notes[0] == 0) - notes = xstrdup(title); - else - notes = enscape(wpt->notes); - - gs = geoniche_geostuff(wpt); - if (gs) { - notes = xstrappend(notes, gs); - xfree (gs); - } - /* last chance to fill notes with something */ - if (*notes == '\0') notes = xstrappend(notes, "(notes)"); - - vlen = xasprintf(&vdata, - "Target,%d,%s,,%s,%f,%f,%f,%s,%s,,,,%d,,,,%s" - , id - , title - /* route ID */ - , Arg_category ? Arg_category : "Cache" - , wpt->latitude - , wpt->longitude - , wpt->altitude - , datestr - , timestr - /* visited date */ - /* visited time */ - /* icon color R G B */ - , wpt2icon(wpt) - /* unused1 */ - /* unused2 */ - /* unused3 */ - , notes - ); - - pdb_write_rec(file_out, 0, 0, ct++, vdata, vlen + 1); - - xfree(notes); - xfree(title); - xfree(vdata); - - rec_ct++; + int vlen; + char *vdata; + char *title; + struct tm tm; + char datestr[10+1]; + char timestr[8+1]; + char *notes; + int id; + time_t tx; + char *gs; + + if (rec_ct == 0) { + pdb_write_rec(file_out, 0, 0, ct++, Rec0Magic, sizeof(Rec0Magic)); + } + + if (wpt->description && wpt->description[0]) { + title = enscape(wpt->description); + } else { + title = enscape(wpt->shortname); + } + + id = gid2id(wpt->shortname); + if (id < 0) { + id = rec_ct; + } + + tx = (wpt->creation_time != 0) ? wpt->creation_time : gpsbabel_time; + if (tx == 0) { /* maybe zero during testo (freezed time) */ + strcpy(datestr, "01/01/1904"); /* this seems to be the uninitialized date value for geoniche */ + strcpy(timestr, "00:00:00"); + } else { + tm = *localtime(&tx); + strftime(datestr, sizeof(datestr), "%m/%d/%Y", &tm); + strftime(timestr, sizeof(timestr), "%H:%M:%S", &tm); + } + + /* Notes field MUST have soemthing in it */ + if (!wpt->notes || wpt->notes[0] == 0) { + notes = xstrdup(title); + } else { + notes = enscape(wpt->notes); + } + + gs = geoniche_geostuff(wpt); + if (gs) { + notes = xstrappend(notes, gs); + xfree(gs); + } + /* last chance to fill notes with something */ + if (*notes == '\0') { + notes = xstrappend(notes, "(notes)"); + } + + vlen = xasprintf(&vdata, + "Target,%d,%s,,%s,%f,%f,%f,%s,%s,,,,%d,,,,%s" + , id + , title + /* route ID */ + , Arg_category ? Arg_category : "Cache" + , wpt->latitude + , wpt->longitude + , wpt->altitude + , datestr + , timestr + /* visited date */ + /* visited time */ + /* icon color R G B */ + , wpt2icon(wpt) + /* unused1 */ + /* unused2 */ + /* unused3 */ + , notes + ); + + pdb_write_rec(file_out, 0, 0, ct++, vdata, vlen + 1); + + xfree(notes); + xfree(title); + xfree(vdata); + + rec_ct++; } static void data_write(void) { - if (Arg_dbname) { - if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) - fatal(MYNAME ": Reserved database name!\n"); - strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN); - } - else - strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24); - file_out->type = MYTYPE_ASC; - file_out->creator = MYCREATOR; - file_out->version = 0; - file_out->revision = 1; - - rec_ct = 0; - ct = 0; - waypt_disp_all(geoniche_writewpt); + if (Arg_dbname) { + if (case_ignore_strcmp(Arg_dbname, "GeoNiche Targets") == 0) { + fatal(MYNAME ": Reserved database name!\n"); + } + strncpy(file_out->name, Arg_dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, FilenameOut, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + (49*365 + 17*366) * (60*60*24); + file_out->type = MYTYPE_ASC; + file_out->creator = MYCREATOR; + file_out->version = 0; + file_out->revision = 1; + + rec_ct = 0; + ct = 0; + waypt_disp_all(geoniche_writewpt); } -ff_vecs_t geoniche_vecs = -{ - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - Args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ +ff_vecs_t geoniche_vecs = { + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + Args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/ggv_log.c b/gpsbabel/ggv_log.c index ef31cba31..933441251 100644 --- a/gpsbabel/ggv_log.c +++ b/gpsbabel/ggv_log.c @@ -34,7 +34,7 @@ static int ggv_log_ver; static arglist_t ggv_log_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -44,233 +44,246 @@ arglist_t ggv_log_args[] = { static void ggv_log_rd_init(const char *fname) { - static char magic[32]; - int len = 0; - - fin = gbfopen(fname, "rb", MYNAME); - - for (;;) { - int cin; - - cin = gbfgetc(fin); - if (cin < 0) break; - - magic[len++] = cin; - - if (cin == '\0') { - double ver = 0; - char *sver; - if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) break; - - sver = &magic[18]; - sscanf(sver, "%lf:", &ver); - ggv_log_ver = ver * 10; - if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) return; /* header accepted */ - - fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver); - } - else if (len == sizeof(magic)) - break; - } - fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n"); + static char magic[32]; + int len = 0; + + fin = gbfopen(fname, "rb", MYNAME); + + for (;;) { + int cin; + + cin = gbfgetc(fin); + if (cin < 0) { + break; + } + + magic[len++] = cin; + + if (cin == '\0') { + double ver = 0; + char *sver; + if (strncmp(magic, "DOMGVGPS Logfile V", 18) != 0) { + break; + } + + sver = &magic[18]; + sscanf(sver, "%lf:", &ver); + ggv_log_ver = ver * 10; + if ((ggv_log_ver == 10) || (ggv_log_ver == 25)) { + return; /* header accepted */ + } + + fatal(MYNAME ": Sorry, unsupported version (%s)!\n", sver); + } else if (len == sizeof(magic)) { + break; + } + } + fatal(MYNAME ": Invalid header. Probably no " MYNAME " file!\n"); } -static void +static void ggv_log_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void ggv_log_read(void) { - signed char *buf; - int bufsz = 0, len; - route_head *trk = NULL; - - switch(ggv_log_ver) { - case 10: bufsz = 0x2A; break; - case 25: bufsz = 0x6F; break; - } - - buf = xmalloc(bufsz); - - while ((len = gbfread(buf, 1, bufsz, fin))) { - int deg, min; - double xlat, xlon; - float sec; - struct tm tm; - waypoint *wpt; - - if (len != bufsz) break; - - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - - memset(&tm, 0, sizeof(tm)); - - wpt = waypt_new(); - - deg = (gbint16) le_read16(&buf[0]); - min = le_read16(&buf[2]); - sec = le_read_float(&buf[4]); - xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); - wpt->latitude = xlat; - - deg = (gbint16) le_read16(&buf[8]); - min = le_read16(&buf[10]); - sec = le_read_float(&buf[12]); - xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); - wpt->longitude = xlon; - - WAYPT_SET(wpt, course, le_read16(&buf[16 + 0])); - - if (ggv_log_ver == 10) { - double secs; - - wpt->altitude = le_read16(&buf[16 + 2]); - WAYPT_SET(wpt, speed, le_read16(&buf[16 + 4])); - tm.tm_year = le_read16(&buf[16 + 8]); - tm.tm_mon = le_read16(&buf[16 + 10]); - tm.tm_mday = le_read16(&buf[16 + 12]); - tm.tm_hour = le_read16(&buf[16 + 14]); - tm.tm_min = le_read16(&buf[16 + 16]); - secs = le_read_double(&buf[16 + 18]); - tm.tm_sec = (int)secs; - wpt->microseconds = (secs - tm.tm_sec) * 1000000; - } - else { - wpt->altitude = le_read16(&buf[16 + 4]); - wpt->sat = (unsigned char)buf[16 + 14]; - - /* other probably valid double values at offset: - - 22: 0.0 - 20.0 - 43: 0.0 - 59.0 - 51: -1.0 - 61: -1.0 - 79: .. - 20.0 ? speed over ground ? (++) - 87: ? course ? - 95: 0.0 - 3.1 (++) - 103: -1 - - */ - } - - if (wpt->altitude == 0) - wpt->altitude = unknown_alt; - - if (tm.tm_year >= 1900) { - tm.tm_year -= 1900; - if (tm.tm_mon > 0) { - tm.tm_mon--; - wpt->creation_time = mkgmtime(&tm); - } - } - - track_add_wpt(trk, wpt); - } - xfree(buf); + signed char *buf; + int bufsz = 0, len; + route_head *trk = NULL; + + switch (ggv_log_ver) { + case 10: + bufsz = 0x2A; + break; + case 25: + bufsz = 0x6F; + break; + } + + buf = xmalloc(bufsz); + + while ((len = gbfread(buf, 1, bufsz, fin))) { + int deg, min; + double xlat, xlon; + float sec; + struct tm tm; + waypoint *wpt; + + if (len != bufsz) { + break; + } + + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + + memset(&tm, 0, sizeof(tm)); + + wpt = waypt_new(); + + deg = (gbint16) le_read16(&buf[0]); + min = le_read16(&buf[2]); + sec = le_read_float(&buf[4]); + xlat = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->latitude = xlat; + + deg = (gbint16) le_read16(&buf[8]); + min = le_read16(&buf[10]); + sec = le_read_float(&buf[12]); + xlon = (double)deg + ((double)min / (double)60) + (sec / (double)3600.0); + wpt->longitude = xlon; + + WAYPT_SET(wpt, course, le_read16(&buf[16 + 0])); + + if (ggv_log_ver == 10) { + double secs; + + wpt->altitude = le_read16(&buf[16 + 2]); + WAYPT_SET(wpt, speed, le_read16(&buf[16 + 4])); + tm.tm_year = le_read16(&buf[16 + 8]); + tm.tm_mon = le_read16(&buf[16 + 10]); + tm.tm_mday = le_read16(&buf[16 + 12]); + tm.tm_hour = le_read16(&buf[16 + 14]); + tm.tm_min = le_read16(&buf[16 + 16]); + secs = le_read_double(&buf[16 + 18]); + tm.tm_sec = (int)secs; + wpt->microseconds = (secs - tm.tm_sec) * 1000000; + } else { + wpt->altitude = le_read16(&buf[16 + 4]); + wpt->sat = (unsigned char)buf[16 + 14]; + + /* other probably valid double values at offset: + + 22: 0.0 - 20.0 + 43: 0.0 - 59.0 + 51: -1.0 + 61: -1.0 + 79: .. - 20.0 ? speed over ground ? (++) + 87: ? course ? + 95: 0.0 - 3.1 (++) + 103: -1 + + */ + } + + if (wpt->altitude == 0) { + wpt->altitude = unknown_alt; + } + + if (tm.tm_year >= 1900) { + tm.tm_year -= 1900; + if (tm.tm_mon > 0) { + tm.tm_mon--; + wpt->creation_time = mkgmtime(&tm); + } + } + + track_add_wpt(trk, wpt); + } + xfree(buf); } static void ggv_log_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); - - gbfputcstr("DOMGVGPS Logfile V1.0:", fout); + fout = gbfopen(fname, "wb", MYNAME); + + gbfputcstr("DOMGVGPS Logfile V1.0:", fout); } static void ggv_log_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void ggv_log_track_head_cb(const route_head *trk) { - queue *elem, *tmp; - waypoint *prev = NULL; - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - double latmin, lonmin, latsec, lonsec; - int latint, lonint; - double course = 0, speed = 0; - struct tm tm; - waypoint *wpt = (waypoint *)elem; - double secs = 0; - - latint = wpt->latitude; - lonint = wpt->longitude; - latmin = 60.0 * (fabs(wpt->latitude) - latint); - lonmin = 60.0 * (fabs(wpt->longitude) - lonint); - latsec = 60.0 * (latmin - floor(latmin)); - lonsec = 60.0 * (lonmin - floor(lonmin)); - - if (wpt->creation_time > 0) { - tm = *gmtime(&wpt->creation_time); - tm.tm_mon += 1; - tm.tm_year += 1900; - } - else - memset(&tm, 0, sizeof(tm)); - - if (prev != NULL) { - course = heading_true_degrees( - prev->latitude, prev->longitude, - wpt->latitude, wpt->longitude); - speed = waypt_speed(prev, wpt); - } - if (wpt->creation_time > 0) - secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000); - - gbfputint16((gbint16) latint, fout); - gbfputint16((gbint16) latmin, fout); - gbfputflt(latsec, fout); - gbfputint16((gbint16) lonint, fout); - gbfputint16((gbint16) lonmin, fout); - gbfputflt(lonsec, fout); - gbfputint16((gbint16) course, fout); - gbfputint16((gbint16) (wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout); - gbfputint16((gbint16) speed, fout); - gbfputint16(0, fout); - gbfputint16(tm.tm_year, fout); - gbfputint16(tm.tm_mon, fout); - gbfputint16(tm.tm_mday, fout); - gbfputint16(tm.tm_hour, fout); - gbfputint16(tm.tm_min, fout); - gbfputdbl(secs, fout); - - prev = wpt; - } + queue *elem, *tmp; + waypoint *prev = NULL; + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + double course = 0, speed = 0; + struct tm tm; + waypoint *wpt = (waypoint *)elem; + double secs = 0; + + latint = wpt->latitude; + lonint = wpt->longitude; + latmin = 60.0 * (fabs(wpt->latitude) - latint); + lonmin = 60.0 * (fabs(wpt->longitude) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + + if (wpt->creation_time > 0) { + tm = *gmtime(&wpt->creation_time); + tm.tm_mon += 1; + tm.tm_year += 1900; + } else { + memset(&tm, 0, sizeof(tm)); + } + + if (prev != NULL) { + course = heading_true_degrees( + prev->latitude, prev->longitude, + wpt->latitude, wpt->longitude); + speed = waypt_speed(prev, wpt); + } + if (wpt->creation_time > 0) { + secs = (double)tm.tm_sec + ((double)wpt->microseconds / 1000000); + } + + gbfputint16((gbint16) latint, fout); + gbfputint16((gbint16) latmin, fout); + gbfputflt(latsec, fout); + gbfputint16((gbint16) lonint, fout); + gbfputint16((gbint16) lonmin, fout); + gbfputflt(lonsec, fout); + gbfputint16((gbint16) course, fout); + gbfputint16((gbint16)(wpt->altitude != unknown_alt) ? wpt->altitude : 0, fout); + gbfputint16((gbint16) speed, fout); + gbfputint16(0, fout); + gbfputint16(tm.tm_year, fout); + gbfputint16(tm.tm_mon, fout); + gbfputint16(tm.tm_mday, fout); + gbfputint16(tm.tm_hour, fout); + gbfputint16(tm.tm_min, fout); + gbfputdbl(secs, fout); + + prev = wpt; + } } static void ggv_log_write(void) { - track_disp_all(ggv_log_track_head_cb, NULL, NULL); + track_disp_all(ggv_log_track_head_cb, NULL, NULL); } /**************************************************************************/ ff_vecs_t ggv_log_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - ggv_log_rd_init, - ggv_log_wr_init, - ggv_log_rd_deinit, - ggv_log_wr_deinit, - ggv_log_read, - ggv_log_write, - NULL, - ggv_log_args, - CET_CHARSET_ASCII, 1 + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none /* routes */ + }, + ggv_log_rd_init, + ggv_log_wr_init, + ggv_log_rd_deinit, + ggv_log_wr_deinit, + ggv_log_read, + ggv_log_write, + NULL, + ggv_log_args, + CET_CHARSET_ASCII, 1 }; /**************************************************************************/ diff --git a/gpsbabel/ggv_ovl.c b/gpsbabel/ggv_ovl.c index fbd3057a1..29622ad7b 100644 --- a/gpsbabel/ggv_ovl.c +++ b/gpsbabel/ggv_ovl.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include #include #include @@ -32,29 +32,29 @@ static arglist_t ggv_ovl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; typedef enum { - OVL_SYMBOL_BITMAP = 1, - OVL_SYMBOL_TEXT, - OVL_SYMBOL_LINE, - OVL_SYMBOL_POLYGON, - OVL_SYMBOL_RECTANGLE, - OVL_SYMBOL_CIRCLE, - OVL_SYMBOL_TRIANGLE + OVL_SYMBOL_BITMAP = 1, + OVL_SYMBOL_TEXT, + OVL_SYMBOL_LINE, + OVL_SYMBOL_POLYGON, + OVL_SYMBOL_RECTANGLE, + OVL_SYMBOL_CIRCLE, + OVL_SYMBOL_TRIANGLE } OVL_SYMBOL_TYP; typedef enum { - OVL_COLOR_RED = 1, /* = 1 */ - OVL_COLOR_LIME, /* = 2 */ - OVL_COLOR_BLUE, /* = 3 */ - OVL_COLOR_YELLOW, /* = 4 */ - OVL_COLOR_BLACK, /* = 5 */ - OVL_COLOR_WHITE, /* = 6 */ - OVL_COLOR_7, /* = 7 (draws only a simple line) */ - OVL_COLOR_FUCHSIA, /* = 8 */ - OVL_COLOR_AQUA, /* = 9 */ + OVL_COLOR_RED = 1, /* = 1 */ + OVL_COLOR_LIME, /* = 2 */ + OVL_COLOR_BLUE, /* = 3 */ + OVL_COLOR_YELLOW, /* = 4 */ + OVL_COLOR_BLACK, /* = 5 */ + OVL_COLOR_WHITE, /* = 6 */ + OVL_COLOR_7, /* = 7 (draws only a simple line) */ + OVL_COLOR_FUCHSIA, /* = 8 */ + OVL_COLOR_AQUA, /* = 9 */ } OVL_COLOR_TYP; /* some hints: @@ -81,110 +81,121 @@ static OVL_COLOR_TYP color; static void ggv_ovl_rd_init(const char *fname) { - inifile = inifile_init(fname, MYNAME); - if (inifile->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + inifile = inifile_init(fname, MYNAME); + if (inifile->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } - route_ct = 0; - track_ct = 0; + route_ct = 0; + track_ct = 0; } -static void +static void ggv_ovl_rd_deinit(void) { - inifile_done(inifile); + inifile_done(inifile); } static void ggv_ovl_read(void) { - int symbols; - int i; - - symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1); - - for (i = 1; i <= symbols; i++) { - int points; - OVL_SYMBOL_TYP type; - char symbol[32]; - - snprintf(symbol, sizeof(symbol), "Symbol %d", i); - - type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0); - points = inifile_readint_def(inifile, symbol, "Punkte", -1); - - switch(type) { - - char coord[32]; - waypoint *wpt; - char *cx; - int group; - - case OVL_SYMBOL_LINE: - case OVL_SYMBOL_POLYGON: - - if (!inifile_readint(inifile, symbol, "Group", &group)) group = -1; - - if (points > 0) { - int j; - route_head *rte, *trk; - - rte = trk = route_head_alloc(); - if (group > 1) { - route_add_head(rte); - route_ct++; - xasprintf(&rte->rte_name, "Route %d", route_ct); - } - else { - track_add_head(trk); - track_ct++; - xasprintf(&trk->rte_name, "Track %d", track_ct); - } - - for (j = 0; j < points; j++) { - - wpt = waypt_new(); - - snprintf(coord, sizeof(coord), "YKoord%d", j); - if ((cx = inifile_readstr(inifile, symbol, coord))) - wpt->latitude = atof(cx); - else - continue; - - snprintf(coord, sizeof(coord), "XKoord%d", j); - if ((cx = inifile_readstr(inifile, symbol, coord))) - wpt->longitude = atof(cx); - else - continue; - - if (group > 1) route_add_wpt(rte, wpt); - else track_add_wpt(trk, wpt); - } - } - break; - - case OVL_SYMBOL_CIRCLE: - case OVL_SYMBOL_TRIANGLE: - - wpt = waypt_new(); - wpt->shortname = xstrdup(symbol); - - if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) - wpt->latitude = atof(cx); - else - continue; - if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) - wpt->longitude = atof(cx); - else - continue; - - waypt_add(wpt); - break; - - case OVL_SYMBOL_BITMAP: - case OVL_SYMBOL_TEXT: - case OVL_SYMBOL_RECTANGLE: break; - } - } + int symbols; + int i; + + symbols = inifile_readint_def(inifile, "Overlay", "Symbols", -1); + + for (i = 1; i <= symbols; i++) { + int points; + OVL_SYMBOL_TYP type; + char symbol[32]; + + snprintf(symbol, sizeof(symbol), "Symbol %d", i); + + type = (OVL_SYMBOL_TYP) inifile_readint_def(inifile, symbol, "Typ", 0); + points = inifile_readint_def(inifile, symbol, "Punkte", -1); + + switch (type) { + + char coord[32]; + waypoint *wpt; + char *cx; + int group; + + case OVL_SYMBOL_LINE: + case OVL_SYMBOL_POLYGON: + + if (!inifile_readint(inifile, symbol, "Group", &group)) { + group = -1; + } + + if (points > 0) { + int j; + route_head *rte, *trk; + + rte = trk = route_head_alloc(); + if (group > 1) { + route_add_head(rte); + route_ct++; + xasprintf(&rte->rte_name, "Route %d", route_ct); + } else { + track_add_head(trk); + track_ct++; + xasprintf(&trk->rte_name, "Track %d", track_ct); + } + + for (j = 0; j < points; j++) { + + wpt = waypt_new(); + + snprintf(coord, sizeof(coord), "YKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) { + wpt->latitude = atof(cx); + } else { + continue; + } + + snprintf(coord, sizeof(coord), "XKoord%d", j); + if ((cx = inifile_readstr(inifile, symbol, coord))) { + wpt->longitude = atof(cx); + } else { + continue; + } + + if (group > 1) { + route_add_wpt(rte, wpt); + } else { + track_add_wpt(trk, wpt); + } + } + } + break; + + case OVL_SYMBOL_CIRCLE: + case OVL_SYMBOL_TRIANGLE: + + wpt = waypt_new(); + wpt->shortname = xstrdup(symbol); + + if ((cx = inifile_readstr(inifile, symbol, "YKoord"))) { + wpt->latitude = atof(cx); + } else { + continue; + } + if ((cx = inifile_readstr(inifile, symbol, "XKoord"))) { + wpt->longitude = atof(cx); + } else { + continue; + } + + waypt_add(wpt); + break; + + case OVL_SYMBOL_BITMAP: + case OVL_SYMBOL_TEXT: + case OVL_SYMBOL_RECTANGLE: + break; + } + } } /**************************************************************************/ @@ -204,40 +215,40 @@ static int get_direction(const waypoint *A, const waypoint *B); static void ggv_ovl_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); - - symbol_ct = 0; + fout = gbfopen(fname, "w", MYNAME); + + symbol_ct = 0; } static void ggv_ovl_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void ggv_ovl_write(void) { - group_ct = 1; /* tracks are not grouped */ - color = OVL_COLOR_FUCHSIA; - track_disp_all(track_disp_cb, NULL, NULL); - - group_ct++; - color = OVL_COLOR_AQUA; - route_disp_all(route_disp_cb, NULL, NULL); - - group_ct++; - color = OVL_COLOR_LIME; - waypt_disp_all(waypt_disp_cb); - - gbfprintf(fout, "[Overlay]\n"); - gbfprintf(fout, "Symbols=%d\n", symbol_ct); - gbfprintf(fout, "[MapLage]\n"); - gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n"); - gbfprintf(fout, "DimmFc=100\n"); - gbfprintf(fout, "ZoomFc=100\n"); - write_bounds(); - gbfprintf(fout, "RefOn=0\n"); /* no reference point */ + group_ct = 1; /* tracks are not grouped */ + color = OVL_COLOR_FUCHSIA; + track_disp_all(track_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_AQUA; + route_disp_all(route_disp_cb, NULL, NULL); + + group_ct++; + color = OVL_COLOR_LIME; + waypt_disp_all(waypt_disp_cb); + + gbfprintf(fout, "[Overlay]\n"); + gbfprintf(fout, "Symbols=%d\n", symbol_ct); + gbfprintf(fout, "[MapLage]\n"); + gbfprintf(fout, "MapName=Bundesrepublik 1:1 Mio\n"); + gbfprintf(fout, "DimmFc=100\n"); + gbfprintf(fout, "ZoomFc=100\n"); + write_bounds(); + gbfprintf(fout, "RefOn=0\n"); /* no reference point */ } /**************************************************************************/ @@ -245,13 +256,13 @@ ggv_ovl_write(void) static void waypt_disp_cb(const waypoint *wpt) { - draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt); - gbfprintf(fout, "Width=20\n"); - gbfprintf(fout, "Height=20\n"); - gbfprintf(fout, "Dir=100\n"); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=102\n"); - gbfprintf(fout, "Area=2\n"); + draw_symbol_basics(OVL_SYMBOL_CIRCLE, 1, color, wpt); + gbfprintf(fout, "Width=20\n"); + gbfprintf(fout, "Height=20\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=102\n"); + gbfprintf(fout, "Area=2\n"); // draw_symbol_text(wpt->shortname, wpt); } @@ -260,29 +271,31 @@ waypt_disp_cb(const waypoint *wpt) static void track_disp_cb(const route_head *trk) { - int i; - queue *elem, *tmp; - int waypt_ct = trk->rte_waypt_ct; - - if (waypt_ct <= 0) return; - - draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL); - - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=105\n"); - gbfprintf(fout, "Punkte=%d\n", waypt_ct); - - i = 0; - - QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) { - - waypoint *wpt = (waypoint *) elem; - - gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude); - gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude); - - i++; - } + int i; + queue *elem, *tmp; + int waypt_ct = trk->rte_waypt_ct; + + if (waypt_ct <= 0) { + return; + } + + draw_symbol_basics(OVL_SYMBOL_LINE, 1, color, NULL); + + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=105\n"); + gbfprintf(fout, "Punkte=%d\n", waypt_ct); + + i = 0; + + QUEUE_FOR_EACH(&(trk->waypoint_list), elem, tmp) { + + waypoint *wpt = (waypoint *) elem; + + gbfprintf(fout, "XKoord%d=%0.8f\n", i, wpt->longitude); + gbfprintf(fout, "YKoord%d=%0.8f\n", i, wpt->latitude); + + i++; + } } /* -----------------------------------------------------------------------*/ @@ -290,38 +303,40 @@ track_disp_cb(const route_head *trk) static void route_disp_cb(const route_head *rte) { - int i; - queue *elem, *tmp; - waypoint *prev; - int waypt_ct = rte->rte_waypt_ct; - - if (waypt_ct <= 0) return; - - track_disp_cb(rte); /* draw a line as tracks */ - - color = OVL_COLOR_RED; - - i = 0; - prev = NULL; - - QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) { - - waypoint *wpt = (waypoint *) elem; - - if (prev != NULL) { - draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, 9 /* color */, prev); - - gbfprintf(fout, "Width=12\n"); - gbfprintf(fout, "Height=8\n"); - gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt)); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=101\n"); - gbfprintf(fout, "Area=2\n"); - } - - i++; - prev = wpt; - } + int i; + queue *elem, *tmp; + waypoint *prev; + int waypt_ct = rte->rte_waypt_ct; + + if (waypt_ct <= 0) { + return; + } + + track_disp_cb(rte); /* draw a line as tracks */ + + color = OVL_COLOR_RED; + + i = 0; + prev = NULL; + + QUEUE_FOR_EACH(&(rte->waypoint_list), elem, tmp) { + + waypoint *wpt = (waypoint *) elem; + + if (prev != NULL) { + draw_symbol_basics(OVL_SYMBOL_TRIANGLE, 1, 9 /* color */, prev); + + gbfprintf(fout, "Width=12\n"); + gbfprintf(fout, "Height=8\n"); + gbfprintf(fout, "Dir=%d\n", 100 + get_direction(prev, wpt)); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=101\n"); + gbfprintf(fout, "Area=2\n"); + } + + i++; + prev = wpt; + } } /* -----------------------------------------------------------------------*/ @@ -329,46 +344,47 @@ route_disp_cb(const route_head *rte) static void waypt_bound_calc(const waypoint *waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void write_bounds(void) { - waypt_init_bounds(&all_bounds); + waypt_init_bounds(&all_bounds); - waypt_disp_all(waypt_bound_calc); - route_disp_all(NULL, NULL, waypt_bound_calc); - track_disp_all(NULL, NULL, waypt_bound_calc); + waypt_disp_all(waypt_bound_calc); + route_disp_all(NULL, NULL, waypt_bound_calc); + track_disp_all(NULL, NULL, waypt_bound_calc); - if (waypt_bounds_valid(&all_bounds)) { + if (waypt_bounds_valid(&all_bounds)) { - double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2); - double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2); + double cx = all_bounds.min_lat + ((all_bounds.max_lat - all_bounds.min_lat) / 2); + double cy = all_bounds.min_lon + ((all_bounds.max_lon - all_bounds.min_lon) / 2); - gbfprintf(fout, "CenterLat=%0.8f\n", cx); - gbfprintf(fout, "CenterLong=%0.8f\n", cy); - } - else { - gbfprintf(fout, "CenterLong=10.52374295\n"); - gbfprintf(fout, "CenterLat=52.26474445\n"); - } + gbfprintf(fout, "CenterLat=%0.8f\n", cx); + gbfprintf(fout, "CenterLong=%0.8f\n", cy); + } else { + gbfprintf(fout, "CenterLong=10.52374295\n"); + gbfprintf(fout, "CenterLat=52.26474445\n"); + } } static void draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP color, const waypoint *wpt) { - symbol_ct++; - - gbfprintf(fout, "[Symbol %d]\n", symbol_ct); - gbfprintf(fout, "Typ=%d\n", typ); - gbfprintf(fout, "Group=%d\n", group_ct); - gbfprintf(fout, "Col=%d\n", color); - if (art >= 0) gbfprintf(fout, "Art=%d\n", art); - if (wpt) { - gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude); - gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude); - } + symbol_ct++; + + gbfprintf(fout, "[Symbol %d]\n", symbol_ct); + gbfprintf(fout, "Typ=%d\n", typ); + gbfprintf(fout, "Group=%d\n", group_ct); + gbfprintf(fout, "Col=%d\n", color); + if (art >= 0) { + gbfprintf(fout, "Art=%d\n", art); + } + if (wpt) { + gbfprintf(fout, "XKoord=%.8f\n", wpt->longitude); + gbfprintf(fout, "YKoord=%.8f\n", wpt->latitude); + } } /* the following code comes from first overlay module */ @@ -376,65 +392,74 @@ draw_symbol_basics(const OVL_SYMBOL_TYP typ, const int art, const OVL_COLOR_TYP static int get_direction(const waypoint *A, const waypoint *B) { - double lata, lona, latb, lonb; - double dist, dir; - int res; - - lata = RAD(A->latitude); - lona = RAD(A->longitude); - latb = RAD(B->latitude); - lonb = RAD(B->longitude); - - dist = gcdist(lata, lona, latb, lonb); - dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist))); - if (lonb < lona) dir = -dir; - res = (int) DEG(dir); - res = 360 - (res + 270); - if (res < 0) res += 360; - else if (res > 360) res -= 360.0; - - return res; + double lata, lona, latb, lonb; + double dist, dir; + int res; + + lata = RAD(A->latitude); + lona = RAD(A->longitude); + latb = RAD(B->latitude); + lonb = RAD(B->longitude); + + dist = gcdist(lata, lona, latb, lonb); + dir = acos((sin(latb) - sin(lata) * cos(dist)) / (cos(lata) * sin(dist))); + if (lonb < lona) { + dir = -dir; + } + res = (int) DEG(dir); + res = 360 - (res + 270); + if (res < 0) { + res += 360; + } else if (res > 360) { + res -= 360.0; + } + + return res; } #if 0 static void draw_symbol_text(const char *text, const waypoint *reference) { - waypoint wpt; - - if ((reference == NULL) || (text == NULL)) return; - if (*text == '\0') return; - - wpt = *reference; - - wpt.latitude = wpt.latitude + 0.015; - wpt.longitude = wpt.longitude + 0.015; - - draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt); - - gbfprintf(fout, "Area=1\n"); - gbfprintf(fout, "Zoom=1\n"); - gbfprintf(fout, "Size=120\n"); - gbfprintf(fout, "Font=3\n"); - gbfprintf(fout, "Dir=100\n"); - gbfprintf(fout, "Text=%s\n", text); + waypoint wpt; + + if ((reference == NULL) || (text == NULL)) { + return; + } + if (*text == '\0') { + return; + } + + wpt = *reference; + + wpt.latitude = wpt.latitude + 0.015; + wpt.longitude = wpt.longitude + 0.015; + + draw_symbol_basics(OVL_SYMBOL_TEXT, -1, OVL_COLOR_BLACK, &wpt); + + gbfprintf(fout, "Area=1\n"); + gbfprintf(fout, "Zoom=1\n"); + gbfprintf(fout, "Size=120\n"); + gbfprintf(fout, "Font=3\n"); + gbfprintf(fout, "Dir=100\n"); + gbfprintf(fout, "Text=%s\n", text); } #endif /**************************************************************************/ ff_vecs_t ggv_ovl_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - ggv_ovl_rd_init, - ggv_ovl_wr_init, - ggv_ovl_rd_deinit, - ggv_ovl_wr_deinit, - ggv_ovl_read, - ggv_ovl_write, - NULL, - ggv_ovl_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, + ggv_ovl_rd_init, + ggv_ovl_wr_init, + ggv_ovl_rd_deinit, + ggv_ovl_wr_deinit, + ggv_ovl_read, + ggv_ovl_write, + NULL, + ggv_ovl_args, + CET_CHARSET_MS_ANSI, 0 }; /**************************************************************************/ diff --git a/gpsbabel/globals.c b/gpsbabel/globals.c index 3891a45e7..f3580071a 100644 --- a/gpsbabel/globals.c +++ b/gpsbabel/globals.c @@ -1,6 +1,6 @@ /* Global data for GPSBabel. - + Copyright (C) 2005 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify diff --git a/gpsbabel/glogbook.c b/gpsbabel/glogbook.c index 8a8d738c2..e85df40e4 100644 --- a/gpsbabel/glogbook.c +++ b/gpsbabel/glogbook.c @@ -31,7 +31,7 @@ static route_head *trk_head; static arglist_t glogbook_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Tracks */ @@ -44,139 +44,139 @@ static xg_callback gl_trk_long; static xg_callback gl_trk_alt; static xg_tag_mapping gl_map[] = { - { gl_trk_s, cb_start, "/History/Run/Track" }, - { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, - { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, - { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, - { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, - { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, - { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, - { NULL, 0, NULL} + { gl_trk_s, cb_start, "/History/Run/Track" }, + { gl_trk_pnt_s,cb_start, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_pnt_e,cb_end, "/History/Run/Track/Trackpoint/Position" }, + { gl_trk_lat, cb_cdata, "/History/Run/Track/Trackpoint/Position/Latitude" }, + { gl_trk_long, cb_cdata, "/History/Run/Track/Trackpoint/Position/Longitude" }, + { gl_trk_alt, cb_cdata, "/History/Run/Track/Trackpoint/Position/Altitude" }, + { gl_trk_utc, cb_cdata, "/History/Run/Track/Trackpoint/Time" }, + { NULL, 0, NULL} }; static void glogbook_rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void glogbook_read(void) { - xml_read(); + xml_read(); } static void glogbook_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void glogbook_wr_init(const char *fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void glogbook_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void glogbook_waypt_pr(const waypoint *wpt) -{ - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " %.5f\n", wpt->latitude); - gbfprintf(ofd, " %.5f\n", wpt->longitude); - if (wpt->altitude != unknown_alt) { - gbfprintf(ofd, " %.3f\n", wpt->altitude); - } - gbfprintf(ofd, " \n"); - gbfprintf(ofd, " "); - xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); - gbfprintf(ofd, " \n"); +{ + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " %.5f\n", wpt->latitude); + gbfprintf(ofd, " %.5f\n", wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(ofd, " %.3f\n", wpt->altitude); + } + gbfprintf(ofd, " \n"); + gbfprintf(ofd, " "); + xml_write_time(ofd, wpt->creation_time, wpt->microseconds, "Time"); + gbfprintf(ofd, " \n"); } static void -glogbook_hdr( const route_head *rte) +glogbook_hdr(const route_head *rte) { - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void glogbook_ftr(const route_head *rte) { - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); } static void glogbook_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, " \n"); - track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); - gbfprintf(ofd, " \n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, " \n"); + track_disp_all(glogbook_hdr, glogbook_ftr, glogbook_waypt_pr); + gbfprintf(ofd, " \n"); + gbfprintf(ofd, "\n"); } void gl_trk_s(const char *args, const char **unused) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head = route_head_alloc(); + track_add_head(trk_head); } #if 0 void gl_trk_ident(const char *args, const char **unused) { - trk_head->rte_name = xstrdup(args); + trk_head->rte_name = xstrdup(args); } #endif void gl_trk_pnt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } void gl_trk_pnt_e(const char *args, const char **unused) { - track_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } void gl_trk_utc(const char *args, const char **unused) { - wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); } void gl_trk_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } void gl_trk_long(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } void gl_trk_alt(const char *args, const char **unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } ff_vecs_t glogbook_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none}, - glogbook_rd_init, - glogbook_wr_init, - glogbook_rd_deinit, - glogbook_wr_deinit, - glogbook_read, - glogbook_write, - NULL, - glogbook_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none}, + glogbook_rd_init, + glogbook_wr_init, + glogbook_rd_deinit, + glogbook_wr_deinit, + glogbook_read, + glogbook_write, + NULL, + glogbook_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/gnav_trl.c b/gpsbabel/gnav_trl.c index fdcaeccac..fcc121b6f 100644 --- a/gpsbabel/gnav_trl.c +++ b/gpsbabel/gnav_trl.c @@ -27,14 +27,14 @@ static arglist_t gnav_trl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; typedef struct gnav_trl_s { - gbuint32 time; - float lat; - float lon; - gbuint32 alt; + gbuint32 time; + float lat; + float lon; + gbuint32 alt; } gnav_trl_t; static gbfile *fin, *fout; @@ -46,113 +46,115 @@ static gbfile *fin, *fout; static void gnav_trl_rd_init(const char *fname) { - fin = gbfopen_le(fname, "rb", MYNAME); + fin = gbfopen_le(fname, "rb", MYNAME); } static void gnav_trl_rw_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); + fout = gbfopen_le(fname, "wb", MYNAME); } static void gnav_trl_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void gnav_trl_rw_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static double read_altitude(void *ptr) { - unsigned char *i = (unsigned char *) ptr; - char buf[sizeof(float)]; - le_write32(&buf, i[2] << 24 | i[1] << 16 | i[0] <<8 | i[3]); - return le_read_float(&buf); + unsigned char *i = (unsigned char *) ptr; + char buf[sizeof(float)]; + le_write32(&buf, i[2] << 24 | i[1] << 16 | i[0] <<8 | i[3]); + return le_read_float(&buf); } static void write_altitude(void *ptr, const float alt) { - char buf[sizeof(float)]; - unsigned char *i = (unsigned char *) &buf; - le_write_float(&buf, alt); - le_write32(ptr, i[0] << 24 | i[3] << 16 | i[2] << 8 | i[1]); + char buf[sizeof(float)]; + unsigned char *i = (unsigned char *) &buf; + le_write_float(&buf, alt); + le_write32(ptr, i[0] << 24 | i[3] << 16 | i[2] << 8 | i[1]); } static void gnav_trl_read(void) { - route_head *trk = NULL; + route_head *trk = NULL; - while (! gbfeof(fin)) { - gnav_trl_t rec; - waypoint *wpt; + while (! gbfeof(fin)) { + gnav_trl_t rec; + waypoint *wpt; - if (gbfread(&rec, sizeof(rec), 1, fin) != 1) - fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + if (gbfread(&rec, sizeof(rec), 1, fin) != 1) { + fatal(MYNAME ": Unexpected EOF (end of file)!\n"); + } - wpt = waypt_new(); + wpt = waypt_new(); - wpt->creation_time = le_read32(&rec.time); - wpt->latitude = le_read_float(&rec.lat); - wpt->longitude = le_read_float(&rec.lon); - wpt->altitude = read_altitude(&rec.alt); + wpt->creation_time = le_read32(&rec.time); + wpt->latitude = le_read_float(&rec.lat); + wpt->longitude = le_read_float(&rec.lon); + wpt->altitude = read_altitude(&rec.alt); - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void gnav_trl_write_trkpt(const waypoint *wpt) { - gnav_trl_t rec; - - le_write32(&rec.time, wpt->creation_time); - le_write_float(&rec.lat, wpt->latitude); - le_write_float(&rec.lon, wpt->longitude); - if (wpt->altitude != unknown_alt) - write_altitude(&rec.alt, wpt->altitude); - else - write_altitude(&rec.alt, 0); - - gbfwrite(&rec, sizeof(rec), 1, fout); + gnav_trl_t rec; + + le_write32(&rec.time, wpt->creation_time); + le_write_float(&rec.lat, wpt->latitude); + le_write_float(&rec.lon, wpt->longitude); + if (wpt->altitude != unknown_alt) { + write_altitude(&rec.alt, wpt->altitude); + } else { + write_altitude(&rec.alt, 0); + } + + gbfwrite(&rec, sizeof(rec), 1, fout); } static void gnav_trl_write(void) { - track_disp_all(NULL, NULL, gnav_trl_write_trkpt); + track_disp_all(NULL, NULL, gnav_trl_write_trkpt); } /**************************************************************************/ ff_vecs_t gnav_trl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gnav_trl_rd_init, - gnav_trl_rw_init, - gnav_trl_rd_deinit, - gnav_trl_rw_deinit, - gnav_trl_read, - gnav_trl_write, - NULL, - gnav_trl_args, - CET_CHARSET_UTF8, 1 /* CET - do nothing ! */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + gnav_trl_rd_init, + gnav_trl_rw_init, + gnav_trl_rd_deinit, + gnav_trl_rw_deinit, + gnav_trl_read, + gnav_trl_write, + NULL, + gnav_trl_args, + CET_CHARSET_UTF8, 1 /* CET - do nothing ! */ }; diff --git a/gpsbabel/google.c b/gpsbabel/google.c index 889405696..f0a012179 100644 --- a/gpsbabel/google.c +++ b/gpsbabel/google.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -35,7 +35,7 @@ static int serial = 0; static void google_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded Google Maps support because expat was not installed.\n"); } static void @@ -48,66 +48,54 @@ static xg_callback goog_points, goog_levels, goog_poly_e, goog_script; static xg_callback goog_segment_s, goog_segment, goog_td_s, goog_td_b; static xg_callback goog_td_e; -static +static xg_tag_mapping google_map[] = { - { goog_points, cb_cdata, "/page/directions/polyline/points" }, - { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, - { goog_poly_e, cb_end, "/page/directions/polyline" }, - { goog_script, cb_cdata, "/html/head/script" }, - { goog_segment_s, cb_start, "/page/directions/segments/segment" }, - { goog_segment, cb_cdata, "/page/directions/segments/segment" }, - { goog_td_s, cb_start, "/div/table/tr/td" }, - { goog_td_s, cb_start, "/div/div/table/tr/td" }, - { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, - { goog_td_b, cb_cdata, "/div/div/table/tr/td/b" }, - { goog_td_e, cb_end, "/div/table/tr/td" }, - { goog_td_e, cb_end, "/div/div/table/tr/td" }, - { NULL, 0, NULL } + { goog_points, cb_cdata, "/page/directions/polyline/points" }, + { goog_levels, cb_cdata, "/page/directions/polyline/levels" }, + { goog_poly_e, cb_end, "/page/directions/polyline" }, + { goog_script, cb_cdata, "/html/head/script" }, + { goog_segment_s, cb_start, "/page/directions/segments/segment" }, + { goog_segment, cb_cdata, "/page/directions/segments/segment" }, + { goog_td_s, cb_start, "/div/table/tr/td" }, + { goog_td_s, cb_start, "/div/div/table/tr/td" }, + { goog_td_b, cb_cdata, "/div/table/tr/td/b" }, + { goog_td_b, cb_cdata, "/div/div/table/tr/td/b" }, + { goog_td_e, cb_end, "/div/table/tr/td" }, + { goog_td_e, cb_end, "/div/div/table/tr/td" }, + { NULL, 0, NULL } }; -void goog_script( const char *args, const char **unused ) +void goog_script(const char *args, const char **unused) { - if (args) - { - if ( script ) - { - script = xstrappend( script, args ); - } - else - { - script = xstrdup( args ); - } - } -} - -void goog_points( const char *args, const char **unused ) + if (args) { + if (script) { + script = xstrappend(script, args); + } else { + script = xstrdup(args); + } + } +} + +void goog_points(const char *args, const char **unused) { - if (args) - { - if ( encoded_points ) - { - encoded_points = xstrappend( encoded_points, args ); - } - else - { - encoded_points = xstrdup(args); - } - } + if (args) { + if (encoded_points) { + encoded_points = xstrappend(encoded_points, args); + } else { + encoded_points = xstrdup(args); + } + } } -void goog_levels( const char *args, const char **unused ) +void goog_levels(const char *args, const char **unused) { - if (args) - { - if ( encoded_levels ) - { - encoded_levels = xstrappend( encoded_levels, args ); - } - else - { - encoded_levels = xstrdup(args); - } - } + if (args) { + if (encoded_levels) { + encoded_levels = xstrappend(encoded_levels, args); + } else { + encoded_levels = xstrdup(args); + } + } } static char goog_segname[7]; @@ -118,445 +106,421 @@ static int goog_segroute = 0; * The segments contain an index into the points array. We use that * index to find the waypoint and insert a better name for it. */ -void goog_segment_s( const char *args, const char **attrv ) +void goog_segment_s(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "pointIndex")) { - snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); - } - avp += 2; - } + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "pointIndex")) { + snprintf(goog_segname, sizeof(goog_segname), "\\%5.5x", atoi(avp[1])); + } + avp += 2; + } } -void goog_segment( const char *args, const char **unused ) +void goog_segment(const char *args, const char **unused) { - waypoint *wpt_tmp; - - wpt_tmp = route_find_waypt_by_name( routehead[goog_segroute], goog_segname); - if (wpt_tmp) { - xfree(wpt_tmp->shortname); - wpt_tmp->shortname = mkshort(desc_handle,args); - wpt_tmp->description = xstrdup(args); - } + waypoint *wpt_tmp; + + wpt_tmp = route_find_waypt_by_name(routehead[goog_segroute], goog_segname); + if (wpt_tmp) { + xfree(wpt_tmp->shortname); + wpt_tmp->shortname = mkshort(desc_handle,args); + wpt_tmp->description = xstrdup(args); + } } -void goog_td_s( const char *args, const char **attrv ) +void goog_td_s(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - int isdesc = 0; - int isseg = 0; - while (*avp) { - if ( 0 == strcmp(avp[0], "class" )) { - isdesc = !strcmp(avp[1], "desc" ); - isseg = !strcmp(avp[1], "dirsegtext" ); - } - else if ( isdesc && (0 == strcmp( avp[0], "id" ))) { - goog_segroute = 0; - snprintf( goog_segname, sizeof(goog_segname), - "\\%5.5x", - atoi(avp[1] + 6 )); - } - else if ( isseg && (0 == strcmp( avp[0], "id" ))) { - if ( strchr(strchr(avp[1],'_')+1,'_')) { - goog_segroute = atoi(strchr(avp[1],'_')+1); - } - else { - goog_segroute = 0; - } - snprintf( goog_segname, sizeof(goog_segname), - "\\%5.5x", - atoi(strrchr( avp[1],'_') + 1 )+routecount[goog_segroute]); - } - avp += 2; - } + const char **avp = &attrv[0]; + int isdesc = 0; + int isseg = 0; + while (*avp) { + if (0 == strcmp(avp[0], "class")) { + isdesc = !strcmp(avp[1], "desc"); + isseg = !strcmp(avp[1], "dirsegtext"); + } else if (isdesc && (0 == strcmp(avp[0], "id"))) { + goog_segroute = 0; + snprintf(goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(avp[1] + 6)); + } else if (isseg && (0 == strcmp(avp[0], "id"))) { + if (strchr(strchr(avp[1],'_')+1,'_')) { + goog_segroute = atoi(strchr(avp[1],'_')+1); + } else { + goog_segroute = 0; + } + snprintf(goog_segname, sizeof(goog_segname), + "\\%5.5x", + atoi(strrchr(avp[1],'_') + 1)+routecount[goog_segroute]); + } + avp += 2; + } } - -void goog_td_b( const char *args, const char **attrv ) { - if ( goog_segname[0] == '\\' && !strchr( args, '\xa0')) { - if ( goog_realname ) { - xfree( goog_realname ); - goog_realname = NULL; - } - goog_realname = xmalloc( strlen(args)+1); - strcpy( goog_realname, args ); - } + +void goog_td_b(const char *args, const char **attrv) +{ + if (goog_segname[0] == '\\' && !strchr(args, '\xa0')) { + if (goog_realname) { + xfree(goog_realname); + goog_realname = NULL; + } + goog_realname = xmalloc(strlen(args)+1); + strcpy(goog_realname, args); + } } -void goog_td_e( const char *args, const char **attrv ) +void goog_td_e(const char *args, const char **attrv) { - if ( goog_segname[0] == '\\' && goog_realname ) { - goog_segment( goog_realname, attrv ); - } - goog_segname[0] = '\0'; - if ( goog_realname ) { - xfree( goog_realname ); - goog_realname = NULL; - } + if (goog_segname[0] == '\\' && goog_realname) { + goog_segment(goog_realname, attrv); + } + goog_segname[0] = '\0'; + if (goog_realname) { + xfree(goog_realname); + goog_realname = NULL; + } } -static long decode_goog64( char **str ) +static long decode_goog64(char **str) { - long result = 0; - unsigned char c = 0; - unsigned char shift = 0; - - if ( !(**str)) { - return 0; - } - - do - { - c = (unsigned char)(*(*str)++)-'?'; - result |= (c & 31)<latitude = lat / 100000.0; - wpt_tmp->longitude = lon / 100000.0; - wpt_tmp->route_priority=level; - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); - route_add_wpt(routehead[goog_segroute], wpt_tmp); - } - } - + long lat = 0; + long lon = 0; + long level = 0; + long level1 = -9999; + long level2 = -9999; + char *str = encoded_points; + char *lstr = encoded_levels; + + routehead[goog_segroute] = route_head_alloc(); + route_add_head(routehead[goog_segroute]); + routecount[goog_segroute] = serial; + + while (str && *str) { + lat += decode_goog64(&str); + lon += decode_goog64(&str); + + level = -1; + level2 = level1; + if (lstr && *lstr) { + level1 = -decode_goog64(&lstr); + } else { + level1 = -9999; + } + level = (level1latitude = lat / 100000.0; + wpt_tmp->longitude = lon / 100000.0; + wpt_tmp->route_priority=level; + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5x", serial++); + route_add_wpt(routehead[goog_segroute], wpt_tmp); + } + } + } static void google_rd_init(const char *fname) { - desc_handle = mkshort_new_handle(); - setshort_length(desc_handle, 12); + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 12); - xml_init(fname, google_map, "ISO-8859-1" ); + xml_init(fname, google_map, "ISO-8859-1"); } static void google_read(void) { - routehead = (route_head **)xmalloc(sizeof(route_head *)); - routecount = (int *)xmalloc(sizeof(int)); - goog_segroute = 0; - xml_read(); - xfree( routehead ); - xfree( routecount ); - - if ( encoded_points ) - { - xfree( encoded_points ); - encoded_points = NULL; - } - if ( encoded_levels ) - { - xfree( encoded_levels ); - encoded_levels = NULL; - } - if ( script ) - { - char *xml = strchr( script, '\'' ); - char *dict = strstr( script, "({" ); - - char *end = NULL; - - if ( xml && (!dict || (xml < dict ))) { - routehead = (route_head **)xmalloc(sizeof(route_head *)); - routecount = (int *)xmalloc(sizeof(int)); - goog_segroute = 0; - xml++; - end = strchr( xml+1, '\'' ); - if ( end ) { - *end = '\0'; - xml_deinit(); - xml_init( NULL, google_map, NULL ); - xml_readstring( xml ); - if ( encoded_points ) - { - xfree( encoded_points ); - encoded_points = NULL; - } - if ( encoded_levels ) - { - xfree( encoded_levels ); - encoded_levels = NULL; - } - } - } - else if ( dict ) { - char qc = '\''; - int ofs = 9; - int panelofs = 8; - int count = 0; - char *tmp = NULL; - char *start = NULL; - - char *panel = strstr( dict, "panel: '" ); - encoded_points = strstr( dict, "points: '" ); - encoded_levels = strstr( dict, "levels: '" ); - if ( !encoded_points ) { - ofs = 10; - qc = '"'; - encoded_points = strstr( dict, "\"points\":\"" ); - encoded_levels = strstr( dict, "\"levels\":\"" ); - if ( !encoded_points ) { - encoded_points = strstr(dict, "points:\"" ); - encoded_levels = strstr(dict, "levels:\"" ); - ofs = 8; - } - } - - if ( !panel ) { - panel = strstr( dict, "panel:\""); - panelofs = 7; - } - tmp = panel; - while ( tmp ) { - if ( qc == '"' ) { - char *tmp1 = strstr( tmp, "\"points\":\"" ); - if ( !tmp1 ) { - tmp1 = strstr( tmp, "points:\"" ); - } - tmp = tmp1; - } - else { - tmp = strstr( tmp, "points: '" ); - } - count++; - if ( tmp ) { - tmp++; - } - } - routehead = (route_head **)xmalloc(sizeof(route_head *)*count); - routecount = (int *)xmalloc(sizeof(int)*count); - goog_segroute = 0; - - do { - - if ( encoded_points && encoded_levels ) { - encoded_points += ofs; - encoded_levels += ofs; - end = strchr( encoded_points, qc ); - if ( end ) { - *end = '\0'; - end = encoded_points; - while ( (end = strstr(end, "\\\\" ))) { - memmove( end, end+1, strlen(end)+1 ); - end++; - } - end = strchr( encoded_levels, qc ); - if ( end ) { - start = end; - *end = '\0'; - end = encoded_levels; - while ( (end = strstr(end, "\\\\" ))) { - memmove( end, end+1, strlen(end)+1 ); - end++; - } - goog_poly_e( NULL, NULL ); - - goog_segroute++; - start++; - { - encoded_points = strstr( start, "points: '" ); - encoded_levels = strstr( start, "levels: '" ); - } - if ( !encoded_points ) { - encoded_points = strstr( start, "\"points\":\"" ); - encoded_levels = strstr( start, "\"levels\":\"" ); - } - if ( !encoded_points ) { - encoded_points = strstr( start, "points:\"" ); - encoded_levels = strstr( start, "levels:\"" ); - } - } - } - } - } while ( start && encoded_points && encoded_levels ); - if ( panel ) { - panel += panelofs; - end = strstr( panel, "/table>
"); - } - if ( !end ) { - end = strstr( panel, "/div>
"); - } - } - if ( end ) { - char *to = panel; - char *from = panel; - while ( *from ) { - if ( !strncmp( from, "\\\"", 2 )) { - *to++ = '"'; - from += 2; - if ( *(to-2) != '=' ) { - *to++ = ' '; - } - } - else if ( !strncmp( from, "\\042", 4)) { - *to++ = '"'; - from += 4; - - if ( *(to-2) != '=' ) { - *to++ = ' '; - } - } - else if ( !strncmp( from, "\\u0026utm", 9)) { - strcpy( to, "&utm" ); - to += 8; - from += 9; - } - else if ( !strncmp( from, "\\u0026", 6 )) { - *to++='&'; - from += 6; - } - else if ( !strncmp( from, "\\u003c", 6 )) { - *to++='<'; - from += 6; - } - else if ( !strncmp( from, "\\u003e", 6 )) { - *to++='>'; - from += 6; - } - else if ( !strncmp( from, "\\x", 2)) { - unsigned int c; - sscanf(from+2, "%2x", &c); - *to++ = (char)c; - from += 4; - } - else if ( !strncmp( from, "\\'", 2)) { - *to++ = '\''; - from += 2; - } - else if ( !strncmp( from, " nowrap ", 8)) { - *to++ = ' '; - from += 8; - } - else if ( !strncmp( from, "tr style=\\\"display:none", 23 )) { - if ( strcmp( to-5, "/tr><" )) { - /* broken 6-26-07 missing that apparently doesn't bother browsers */ - strcpy(to, "/tr><" ); - to += 5; - } - *to++ = *from++; - } - else { - *to++ = *from++; - } - } - *to = '\0'; - -#if 0 - { - FILE *foo = fopen( "foo.xml", "w" ); - fprintf(foo, "\n", xhtml_entities ); - fwrite( panel, sizeof(char), strlen(panel), foo ); - fclose( foo ); - } + routehead = (route_head **)xmalloc(sizeof(route_head *)); + routecount = (int *)xmalloc(sizeof(int)); + goog_segroute = 0; + xml_read(); + xfree(routehead); + xfree(routecount); + + if (encoded_points) { + xfree(encoded_points); + encoded_points = NULL; + } + if (encoded_levels) { + xfree(encoded_levels); + encoded_levels = NULL; + } + if (script) { + char *xml = strchr(script, '\''); + char *dict = strstr(script, "({"); + + char *end = NULL; + + if (xml && (!dict || (xml < dict))) { + routehead = (route_head **)xmalloc(sizeof(route_head *)); + routecount = (int *)xmalloc(sizeof(int)); + goog_segroute = 0; + xml++; + end = strchr(xml+1, '\''); + if (end) { + *end = '\0'; + xml_deinit(); + xml_init(NULL, google_map, NULL); + xml_readstring(xml); + if (encoded_points) { + xfree(encoded_points); + encoded_points = NULL; + } + if (encoded_levels) { + xfree(encoded_levels); + encoded_levels = NULL; + } + } + } else if (dict) { + char qc = '\''; + int ofs = 9; + int panelofs = 8; + int count = 0; + char *tmp = NULL; + char *start = NULL; + + char *panel = strstr(dict, "panel: '"); + encoded_points = strstr(dict, "points: '"); + encoded_levels = strstr(dict, "levels: '"); + if (!encoded_points) { + ofs = 10; + qc = '"'; + encoded_points = strstr(dict, "\"points\":\""); + encoded_levels = strstr(dict, "\"levels\":\""); + if (!encoded_points) { + encoded_points = strstr(dict, "points:\""); + encoded_levels = strstr(dict, "levels:\""); + ofs = 8; + } + } + + if (!panel) { + panel = strstr(dict, "panel:\""); + panelofs = 7; + } + tmp = panel; + while (tmp) { + if (qc == '"') { + char *tmp1 = strstr(tmp, "\"points\":\""); + if (!tmp1) { + tmp1 = strstr(tmp, "points:\""); + } + tmp = tmp1; + } else { + tmp = strstr(tmp, "points: '"); + } + count++; + if (tmp) { + tmp++; + } + } + routehead = (route_head **)xmalloc(sizeof(route_head *)*count); + routecount = (int *)xmalloc(sizeof(int)*count); + goog_segroute = 0; + + do { + + if (encoded_points && encoded_levels) { + encoded_points += ofs; + encoded_levels += ofs; + end = strchr(encoded_points, qc); + if (end) { + *end = '\0'; + end = encoded_points; + while ((end = strstr(end, "\\\\"))) { + memmove(end, end+1, strlen(end)+1); + end++; + } + end = strchr(encoded_levels, qc); + if (end) { + start = end; + *end = '\0'; + end = encoded_levels; + while ((end = strstr(end, "\\\\"))) { + memmove(end, end+1, strlen(end)+1); + end++; + } + goog_poly_e(NULL, NULL); + + goog_segroute++; + start++; + { + encoded_points = strstr(start, "points: '"); + encoded_levels = strstr(start, "levels: '"); + } + if (!encoded_points) { + encoded_points = strstr(start, "\"points\":\""); + encoded_levels = strstr(start, "\"levels\":\""); + } + if (!encoded_points) { + encoded_points = strstr(start, "points:\""); + encoded_levels = strstr(start, "levels:\""); + } + } + } + } + } while (start && encoded_points && encoded_levels); + if (panel) { + panel += panelofs; + end = strstr(panel, "/table>
"); + } + if (!end) { + end = strstr(panel, "/div>
"); + } + } + if (end) { + char *to = panel; + char *from = panel; + while (*from) { + if (!strncmp(from, "\\\"", 2)) { + *to++ = '"'; + from += 2; + if (*(to-2) != '=') { + *to++ = ' '; + } + } else if (!strncmp(from, "\\042", 4)) { + *to++ = '"'; + from += 4; + + if (*(to-2) != '=') { + *to++ = ' '; + } + } else if (!strncmp(from, "\\u0026utm", 9)) { + strcpy(to, "&utm"); + to += 8; + from += 9; + } else if (!strncmp(from, "\\u0026", 6)) { + *to++='&'; + from += 6; + } else if (!strncmp(from, "\\u003c", 6)) { + *to++='<'; + from += 6; + } else if (!strncmp(from, "\\u003e", 6)) { + *to++='>'; + from += 6; + } else if (!strncmp(from, "\\x", 2)) { + unsigned int c; + sscanf(from+2, "%2x", &c); + *to++ = (char)c; + from += 4; + } else if (!strncmp(from, "\\'", 2)) { + *to++ = '\''; + from += 2; + } else if (!strncmp(from, " nowrap ", 8)) { + *to++ = ' '; + from += 8; + } else if (!strncmp(from, "tr style=\\\"display:none", 23)) { + if (strcmp(to-5, "/tr><")) { + /* broken 6-26-07 missing that apparently doesn't bother browsers */ + strcpy(to, "/tr><"); + to += 5; + } + *to++ = *from++; + } else { + *to++ = *from++; + } + } + *to = '\0'; + +#if 0 + { + FILE *foo = fopen("foo.xml", "w"); + fprintf(foo, "\n", xhtml_entities); + fwrite(panel, sizeof(char), strlen(panel), foo); + fclose(foo); + } #endif - xml_deinit(); - xml_init( NULL, google_map, NULL ); - xml_readprefixstring( "" ); - xml_readstring( panel ); - } - } - } - xfree( script ); - xfree( routehead ); - xfree( routecount ); - script = NULL; - } - - /* - * 'Tis better to leak than crash when we are merging and - * don't see an 'end' in the first file. This feels a bit - * like plastering over a deeper problem... - * - */ - if ( encoded_points ) { - encoded_points = NULL; - } - if ( encoded_levels ) { - encoded_levels = NULL; - } + xml_deinit(); + xml_init(NULL, google_map, NULL); + xml_readprefixstring(""); + xml_readstring(panel); + } + } + } + xfree(script); + xfree(routehead); + xfree(routecount); + script = NULL; + } + + /* + * 'Tis better to leak than crash when we are merging and + * don't see an 'end' in the first file. This feels a bit + * like plastering over a deeper problem... + * + */ + if (encoded_points) { + encoded_points = NULL; + } + if (encoded_levels) { + encoded_levels = NULL; + } } #endif static void google_rd_deinit(void) { - xml_deinit(); - mkshort_del_handle(&desc_handle); + xml_deinit(); + mkshort_del_handle(&desc_handle); } ff_vecs_t google_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none}, - google_rd_init, - NULL, - google_rd_deinit, - NULL, - google_read, - NULL, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none}, + google_rd_init, + NULL, + google_rd_deinit, + NULL, + google_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/gopal.c b/gpsbabel/gopal.c index 8b7ff716c..5a767442e 100644 --- a/gpsbabel/gopal.c +++ b/gpsbabel/gopal.c @@ -21,25 +21,25 @@ ===================================================================================== - This file allows gpsbabel to read and write the internal track log format used by - GoPal navigation systems. They produce a simple line-oriented format with one point per + This file allows gpsbabel to read and write the internal track log format used by + GoPal navigation systems. They produce a simple line-oriented format with one point per second. Unfortunately the the data does not contain a valid date, only some kind of timetick, together with each point (perhaps by mistake ??). So we have to parse the filename for a valid starting - date and add the timeoffset. Second problem (at least to me) was that irregularly stupid errors were - in the data, i.e. only one data point shows a totally wrong longitude or latitude. Everything else in + date and add the timeoffset. Second problem (at least to me) was that irregularly stupid errors were + in the data, i.e. only one data point shows a totally wrong longitude or latitude. Everything else in the dataset seems ok, so I needed a way to sort out these errors. My solution is to calculate the speed between successive points and drop points not between minspeed and maxspeed. This way I can sort out most - of this annoying bugs, a side effect is that if a minimum speed > 0 is set points with the same coodinates are also + of this annoying bugs, a side effect is that if a minimum speed > 0 is set points with the same coodinates are also dropped. Fileformat GoPal TICK; TIME UTC; LONG; LAT; HEIGHT; SPEED km/h; FIX; HDOP; SAT - 3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + 3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 Filenames: trackYYYYMMDD_HHMMSS.trk A_YYYYMMDD_HHMMSS.trk with HHMMSS local time (not UTC) - + History 2008-07-18 initial release of Version 0.1 2008-07-26 bugfix: filenamehandling linux, format specification in write statement @@ -71,25 +71,24 @@ static double minspeed,maxspeed; static struct tm opt_tm; /* converted "date" parameter */ static arglist_t gopal_args[] = { - {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"maxspeed", &optmaxspeed, "The maximum speed (km/h) traveling from waypoint to waypoint.", "200", ARGTYPE_INT, "1", "1000" }, - {"minspeed", &optminspeed, "The minimum speed (km/h) traveling from waypoint to waypoint. Set >0 to remove duplicate waypoints", "0", ARGTYPE_INT, "0", "999" }, - {"clean", &optclean, "Cleanup common errors in trackdata", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"maxspeed", &optmaxspeed, "The maximum speed (km/h) traveling from waypoint to waypoint.", "200", ARGTYPE_INT, "1", "1000" }, + {"minspeed", &optminspeed, "The minimum speed (km/h) traveling from waypoint to waypoint. Set >0 to remove duplicate waypoints", "0", ARGTYPE_INT, "0", "999" }, + {"clean", &optclean, "Cleanup common errors in trackdata", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL int gopal_check_line(char *line) { - char *c = line; - int i = 0; - while ((c = strchr(c, ','))) - { - c++; - i++; - } - return i; + char *c = line; + int i = 0; + while ((c = strchr(c, ','))) { + c++; + i++; + } + return i; } @@ -100,239 +99,246 @@ int gopal_check_line(char *line) static void gopal_rd_init(const char *fname) -{char buff[32]; - char *ck; - char *filename; - CHECK_BOOL(optclean); - if (optminspeed) - { - minspeed=atof(optminspeed); - if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal minspeed = %s\n",optminspeed); - } - else - minspeed=0; - if (optmaxspeed) - { - maxspeed=atof(optmaxspeed); - if (global_opts.debug_level > 1) fprintf(stderr,"options from command line : gopal maxspeed = %s\n",optmaxspeed); - } - else - maxspeed=200; - if (global_opts.debug_level > 1) fprintf(stderr,"setting minspeed to %5.1lf km/h and maxspeed to %5.1lf km/h\n",minspeed,maxspeed); - - fin = gbfopen(fname, "r", MYNAME); - - memset(buff,0,sizeof(buff)); - if (optdate) - { - memset(&opt_tm, 0, sizeof(opt_tm)); - - ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); - if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) - fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); - else if (opt_tm.tm_year < 70) - fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); - tx = mkgmtime(&opt_tm); - - } - else - { - /* remove path */ - filename = get_filename(fname); - - if ((strncmp(filename,"track",5)==0)&&(strlen(filename)>13)) // we need at least 13 letters: trackYYYYMMDD... - { - strncpy(&buff[0],&filename[5],8); - } - else - if ((strncmp(filename,"A_",2)==0)&&(strlen(filename)>10))// here we expect at least 10 letters: A_YYYYMMDD... - { - strncpy(&buff[0],&filename[2],8); - } - // in buff we should now have something wich looks like a valid date starting with YYYYMMDD - ck = (char *)strptime(buff, "%Y%m%d", &filenamedate); - // if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) - // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); - // /* else */ if (filenamedate.tm_year < 70) - // fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); - // tx= mkgmtime(&filenamedate); - } +{ + char buff[32]; + char *ck; + char *filename; + CHECK_BOOL(optclean); + if (optminspeed) { + minspeed=atof(optminspeed); + if (global_opts.debug_level > 1) { + fprintf(stderr,"options from command line : gopal minspeed = %s\n",optminspeed); + } + } else { + minspeed=0; + } + if (optmaxspeed) { + maxspeed=atof(optmaxspeed); + if (global_opts.debug_level > 1) { + fprintf(stderr,"options from command line : gopal maxspeed = %s\n",optmaxspeed); + } + } else { + maxspeed=200; + } + if (global_opts.debug_level > 1) { + fprintf(stderr,"setting minspeed to %5.1lf km/h and maxspeed to %5.1lf km/h\n",minspeed,maxspeed); + } + + fin = gbfopen(fname, "r", MYNAME); + + memset(buff,0,sizeof(buff)); + if (optdate) { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) { + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + } else if (opt_tm.tm_year < 70) { + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } + tx = mkgmtime(&opt_tm); + + } else { + /* remove path */ + filename = get_filename(fname); + + if ((strncmp(filename,"track",5)==0)&&(strlen(filename)>13)) { // we need at least 13 letters: trackYYYYMMDD... + strncpy(&buff[0],&filename[5],8); + } else if ((strncmp(filename,"A_",2)==0)&&(strlen(filename)>10)) { // here we expect at least 10 letters: A_YYYYMMDD... + strncpy(&buff[0],&filename[2],8); + } + // in buff we should now have something wich looks like a valid date starting with YYYYMMDD + ck = (char *)strptime(buff, "%Y%m%d", &filenamedate); + // if (((ck == NULL) || (*ck != '\0') )&&!(optdate)) + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + // /* else */ if (filenamedate.tm_year < 70) + // fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", buff); + // tx= mkgmtime(&filenamedate); + } } -static void +static void gopal_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void gopal_read(void) { - char *buff; - char *str, *c; - int column; - long line; - double hmsd,speed; - int fix, hms; - route_head *route; - waypoint *wpt, *lastwpt=NULL; - double long_old,lat_old; - char tbuffer[64]; - struct tm tm2; - long_old=0;lat_old=0; - strftime(routename,sizeof(routename),"Tracklog %c",gmtime(&tx)); - - route = route_head_alloc(); - route->rte_name=xstrdup(routename); - route_add_head(route); - - line=0; - while ((buff = gbfgetstr(fin))) - { - int nfields; - unsigned long microsecs; - if ((line == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - str = buff = lrtrim(buff); - if (*buff == '\0') continue; - nfields = gopal_check_line(buff); - if ((nfields != 8) && (nfields != 11))continue; - // Old format. Hassle for date. - if ((nfields == 8) && (tx == 0)) { - // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); - } - wpt = waypt_new(); - - column = -1; - // the format of gopal is quite simple. Unfortunately the developers forgot the date as the first element... - //TICK; TIME; LONG; LAT; HEIGHT; SPEED; Fix; HDOP; SAT - //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 - c = csv_lineparse(str, ",", "", column++); - while (c != NULL) - { - switch(column) - { - case 0: /* "-" */ /* unknown fields for the moment */ - sscanf(c, "%lu", µsecs); - wpt->microseconds += microsecs % 1000000; - wpt->creation_time += microsecs / 1000000; - break; - case 1: /* Time UTC */ - sscanf(c,"%lf",&hmsd); - hms = (int) hmsd; - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - tm.tm_year=trackdate.tm_year; - tm.tm_mon=trackdate.tm_mon; - tm.tm_mday=trackdate.tm_mday; - wpt->creation_time = tx+((((time_t)tm.tm_hour * 60) + tm.tm_min) * 60) + tm.tm_sec; - if (global_opts.debug_level > 1){ - strftime(tbuffer, sizeof(tbuffer), "%c", gmtime(&wpt->creation_time)); - printf("parsed timestamp: %s\n",tbuffer); - } - break; - - case 2: /* longitude */ - sscanf(c, "%lf", &wpt->longitude); - break; - - case 3: /* latitude */ - sscanf(c, "%lf", &wpt->latitude); - break; - case 4: /* altitude */ - sscanf(c, "%lf", &wpt->altitude); - break; - case 5: /* speed */ - //sscanf(c, "%lf", &wpt->speed); - wpt->speed=atof(c); - if (global_opts.debug_level > 1){ - printf("parsed speed: %8.5f\n",wpt->speed); - } - break; - case 6: /* type of fix */ - sscanf(c, "%d", &fix); - //my device shows only 0 or 2 - //should i guess from no of sats if 2d or 3d? - switch (fix) { - case 0: wpt->fix = fix_none;break; - case 2: wpt->fix = fix_2d;break; - //case 3: wpt->fix = fix_3d;break; - //case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ - //case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ - default: - wpt->fix = fix_unknown; - break; - } - break; - case 7: /* hdop */ - wpt->hdop = atof(c); - //sscanf(c, "%lf", &wpt->hdop); does not work ??? - //wpt->vdop=0;wpt->hdop=0; - break; - case 8: /* number of sats */ - sscanf(c, "%d", &wpt->sat); - break; - // Somewhere around mid/late 2009, these files started - // seeing 11 fields. - case 9: - memset(&tm2, 0, sizeof(tm2)); - if (!strptime(c, "%Y%m%d", &tm2)) { - fatal ("Bad date '%s'.\n", c); - } - wpt->creation_time += mkgmtime(&tm2); - break; - case 10: // Unknown. Ignored. - case 11: // Bearing. Ignored. - break; - } - c = csv_lineparse(NULL, ",", "", column++); - } - line++; - - if ((wpt->fix != fix_none)&&(lat_old==0)){ //first-time init - lat_old=wpt->latitude; - long_old=wpt->longitude; - //route_add_wpt(route, wpt); - lastwpt=wpt; - } - //calculate the speed to reach this waypoint from the last. This way I try to sort out invalid waypoints - speed=0; - if (lastwpt !=NULL) - { - speed=3.6*radtometers(gcdist(RAD(lastwpt->latitude), RAD(lastwpt->longitude), RAD(wpt->latitude), RAD(wpt->longitude))) / abs(wpt->creation_time - lastwpt->creation_time); - //printf("speed line %d %lf \n",line,speed); - } - /* Error handling: in the tracklog of my device sometimes "jump" waypoints ;-) */ - if ((optclean) && - (((wpt->longitude==0.0)|| (wpt->latitude==0.0)||(abs(wpt->latitude)>90)||(abs(wpt->longitude)>180))|| - ((speed>maxspeed)||(speed 1) fprintf(stderr,"Problem in or around line %5lu: \"%s\" %lf km/h\n",line,buff,speed); - } - else - { - if (global_opts.debug_level > 1) fprintf(stderr,"valid line %5lu: \"%s\" %lf km/h\n",line,buff,speed); - lastwpt=wpt; - long_old=wpt->longitude; - lat_old=wpt->latitude; - route_add_wpt(route,wpt); - waypt_add(waypt_dupe( wpt)); - } - } + char *buff; + char *str, *c; + int column; + long line; + double hmsd,speed; + int fix, hms; + route_head *route; + waypoint *wpt, *lastwpt=NULL; + double long_old,lat_old; + char tbuffer[64]; + struct tm tm2; + long_old=0; + lat_old=0; + strftime(routename,sizeof(routename),"Tracklog %c",gmtime(&tx)); + + route = route_head_alloc(); + route->rte_name=xstrdup(routename); + route_add_head(route); + + line=0; + while ((buff = gbfgetstr(fin))) { + int nfields; + unsigned long microsecs; + if ((line == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + str = buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + nfields = gopal_check_line(buff); + if ((nfields != 8) && (nfields != 11)) { + continue; + } + // Old format. Hassle for date. + if ((nfields == 8) && (tx == 0)) { + // fatal(MYNAME ": Invalid date in filename \"%s\", try to set manually using \"date\" switch!\n", buff); + } + wpt = waypt_new(); + + column = -1; + // the format of gopal is quite simple. Unfortunately the developers forgot the date as the first element... + //TICK; TIME; LONG; LAT; HEIGHT; SPEED; Fix; HDOP; SAT + //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + c = csv_lineparse(str, ",", "", column++); + while (c != NULL) { + switch (column) { + case 0: /* "-" */ /* unknown fields for the moment */ + sscanf(c, "%lu", µsecs); + wpt->microseconds += microsecs % 1000000; + wpt->creation_time += microsecs / 1000000; + break; + case 1: /* Time UTC */ + sscanf(c,"%lf",&hmsd); + hms = (int) hmsd; + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + tm.tm_year=trackdate.tm_year; + tm.tm_mon=trackdate.tm_mon; + tm.tm_mday=trackdate.tm_mday; + wpt->creation_time = tx+((((time_t)tm.tm_hour * 60) + tm.tm_min) * 60) + tm.tm_sec; + if (global_opts.debug_level > 1) { + strftime(tbuffer, sizeof(tbuffer), "%c", gmtime(&wpt->creation_time)); + printf("parsed timestamp: %s\n",tbuffer); + } + break; + + case 2: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 3: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + case 4: /* altitude */ + sscanf(c, "%lf", &wpt->altitude); + break; + case 5: /* speed */ + //sscanf(c, "%lf", &wpt->speed); + wpt->speed=atof(c); + if (global_opts.debug_level > 1) { + printf("parsed speed: %8.5f\n",wpt->speed); + } + break; + case 6: /* type of fix */ + sscanf(c, "%d", &fix); + //my device shows only 0 or 2 + //should i guess from no of sats if 2d or 3d? + switch (fix) { + case 0: + wpt->fix = fix_none; + break; + case 2: + wpt->fix = fix_2d; + break; + //case 3: wpt->fix = fix_3d;break; + //case 4: wpt->fix = fix_dgps;break; /* 2D_diff */ + //case 5: wpt->fix = fix_dgps;break; /* 3D_diff */ + default: + wpt->fix = fix_unknown; + break; + } + break; + case 7: /* hdop */ + wpt->hdop = atof(c); + //sscanf(c, "%lf", &wpt->hdop); does not work ??? + //wpt->vdop=0;wpt->hdop=0; + break; + case 8: /* number of sats */ + sscanf(c, "%d", &wpt->sat); + break; + // Somewhere around mid/late 2009, these files started + // seeing 11 fields. + case 9: + memset(&tm2, 0, sizeof(tm2)); + if (!strptime(c, "%Y%m%d", &tm2)) { + fatal("Bad date '%s'.\n", c); + } + wpt->creation_time += mkgmtime(&tm2); + break; + case 10: // Unknown. Ignored. + case 11: // Bearing. Ignored. + break; + } + c = csv_lineparse(NULL, ",", "", column++); + } + line++; + + if ((wpt->fix != fix_none)&&(lat_old==0)) { //first-time init + lat_old=wpt->latitude; + long_old=wpt->longitude; + //route_add_wpt(route, wpt); + lastwpt=wpt; + } + //calculate the speed to reach this waypoint from the last. This way I try to sort out invalid waypoints + speed=0; + if (lastwpt !=NULL) { + speed=3.6*radtometers(gcdist(RAD(lastwpt->latitude), RAD(lastwpt->longitude), RAD(wpt->latitude), RAD(wpt->longitude))) / abs(wpt->creation_time - lastwpt->creation_time); + //printf("speed line %d %lf \n",line,speed); + } + /* Error handling: in the tracklog of my device sometimes "jump" waypoints ;-) */ + if ((optclean) && + (((wpt->longitude==0.0)|| (wpt->latitude==0.0)||(abs(wpt->latitude)>90)||(abs(wpt->longitude)>180))|| + ((speed>maxspeed)||(speed 1) { + fprintf(stderr,"Problem in or around line %5lu: \"%s\" %lf km/h\n",line,buff,speed); + } + } else { + if (global_opts.debug_level > 1) { + fprintf(stderr,"valid line %5lu: \"%s\" %lf km/h\n",line,buff,speed); + } + lastwpt=wpt; + long_old=wpt->longitude; + lat_old=wpt->latitude; + route_add_wpt(route,wpt); + waypt_add(waypt_dupe(wpt)); + } + } } -static void +static void gopal_route_hdr(const route_head *route) { - + } -static void +static void gopal_route_tlr(const route_head *rte) { } @@ -340,43 +346,48 @@ gopal_route_tlr(const route_head *rte) static void gopal_write_waypt(const waypoint *wpt) { - char tbuffer[64]; - unsigned long timestamp; - int fix=fix_unknown; - //TICK; TIME; LONG; LAT; HEIGHT; SPEED; UN; HDOP; SAT - //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 - strftime(tbuffer, sizeof(tbuffer), "%H%M%S", gmtime(&wpt->creation_time)); - if (wpt->fix!=fix_unknown) { - switch (wpt->fix) - { - case fix_none: fix = 0; break; - case fix_2d: fix = 2; break; - default: fix = 0; break; - } - } - //MSVC handles time_t as int64, gcc and mac only int32, so convert it: - timestamp=(unsigned long)wpt->creation_time; - gbfprintf(fout, "%lu, %s, %lf, %lf, %5.1lf, %8.5lf, %d, %lf, %d\n",timestamp,tbuffer, wpt->longitude, wpt->latitude,wpt->altitude, - wpt->speed,fix,wpt->hdop,wpt->sat); + char tbuffer[64]; + unsigned long timestamp; + int fix=fix_unknown; + //TICK; TIME; LONG; LAT; HEIGHT; SPEED; UN; HDOP; SAT + //3801444, 080558, 2.944362, 43.262117, 295.28, 0.12964, 2, 2.900000, 3 + strftime(tbuffer, sizeof(tbuffer), "%H%M%S", gmtime(&wpt->creation_time)); + if (wpt->fix!=fix_unknown) { + switch (wpt->fix) { + case fix_none: + fix = 0; + break; + case fix_2d: + fix = 2; + break; + default: + fix = 0; + break; + } + } + //MSVC handles time_t as int64, gcc and mac only int32, so convert it: + timestamp=(unsigned long)wpt->creation_time; + gbfprintf(fout, "%lu, %s, %lf, %lf, %5.1lf, %8.5lf, %d, %lf, %d\n",timestamp,tbuffer, wpt->longitude, wpt->latitude,wpt->altitude, + wpt->speed,fix,wpt->hdop,wpt->sat); } static void gopal_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void gopal_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void gopal_write(void) { - route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); + route_disp_all(gopal_route_hdr, gopal_route_tlr, gopal_write_waypt); } static void @@ -387,24 +398,24 @@ gopal_exit(void) /* optional */ /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// +// ff_vecs_t gopal_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gopal_rd_init, - gopal_wr_init, - gopal_rd_deinit, - gopal_wr_deinit, - gopal_read, - gopal_write, - gopal_exit, - gopal_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + gopal_rd_init, + gopal_wr_init, + gopal_rd_deinit, + gopal_wr_deinit, + gopal_read, + gopal_write, + gopal_exit, + gopal_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/gpilots.c b/gpsbabel/gpilots.c index fc567c471..932d31a90 100644 --- a/gpsbabel/gpilots.c +++ b/gpsbabel/gpilots.c @@ -34,119 +34,111 @@ /* * Structures grafted from http://www.cru.fr/perso/cc/GPilotS/ */ - -typedef struct -{ - long lat; /* latitude in semicircles */ - long lon; /* longitude in semicircles */ + +typedef struct { + long lat; /* latitude in semicircles */ + long lon; /* longitude in semicircles */ } Semicircle_Type; -typedef struct -{ - char ident[6]; /* identifier */ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char unused[4]; /* should be set to zero */ - char cmnt[40]; /* comment */ - unsigned char smbl; /* symbol id */ - unsigned char dspl; /* display option */ +typedef struct { + char ident[6]; /* identifier */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char unused[4]; /* should be set to zero */ + char cmnt[40]; /* comment */ + unsigned char smbl; /* symbol id */ + unsigned char dspl; /* display option */ } D103_Wpt_Type; typedef union { - float f; - unsigned int i; + float f; + unsigned int i; } fi_t; -typedef struct /* size */ -{ - unsigned char wpt_class; /* class (see below) 1 */ - unsigned char color; /* color (see below) 1 */ - unsigned char dspl; /* display options (see below) 1 */ - unsigned char attr; /* attributes (see below) 1 */ - unsigned char smbl[2]; /* waypoint symbol 2 */ - unsigned char subclass[18]; /* subclass 18 */ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - float alt; /* altitude in meters 4 */ - float dpth; /* depth in meters 4 */ - float dist; /* proximity distance in meters 4 */ - char state[2]; /* state 2 */ - char cc[2]; /* country code 2 */ - char varlenstrs[1]; /* start of variable length strings */ - /* G_char ident[]; variable length string 1-51 */ - /* G_char comment[]; waypoint user comment 1-51 */ - /* G_char facility[]; facility name 1-31 */ - /* G_char city[]; city name 1-25 */ - /* G_char addr[]; address number 1-51 */ - /* G_char cross_road[]; intersecting road label 1-51 */ +typedef struct { /* size */ + unsigned char wpt_class; /* class (see below) 1 */ + unsigned char color; /* color (see below) 1 */ + unsigned char dspl; /* display options (see below) 1 */ + unsigned char attr; /* attributes (see below) 1 */ + unsigned char smbl[2]; /* waypoint symbol 2 */ + unsigned char subclass[18]; /* subclass 18 */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + float alt; /* altitude in meters 4 */ + float dpth; /* depth in meters 4 */ + float dist; /* proximity distance in meters 4 */ + char state[2]; /* state 2 */ + char cc[2]; /* country code 2 */ + char varlenstrs[1]; /* start of variable length strings */ + /* G_char ident[]; variable length string 1-51 */ + /* G_char comment[]; waypoint user comment 1-51 */ + /* G_char facility[]; facility name 1-31 */ + /* G_char city[]; city name 1-25 */ + /* G_char addr[]; address number 1-51 */ + /* G_char cross_road[]; intersecting road label 1-51 */ } D108_Wpt_Type; -typedef struct /* structure de waypoint "interne" */ -{ - unsigned char ident[51]; /* identifier (50 + '0') */ - Semicircle_Type posn; /* position (common to all Garmin types) */ - unsigned char cmnt[51]; /* comment (50 + '0') */ - float dst; /* proximity distance */ - float alt; /* altitude */ - int smbl; /* symbol id */ - unsigned char dspl; /* display option */ - unsigned char color; /* color */ +typedef struct { /* structure de waypoint "interne" */ + unsigned char ident[51]; /* identifier (50 + '0') */ + Semicircle_Type posn; /* position (common to all Garmin types) */ + unsigned char cmnt[51]; /* comment (50 + '0') */ + float dst; /* proximity distance */ + float alt; /* altitude */ + int smbl; /* symbol id */ + unsigned char dspl; /* display option */ + unsigned char color; /* color */ } Custom_Wpt_Type; -typedef struct /* internal track header */ -{ - char name[256]; /* nom du groupe de trackpoints */ - unsigned char dspl; /* display on the map ? */ - unsigned char color; /* color */ - unsigned char type; /* type of following track points */ - unsigned char unused; /* type of following track points */ - unsigned char number[2]; /* number of track points */ - unsigned char latmin[4]; /* latitude min */ - unsigned char latmax[4]; /* latitude max */ - unsigned char lonmin[4]; /* longitude min */ - unsigned char lonmax[4]; /* longitude max */ - unsigned char unused2[2]; /* type of following track points */ +typedef struct { /* internal track header */ + char name[256]; /* nom du groupe de trackpoints */ + unsigned char dspl; /* display on the map ? */ + unsigned char color; /* color */ + unsigned char type; /* type of following track points */ + unsigned char unused; /* type of following track points */ + unsigned char number[2]; /* number of track points */ + unsigned char latmin[4]; /* latitude min */ + unsigned char latmax[4]; /* latitude max */ + unsigned char lonmin[4]; /* longitude min */ + unsigned char lonmax[4]; /* longitude max */ + unsigned char unused2[2]; /* type of following track points */ } Custom_Trk_Hdr_Type; -typedef struct -{ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char time[4]; - unsigned char alt[4]; - unsigned char new_trk; - unsigned char unused; +typedef struct { + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char time[4]; + unsigned char alt[4]; + unsigned char new_trk; + unsigned char unused; } Custom_Trk_Point_Type; -typedef struct /* custom compact track point type */ -{ - unsigned char lat[4]; /* position */ - unsigned char lon[4]; /* position */ - unsigned char new_trk; - unsigned char unused; +typedef struct { /* custom compact track point type */ + unsigned char lat[4]; /* position */ + unsigned char lon[4]; /* position */ + unsigned char new_trk; + unsigned char unused; } Compact_Trk_Point_Type; /* size : 10 bytes */ -struct record -{ - struct { - unsigned char type; - unsigned short size; - unsigned int version; - } header; - union { - D103_Wpt_Type d103; - D108_Wpt_Type d108; - Custom_Wpt_Type CustWpt; - Custom_Trk_Hdr_Type CustTrkHdr; +struct record { + struct { + unsigned char type; + unsigned short size; + unsigned int version; + } header; + union { + D103_Wpt_Type d103; + D108_Wpt_Type d108; + Custom_Wpt_Type CustWpt; + Custom_Trk_Hdr_Type CustTrkHdr; #if LATER - Custom_Rte_Hdr_Type CustRteHdr; + Custom_Rte_Hdr_Type CustRteHdr; #endif - } wpt; + } wpt; }; @@ -157,287 +149,287 @@ static char *dbname = NULL; static arglist_t my_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - route_head *track_head = NULL; - - if (file_in->creator != MYCREATOR) { - fatal(MYNAME ": Not a %s file.\n", MYNAME); - } - - switch(file_in->type) { - case MYWPT: - /* blah */ - break; - case MYTRK: - /* blah */ - break; - default: - fatal(MYNAME ": Unknown file type 0x%x\n", (int) file_in->type); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt_tmp; - Custom_Trk_Point_Type *tp_cust; - Compact_Trk_Point_Type *tp_comp; - int lat; - int lon; - int sz; - fi_t fi; - int trk_num = 0; - int trk_seg_num = 1; - char trk_seg_num_buf[10]; - char *trk_name = ""; - - wpt_tmp = waypt_new(); - - rec = (struct record *) pdb_rec->data; - switch(rec->header.type) { - /* - * G103Type - */ - case 4: - wpt_tmp->shortname = xstrndupt(rec->wpt.d103.ident, sizeof(rec->wpt.d103.ident)); - wpt_tmp->description = xstrndupt(rec->wpt.d103.cmnt, sizeof(rec->wpt.d103.cmnt)); - /* This is odd. This is a Palm DB file, - * yet the data appears to be little endian, - * not appropriate the the actual Palm. - */ - lon = le_read32(&rec->wpt.d103.lon); - lat = le_read32(&rec->wpt.d103.lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - waypt_add(wpt_tmp); - break; - /* - * G108Type - */ - case 9: - wpt_tmp->shortname = xstrndupt(rec->wpt.d108.varlenstrs, 50); - wpt_tmp->description = xstrndupt(rec->wpt.d108.varlenstrs + strlen(wpt_tmp->shortname) + 1, 50); - /* This is odd. This is a Palm DB file, - * yet the data appears to be little endian, - * not appropriate the the actual Palm. - */ - lon = le_read32(&rec->wpt.d108.lon); - lat = le_read32(&rec->wpt.d108.lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - fi.i = le_read32(&rec->wpt.d108.alt); - wpt_tmp->altitude = fi.f; - fi.i = le_read32(&rec->wpt.d108.dpth); - WAYPT_SET(wpt_tmp, depth, fi.f); - fi.i = le_read32(&rec->wpt.d108.dist); - WAYPT_SET(wpt_tmp, proximity, fi.f); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; - wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); - waypt_add(wpt_tmp); - break; - - /* - * CustomTrkHdr - */ - case 101: - trk_name = rec->wpt.CustTrkHdr.name; - sz = be_read16(&rec->wpt.CustTrkHdr.number); - - /* switch between custom track points and compact track points. - * (compact points have no altitude and time info. - */ - switch (rec->wpt.CustTrkHdr.type) { - case 102: - tp_cust = (Custom_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); - while (sz--) { - if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) { - /* - * Start a new track segment - */ - track_head = route_head_alloc(); - if (trk_seg_num == 1) { - track_head->rte_name = xstrdup(trk_name); - } else { - /* name in the form TRACKNAME #n */ - snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); - track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); - sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); - } - trk_seg_num++; - track_head->rte_num = trk_num; - trk_num++; - track_add_head(track_head); - } - - wpt_tmp = waypt_new(); - - /* This is even more odd. - * Track data is stored as big endian while - * waypoint data is little endian!? - */ - lon = be_read32(&tp_cust->lon); - lat = be_read32(&tp_cust->lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - /* - * Convert Garmin/GPilotS time format to gpsbabel time format. - * Garmin/GPilotS count seconds from "UTC 12:00 AM December 31 1989". - * gpsbabel counts seconds from "UTC 12:00 AM January 1 1970". - */ - wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; - fi.i = be_read32(&tp_cust->alt); - wpt_tmp->altitude = fi.f; - track_add_wpt(track_head, wpt_tmp); - tp_cust++; - } - break; - case 104: - tp_comp = (Compact_Trk_Point_Type *) ((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); - while (sz--) { - if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) { - /* - * Start a new track segment - */ - track_head = route_head_alloc(); - if (trk_seg_num == 1) { - track_head->rte_name = xstrdup(trk_name); - } else { - /* name in the form TRACKNAME #n */ - snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); - track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); - sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); - } - trk_seg_num++; - track_head->rte_num = trk_num; - trk_num++; - track_add_head(track_head); - } - - wpt_tmp = waypt_new(); - lon = be_read32(&tp_comp->lon); - lat = be_read32(&tp_comp->lat); - wpt_tmp->longitude = lon / 2147483648.0 * 180.0; - wpt_tmp->latitude = lat / 2147483648.0 * 180.0; - track_add_wpt(track_head, wpt_tmp); - tp_comp++; - } - break; - default: - fatal(MYNAME ": track point type %d not supported.\n", rec->wpt.CustTrkHdr.type); - } - break; - default: - fatal(MYNAME ": input record type %d not supported.\n", rec->header.type); - } - - } + struct record *rec; + pdbrec_t *pdb_rec; + route_head *track_head = NULL; + + if (file_in->creator != MYCREATOR) { + fatal(MYNAME ": Not a %s file.\n", MYNAME); + } + + switch (file_in->type) { + case MYWPT: + /* blah */ + break; + case MYTRK: + /* blah */ + break; + default: + fatal(MYNAME ": Unknown file type 0x%x\n", (int) file_in->type); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt_tmp; + Custom_Trk_Point_Type *tp_cust; + Compact_Trk_Point_Type *tp_comp; + int lat; + int lon; + int sz; + fi_t fi; + int trk_num = 0; + int trk_seg_num = 1; + char trk_seg_num_buf[10]; + char *trk_name = ""; + + wpt_tmp = waypt_new(); + + rec = (struct record *) pdb_rec->data; + switch (rec->header.type) { + /* + * G103Type + */ + case 4: + wpt_tmp->shortname = xstrndupt(rec->wpt.d103.ident, sizeof(rec->wpt.d103.ident)); + wpt_tmp->description = xstrndupt(rec->wpt.d103.cmnt, sizeof(rec->wpt.d103.cmnt)); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d103.lon); + lat = le_read32(&rec->wpt.d103.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + waypt_add(wpt_tmp); + break; + /* + * G108Type + */ + case 9: + wpt_tmp->shortname = xstrndupt(rec->wpt.d108.varlenstrs, 50); + wpt_tmp->description = xstrndupt(rec->wpt.d108.varlenstrs + strlen(wpt_tmp->shortname) + 1, 50); + /* This is odd. This is a Palm DB file, + * yet the data appears to be little endian, + * not appropriate the the actual Palm. + */ + lon = le_read32(&rec->wpt.d108.lon); + lat = le_read32(&rec->wpt.d108.lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + fi.i = le_read32(&rec->wpt.d108.alt); + wpt_tmp->altitude = fi.f; + fi.i = le_read32(&rec->wpt.d108.dpth); + WAYPT_SET(wpt_tmp, depth, fi.f); + fi.i = le_read32(&rec->wpt.d108.dist); + WAYPT_SET(wpt_tmp, proximity, fi.f); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 0; + wpt_tmp->icon_descr = gt_find_desc_from_icon_number((rec->wpt.d108.smbl[1] << 8) + rec->wpt.d108.smbl[0], PCX, NULL); + waypt_add(wpt_tmp); + break; + + /* + * CustomTrkHdr + */ + case 101: + trk_name = rec->wpt.CustTrkHdr.name; + sz = be_read16(&rec->wpt.CustTrkHdr.number); + + /* switch between custom track points and compact track points. + * (compact points have no altitude and time info. + */ + switch (rec->wpt.CustTrkHdr.type) { + case 102: + tp_cust = (Custom_Trk_Point_Type *)((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_cust->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + + /* This is even more odd. + * Track data is stored as big endian while + * waypoint data is little endian!? + */ + lon = be_read32(&tp_cust->lon); + lat = be_read32(&tp_cust->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + /* + * Convert Garmin/GPilotS time format to gpsbabel time format. + * Garmin/GPilotS count seconds from "UTC 12:00 AM December 31 1989". + * gpsbabel counts seconds from "UTC 12:00 AM January 1 1970". + */ + wpt_tmp->creation_time = be_read32(&tp_cust->time) + 631065600; + fi.i = be_read32(&tp_cust->alt); + wpt_tmp->altitude = fi.f; + track_add_wpt(track_head, wpt_tmp); + tp_cust++; + } + break; + case 104: + tp_comp = (Compact_Trk_Point_Type *)((char *) pdb_rec->data + sizeof(rec->header) + sizeof(rec->wpt.CustTrkHdr)); + while (sz--) { + if ((int)(tp_comp->new_trk) == 1 || trk_seg_num == 1) { + /* + * Start a new track segment + */ + track_head = route_head_alloc(); + if (trk_seg_num == 1) { + track_head->rte_name = xstrdup(trk_name); + } else { + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", trk_seg_num); + track_head->rte_name = xmalloc(strlen(trk_name)+strlen(trk_seg_num_buf)+3); + sprintf(track_head->rte_name, "%s #%s", trk_name, trk_seg_num_buf); + } + trk_seg_num++; + track_head->rte_num = trk_num; + trk_num++; + track_add_head(track_head); + } + + wpt_tmp = waypt_new(); + lon = be_read32(&tp_comp->lon); + lat = be_read32(&tp_comp->lat); + wpt_tmp->longitude = lon / 2147483648.0 * 180.0; + wpt_tmp->latitude = lat / 2147483648.0 * 180.0; + track_add_wpt(track_head, wpt_tmp); + tp_comp++; + } + break; + default: + fatal(MYNAME ": track point type %d not supported.\n", rec->wpt.CustTrkHdr.type); + } + break; + default: + fatal(MYNAME ": input record type %d not supported.\n", rec->header.type); + } + + } } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char *wpt_name; + waypoint *wpt; }; static void my_write_wpt(const waypoint *wpt) { - struct record *rec; - char *vdata; - int lat, lon; - - rec = xcalloc(sizeof *rec, 1); - vdata = (char *)rec + sizeof (*rec); - - rec->header.type = 4; - rec->header.size = 5; - rec->header.version = 6; - - strncpy(rec->wpt.d103.ident, wpt->shortname, sizeof(rec->wpt.d103.ident)); - strncpy(rec->wpt.d103.cmnt, wpt->description, sizeof(rec->wpt.d103.cmnt)); - lat = wpt->latitude / 180.0 * 2147483648.0; - lon = wpt->longitude / 180.0 * 2147483648.0; - le_write32(&rec->wpt.d103.lat, lat); - le_write32(&rec->wpt.d103.lon, lon); - - pdb_write_rec(file_out, 0, ct, ct+1, rec, (char *)vdata - (char *)rec); - ct++; - xfree(rec); + struct record *rec; + char *vdata; + int lat, lon; + + rec = xcalloc(sizeof *rec, 1); + vdata = (char *)rec + sizeof(*rec); + + rec->header.type = 4; + rec->header.size = 5; + rec->header.version = 6; + + strncpy(rec->wpt.d103.ident, wpt->shortname, sizeof(rec->wpt.d103.ident)); + strncpy(rec->wpt.d103.cmnt, wpt->description, sizeof(rec->wpt.d103.cmnt)); + lat = wpt->latitude / 180.0 * 2147483648.0; + lon = wpt->longitude / 180.0 * 2147483648.0; + le_write32(&rec->wpt.d103.lat, lat); + le_write32(&rec->wpt.d103.lon, lon); + + pdb_write_rec(file_out, 0, ct, ct+1, rec, (char *)vdata - (char *)rec); + ct++; + xfree(rec); } static void data_write(void) { - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - - /* - * Populate header. - */ - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - - file_out->type = MYWPT; - file_out->creator = MYCREATOR; - file_out->version = 1; - - waypt_disp_all(my_write_wpt); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + + /* + * Populate header. + */ + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + + file_out->type = MYWPT; + file_out->creator = MYCREATOR; + file_out->version = 1; + + waypt_disp_all(my_write_wpt); } ff_vecs_t gpilots_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none}, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - my_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + my_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gpspilot.c b/gpsbabel/gpspilot.c index 31ebf8dcc..4ab38c731 100644 --- a/gpsbabel/gpspilot.c +++ b/gpsbabel/gpspilot.c @@ -32,17 +32,17 @@ #define MYCREATOR 0x47704c69 /* GpLi */ struct record { - pdb_32 longitude; /* Big endian, long * 3.6e6 */ - pdb_32 latitude; /* similarly */ - pdb_16 elevation; /* meters */ - pdb_16 magvar; /* magnetic variation in degrees, neg = west */ + pdb_32 longitude; /* Big endian, long * 3.6e6 */ + pdb_32 latitude; /* similarly */ + pdb_16 elevation; /* meters */ + pdb_16 magvar; /* magnetic variation in degrees, neg = west */ }; struct runways { - pdb_32 be_longitude; /* Big endian, long * 3.6e6 */ - pdb_32 be_latitude; /* similarly */ - pdb_32 en_longitude; /* Big endian, long * 3.6e6 */ - pdb_32 en_latitude; /* similarly */ + pdb_32 be_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 be_latitude; /* similarly */ + pdb_32 en_longitude; /* Big endian, long * 3.6e6 */ + pdb_32 en_latitude; /* similarly */ }; static pdbfile *file_in, *file_out; @@ -52,189 +52,183 @@ static int ct; static arglist_t gpspilot_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - ct = 0; + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR)) { - fatal(MYNAME ": Not a gpspilot file.\n"); - } - - switch (file_in->type) - { - case MYTYPE_AIRPORT: - case MYTYPE_POINTS: - case MYTYPE_CITIES: - case MYTYPE_LNDMRKS: - case MYTYPE_NAVAIDS: - break; - default: - fatal(MYNAME ": Not a gpspilot file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata; - - wpt_tmp = waypt_new(); - - rec = (struct record *) pdb_rec->data; - wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; - wpt_tmp->latitude = be_read32(&rec->latitude) / 3.6e6; - wpt_tmp->altitude = - be_read16(&rec->elevation); - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - /* - * skip runway records if an airport. - */ - if (pdb_rec->category == 0) - { - int numRunways; - numRunways = be_read16(vdata); - vdata += 2; - vdata += (sizeof(struct runways) * numRunways); - } - - /* - * This maping is a bit contrived. - * Name is up to 36. ID is up to 9. - * Since 'ID' maps more clearly to "shortname" (and this - * more likely to be resemble a wayoint name in another - * receiver) we use that for shortname and use 'name' as - * our description. - */ - wpt_tmp->description = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->shortname = xstrdup(vdata); - vdata = vdata + strlen(vdata) + 1; - - wpt_tmp->notes = xstrdup(vdata); - - waypt_add(wpt_tmp); - - } + struct record *rec; + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR)) { + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + switch (file_in->type) { + case MYTYPE_AIRPORT: + case MYTYPE_POINTS: + case MYTYPE_CITIES: + case MYTYPE_LNDMRKS: + case MYTYPE_NAVAIDS: + break; + default: + fatal(MYNAME ": Not a gpspilot file.\n"); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata; + + wpt_tmp = waypt_new(); + + rec = (struct record *) pdb_rec->data; + wpt_tmp->longitude = be_read32(&rec->longitude) / 3.6e6; + wpt_tmp->latitude = be_read32(&rec->latitude) / 3.6e6; + wpt_tmp->altitude = + be_read16(&rec->elevation); + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + /* + * skip runway records if an airport. + */ + if (pdb_rec->category == 0) { + int numRunways; + numRunways = be_read16(vdata); + vdata += 2; + vdata += (sizeof(struct runways) * numRunways); + } + + /* + * This maping is a bit contrived. + * Name is up to 36. ID is up to 9. + * Since 'ID' maps more clearly to "shortname" (and this + * more likely to be resemble a wayoint name in another + * receiver) we use that for shortname and use 'name' as + * our description. + */ + wpt_tmp->description = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->shortname = xstrdup(vdata); + vdata = vdata + strlen(vdata) + 1; + + wpt_tmp->notes = xstrdup(vdata); + + waypt_add(wpt_tmp); + + } } static void gpspilot_writewpt(const waypoint *wpt) { - struct record *rec; - char *vdata; - - rec = xcalloc(sizeof(*rec)+206,1); - - be_write32(&rec->longitude, si_round(wpt->longitude * 3.6e6)); - be_write32(&rec->latitude, si_round(wpt->latitude * 3.6e6)); - be_write16(&rec->elevation, si_round(wpt->altitude)); - be_write16(&rec->magvar, 0 ); - - vdata = (char *)rec + sizeof(*rec); - if ( wpt->description ) { - strncpy( vdata, wpt->description, 36 ); - vdata[35] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->shortname ) { - strncpy( vdata, wpt->shortname, 9 ); - vdata[8] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - if ( wpt->notes ) { - strncpy( vdata, wpt->notes, 161 ); - vdata[160] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - - pdb_write_rec(file_out, 0, 2, ct++, (void *)rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record *rec; + char *vdata; + + rec = xcalloc(sizeof(*rec)+206,1); + + be_write32(&rec->longitude, si_round(wpt->longitude * 3.6e6)); + be_write32(&rec->latitude, si_round(wpt->latitude * 3.6e6)); + be_write16(&rec->elevation, si_round(wpt->altitude)); + be_write16(&rec->magvar, 0); + + vdata = (char *)rec + sizeof(*rec); + if (wpt->description) { + strncpy(vdata, wpt->description, 36); + vdata[35] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->shortname) { + strncpy(vdata, wpt->shortname, 9); + vdata[8] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + if (wpt->notes) { + strncpy(vdata, wpt->notes, 161); + vdata[160] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + + pdb_write_rec(file_out, 0, 2, ct++, (void *)rec, (char *)vdata - (char *)rec); + + xfree(rec); } static void data_write(void) { - if ( dbname ) { - strncpy(file_out->name, dbname, PDB_DBNAMELEN); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE_POINTS; - file_out->creator = MYCREATOR; - file_out->version = 0; - - waypt_disp_all(gpspilot_writewpt); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE_POINTS; + file_out->creator = MYCREATOR; + file_out->version = 0; + + waypt_disp_all(gpspilot_writewpt); } ff_vecs_t gpspilot_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - gpspilot_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + gpspilot_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/gpssim.c b/gpsbabel/gpssim.c index 8a0d3e6b4..7afd46060 100644 --- a/gpsbabel/gpssim.c +++ b/gpsbabel/gpssim.c @@ -1,6 +1,6 @@ /* Write points to Franson Technology GpsGate simulator - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #define MYNAME "gpssim" @@ -33,16 +33,20 @@ static int doing_tracks; static arglist_t gpssim_args[] = { - { "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", - NULL, ARGTYPE_FLOAT, ARG_NOMINMAX }, - { "split", &splitfiles_opt, "Split input into separate files", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "wayptspd", &wayptspd, "Default speed for waypoints (knots/hr)", + NULL, ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "split", &splitfiles_opt, "Split input into separate files", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* * The only thing kind of odd about this format is the "split" - * option. There's some trashing about with the 'splitfiles' toggle + * option. There's some trashing about with the 'splitfiles' toggle * to ensure that waypoints land in one file and each track and each * route land in files of their own. */ @@ -50,29 +54,29 @@ arglist_t gpssim_args[] = { static void gpssim_wr_init(const char *fname) { - fnamestr = xstrdup(fname); - trk_count = 0; - splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; - - /* If writing to stdout, never split files */ - if (0 == strcmp("-",splitfiles_opt)) { - splitfiles = 0; - } - - if (!splitfiles) { - fout = gbfopen(fname, "wb", MYNAME); - } + fnamestr = xstrdup(fname); + trk_count = 0; + splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0; + + /* If writing to stdout, never split files */ + if (0 == strcmp("-",splitfiles_opt)) { + splitfiles = 0; + } + + if (!splitfiles) { + fout = gbfopen(fname, "wb", MYNAME); + } } static void gpssim_wr_deinit(void) { - if (fout) { - gbfclose(fout); - fout = NULL; - } + if (fout) { + gbfclose(fout); + fout = NULL; + } - xfree(fnamestr); + xfree(fnamestr); } @@ -81,124 +85,124 @@ gpssim_wr_deinit(void) * in them explictly in case we're writing from a UNIX-like host. */ -static void +static void gpssim_write_sentence(const char *const s) { - gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); + gbfprintf(fout, "$%s*%02X\r\n", s, nmea_cksum(s)); } static void gpssim_write_spd(double knotsperhour) { - char obuf[1024]; + char obuf[1024]; - snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); - gpssim_write_sentence(obuf); + snprintf(obuf, sizeof(obuf), "FRSPD,%.2f", knotsperhour); + gpssim_write_sentence(obuf); } static void gpssim_write_pt(const waypoint *wpt) { - char obuf[1024]; - double lat, lon; - - if WAYPT_HAS(wpt, speed) { - gpssim_write_spd(MPS_TO_KNOTS(wpt->speed)); - } - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - - snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - wpt->altitude == unknown_alt ? 0 : wpt->altitude - ); - - if ( wpt->creation_time ) { - char tbuf[20]; - int hms, ymd; - struct tm *tm; - - tm = gmtime(&wpt->creation_time); - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; - ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; - snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); - strcat(obuf, tbuf); - } - - gpssim_write_sentence(obuf); + char obuf[1024]; + double lat, lon; + + if WAYPT_HAS(wpt, speed) { + gpssim_write_spd(MPS_TO_KNOTS(wpt->speed)); + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + snprintf(obuf, sizeof(obuf), "FRWPT,%10.5f,%c,%011.5f,%c,%.1f", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + wpt->altitude == unknown_alt ? 0 : wpt->altitude + ); + + if (wpt->creation_time) { + char tbuf[20]; + int hms, ymd; + struct tm *tm; + + tm = gmtime(&wpt->creation_time); + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + snprintf(tbuf, sizeof(tbuf), ",%d,%d",ymd, hms); + strcat(obuf, tbuf); + } + + gpssim_write_sentence(obuf); } static void gpssim_trk_hdr(const route_head *rh) { - if (splitfiles) { - char c[1024]; - char *ofname = xstrdup(fnamestr); - - if (fout) { - fatal(MYNAME ": output file already open.\n"); - } - - snprintf(c, sizeof(c), "%s%04d.gpssim", - doing_tracks ? "-track" : "-route", - trk_count++); - ofname = xstrappend(ofname, c); - fout = gbfopen(ofname, "wb", MYNAME); - xfree(ofname); - } - track_recompute(rh, NULL); + if (splitfiles) { + char c[1024]; + char *ofname = xstrdup(fnamestr); + + if (fout) { + fatal(MYNAME ": output file already open.\n"); + } + + snprintf(c, sizeof(c), "%s%04d.gpssim", + doing_tracks ? "-track" : "-route", + trk_count++); + ofname = xstrappend(ofname, c); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + track_recompute(rh, NULL); } static void gpssim_trk_ftr(const route_head *rh) { - if (splitfiles) { - gbfclose(fout); - fout = NULL; - } + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } } static void gpssim_write(void) { - if (waypt_count()) { - if (splitfiles) { - char *ofname = xstrdup(fnamestr); - ofname = xstrappend(ofname, "-waypoints.gpssim"); - fout = gbfopen(ofname, "wb", MYNAME); - xfree(ofname); - } - if (wayptspd && wayptspd[0]) { - gpssim_write_spd(atof(wayptspd)); - } - waypt_disp_all(gpssim_write_pt); - if (splitfiles) { - gbfclose(fout); - fout = NULL; - } - } - - doing_tracks = 1; - track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); - - trk_count = 0; - doing_tracks = 0; - route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + if (waypt_count()) { + if (splitfiles) { + char *ofname = xstrdup(fnamestr); + ofname = xstrappend(ofname, "-waypoints.gpssim"); + fout = gbfopen(ofname, "wb", MYNAME); + xfree(ofname); + } + if (wayptspd && wayptspd[0]) { + gpssim_write_spd(atof(wayptspd)); + } + waypt_disp_all(gpssim_write_pt); + if (splitfiles) { + gbfclose(fout); + fout = NULL; + } + } + + doing_tracks = 1; + track_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); + + trk_count = 0; + doing_tracks = 0; + route_disp_all(gpssim_trk_hdr, gpssim_trk_ftr, gpssim_write_pt); } ff_vecs_t gpssim_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_write, ff_cap_write }, - NULL, - gpssim_wr_init, - NULL, - gpssim_wr_deinit, - NULL, - gpssim_write, - NULL, - gpssim_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { ff_cap_write, ff_cap_write, ff_cap_write }, + NULL, + gpssim_wr_init, + NULL, + gpssim_wr_deinit, + NULL, + gpssim_write, + NULL, + gpssim_args, + CET_CHARSET_ASCII, 0 }; diff --git a/gpsbabel/gpsutil.c b/gpsbabel/gpsutil.c index 71e88dedc..8b9b1eca6 100644 --- a/gpsbabel/gpsutil.c +++ b/gpsbabel/gpsutil.c @@ -29,147 +29,154 @@ static short_handle mkshort_handle; static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - char *ibuf; - char desc[31]; - double lat,lon; - char latdir, londir; - int ilat, ilon; - long alt; - char alttype; - char icon[3]; - waypoint *wpt_tmp; - int line = 0; - /* - * Make sure that all waypoints in single read have same - * timestamp. - */ - time_t now = current_time(); - icon[0] = 0; - - while ((ibuf = gbfgetstr(file_in))) { - int n, len; - char *sn; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - /* A sharp in column zero or an blank line is a comment */ - ibuf = lrtrim(ibuf); - len = strlen(ibuf); - if ((len == 0) || (*ibuf == '#')) continue; - - if (len > 71) { - int offs = len - 71; - sn = xstrndup(ibuf, offs + 8); - ibuf += (offs + 9); - } - else { - sn = xstrndup(ibuf, 8); - ibuf += 9; - } - - n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,] %2s", - &lat, &latdir, &lon, &londir, - &alt, &alttype, desc, icon); - /* Require at least first threee fields, otherwise ignore */ - if (n < 2) { - xfree(sn); - continue; - } - rtrim(sn); - rtrim(desc); - rtrim(icon); - wpt_tmp = waypt_new(); - wpt_tmp->altitude = alt; - wpt_tmp->shortname = sn; - wpt_tmp->description = xstrdup(desc); - wpt_tmp->creation_time = now; - - if (latdir == 'S') lat = -lat; - if (londir == 'W') lon = -lon; - - lat /= 100.0; - lon /= 100.0; - ilon = (int)(lon); - wpt_tmp->longitude = ilon + (lon - ilon)*(100.0/60.0); - ilat = (int)(lat); - wpt_tmp->latitude = ilat + (lat - ilat) * (100.0/60.0); - wpt_tmp->icon_descr = mag_find_descr_from_token(icon); - waypt_add(wpt_tmp); - } + char *ibuf; + char desc[31]; + double lat,lon; + char latdir, londir; + int ilat, ilon; + long alt; + char alttype; + char icon[3]; + waypoint *wpt_tmp; + int line = 0; + /* + * Make sure that all waypoints in single read have same + * timestamp. + */ + time_t now = current_time(); + icon[0] = 0; + + while ((ibuf = gbfgetstr(file_in))) { + int n, len; + char *sn; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + /* A sharp in column zero or an blank line is a comment */ + ibuf = lrtrim(ibuf); + len = strlen(ibuf); + if ((len == 0) || (*ibuf == '#')) { + continue; + } + + if (len > 71) { + int offs = len - 71; + sn = xstrndup(ibuf, offs + 8); + ibuf += (offs + 9); + } else { + sn = xstrndup(ibuf, 8); + ibuf += 9; + } + + n = sscanf(ibuf, "%lf%c %lf%c %ld%c %30[^,] %2s", + &lat, &latdir, &lon, &londir, + &alt, &alttype, desc, icon); + /* Require at least first threee fields, otherwise ignore */ + if (n < 2) { + xfree(sn); + continue; + } + rtrim(sn); + rtrim(desc); + rtrim(icon); + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + wpt_tmp->shortname = sn; + wpt_tmp->description = xstrdup(desc); + wpt_tmp->creation_time = now; + + if (latdir == 'S') { + lat = -lat; + } + if (londir == 'W') { + lon = -lon; + } + + lat /= 100.0; + lon /= 100.0; + ilon = (int)(lon); + wpt_tmp->longitude = ilon + (lon - ilon)*(100.0/60.0); + ilat = (int)(lat); + wpt_tmp->latitude = ilat + (lat - ilat) * (100.0/60.0); + wpt_tmp->icon_descr = mag_find_descr_from_token(icon); + waypt_add(wpt_tmp); + } } static void gpsutil_disp(const waypoint *wpt) { - double lon,lat; - const char *icon_token; - char *tdesc = xstrdup(wpt->description); - - icon_token = mag_find_token_from_descr(wpt->icon_descr); - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", - global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname, - fabs(lat), - lat < 0.0 ? 'S' : 'N', - fabs(lon), - lon < 0.0 ? 'W' : 'E', - ((wpt->altitude == unknown_alt) || - (wpt->altitude < 0.0)) ? 0 : wpt->altitude, - 'm', - wpt->description ? tdesc : "", - icon_token); - - xfree(tdesc); + double lon,lat; + const char *icon_token; + char *tdesc = xstrdup(wpt->description); + + icon_token = mag_find_token_from_descr(wpt->icon_descr); + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + gbfprintf(file_out, "%-8.8s %08.3f%c %09.3f%c %07.0f%c %-30.30s %s\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + fabs(lat), + lat < 0.0 ? 'S' : 'N', + fabs(lon), + lon < 0.0 ? 'W' : 'E', + ((wpt->altitude == unknown_alt) || + (wpt->altitude < 0.0)) ? 0 : wpt->altitude, + 'm', + wpt->description ? tdesc : "", + icon_token); + + xfree(tdesc); } static void data_write(void) { - waypt_disp_all(gpsutil_disp); + waypt_disp_all(gpsutil_disp); } ff_vecs_t gpsutil_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/gpx.c b/gpsbabel/gpx.c index be5e5479e..a4cf441fe 100644 --- a/gpsbabel/gpx.c +++ b/gpsbabel/gpx.c @@ -25,8 +25,8 @@ #include "cet_util.h" #include "garmin_fs.h" #if HAVE_LIBEXPAT - #include - static XML_Parser psr; +#include +static XML_Parser psr; #endif static xml_tag *cur_tag; @@ -82,193 +82,194 @@ static format_specific_data **fs_ptr; #endif -/* +/* * Format used for floating point formats. Put in one place to make it - * easier to tweak when comparing output with other GPX programs that + * easier to tweak when comparing output with other GPX programs that * have more or less digits of output... */ /* #define FLT_FMT "%.9lf" */ /* ExpertGPS */ -#define FLT_FMT "%0.9lf" -#define FLT_FMT_T "%0.9lf" -#define FLT_FMT_R "%0.9lf" +#define FLT_FMT "%0.9lf" +#define FLT_FMT_T "%0.9lf" +#define FLT_FMT_R "%0.9lf" typedef enum { - tt_unknown = 0, - tt_gpx, - - tt_name, /* Optional file-level info */ - tt_desc, - tt_author, - tt_email, - tt_url, - tt_urlname, - tt_keywords, - - tt_wpt, - tt_wpt_cmt, - tt_wpt_desc, - tt_wpt_name, - tt_wpt_sym, - tt_wpt_url, - tt_wpt_ele, - tt_wpt_time, - tt_wpt_type, - tt_wpt_urlname, - tt_wpt_link, /* New in GPX 1.1 */ - tt_wpt_link_text, /* New in GPX 1.1 */ - tt_pdop, /* PDOPS are common for all three */ - tt_hdop, /* PDOPS are common for all three */ - tt_vdop, /* PDOPS are common for all three */ - tt_fix, - tt_sat, - tt_cache, - tt_cache_name, - tt_cache_container, - tt_cache_type, - tt_cache_difficulty, - tt_cache_terrain, - tt_cache_hint, - tt_cache_desc_short, - tt_cache_desc_long, - tt_cache_log_wpt, - tt_cache_log_type, - tt_cache_log_date, - tt_cache_placer, - - tt_wpt_extensions, - - tt_garmin_wpt_extensions, /* don't change this order */ - tt_garmin_wpt_proximity, - tt_garmin_wpt_temperature, - tt_garmin_wpt_depth, - tt_garmin_wpt_display_mode, - tt_garmin_wpt_categories, - tt_garmin_wpt_category, - tt_garmin_wpt_addr, - tt_garmin_wpt_city, - tt_garmin_wpt_state, - tt_garmin_wpt_country, - tt_garmin_wpt_postal_code, - tt_garmin_wpt_phone_nr, /* don't change this order */ - - tt_rte, - tt_rte_name, - tt_rte_desc, - tt_rte_cmt, - tt_rte_number, - tt_rte_rtept, - tt_rte_rtept_ele, - tt_rte_rtept_name, - tt_rte_rtept_desc, - tt_rte_rtept_sym, - tt_rte_rtept_time, - tt_rte_rtept_cmt, - tt_rte_rtept_url, - tt_rte_rtept_urlname, - tt_trk, - tt_trk_desc, - tt_trk_name, - tt_trk_trkseg, - tt_trk_number, - tt_trk_trkseg_trkpt, - tt_trk_trkseg_trkpt_cmt, - tt_trk_trkseg_trkpt_name, - tt_trk_trkseg_trkpt_sym, - tt_trk_trkseg_trkpt_url, - tt_trk_trkseg_trkpt_urlname, - tt_trk_trkseg_trkpt_desc, - tt_trk_trkseg_trkpt_ele, - tt_trk_trkseg_trkpt_time, - tt_trk_trkseg_trkpt_course, - tt_trk_trkseg_trkpt_speed, - tt_trk_trkseg_trkpt_heartrate, - tt_trk_trkseg_trkpt_cadence, - - tt_humminbird_wpt_depth, - tt_humminbird_wpt_status, - tt_humminbird_trk_trkseg_trkpt_depth, + tt_unknown = 0, + tt_gpx, + + tt_name, /* Optional file-level info */ + tt_desc, + tt_author, + tt_email, + tt_url, + tt_urlname, + tt_keywords, + + tt_wpt, + tt_wpt_cmt, + tt_wpt_desc, + tt_wpt_name, + tt_wpt_sym, + tt_wpt_url, + tt_wpt_ele, + tt_wpt_time, + tt_wpt_type, + tt_wpt_urlname, + tt_wpt_link, /* New in GPX 1.1 */ + tt_wpt_link_text, /* New in GPX 1.1 */ + tt_pdop, /* PDOPS are common for all three */ + tt_hdop, /* PDOPS are common for all three */ + tt_vdop, /* PDOPS are common for all three */ + tt_fix, + tt_sat, + tt_cache, + tt_cache_name, + tt_cache_container, + tt_cache_type, + tt_cache_difficulty, + tt_cache_terrain, + tt_cache_hint, + tt_cache_desc_short, + tt_cache_desc_long, + tt_cache_log_wpt, + tt_cache_log_type, + tt_cache_log_date, + tt_cache_placer, + + tt_wpt_extensions, + + tt_garmin_wpt_extensions, /* don't change this order */ + tt_garmin_wpt_proximity, + tt_garmin_wpt_temperature, + tt_garmin_wpt_depth, + tt_garmin_wpt_display_mode, + tt_garmin_wpt_categories, + tt_garmin_wpt_category, + tt_garmin_wpt_addr, + tt_garmin_wpt_city, + tt_garmin_wpt_state, + tt_garmin_wpt_country, + tt_garmin_wpt_postal_code, + tt_garmin_wpt_phone_nr, /* don't change this order */ + + tt_rte, + tt_rte_name, + tt_rte_desc, + tt_rte_cmt, + tt_rte_number, + tt_rte_rtept, + tt_rte_rtept_ele, + tt_rte_rtept_name, + tt_rte_rtept_desc, + tt_rte_rtept_sym, + tt_rte_rtept_time, + tt_rte_rtept_cmt, + tt_rte_rtept_url, + tt_rte_rtept_urlname, + tt_trk, + tt_trk_desc, + tt_trk_name, + tt_trk_trkseg, + tt_trk_number, + tt_trk_trkseg_trkpt, + tt_trk_trkseg_trkpt_cmt, + tt_trk_trkseg_trkpt_name, + tt_trk_trkseg_trkpt_sym, + tt_trk_trkseg_trkpt_url, + tt_trk_trkseg_trkpt_urlname, + tt_trk_trkseg_trkpt_desc, + tt_trk_trkseg_trkpt_ele, + tt_trk_trkseg_trkpt_time, + tt_trk_trkseg_trkpt_course, + tt_trk_trkseg_trkpt_speed, + tt_trk_trkseg_trkpt_heartrate, + tt_trk_trkseg_trkpt_cadence, + + tt_humminbird_wpt_depth, + tt_humminbird_wpt_status, + tt_humminbird_trk_trkseg_trkpt_depth, } tag_type; typedef struct { - queue queue; - char *tagdata; + queue queue; + char *tagdata; } gpx_global_entry; /* * The file-level information. */ -static +static struct gpx_global { - gpx_global_entry name; - gpx_global_entry desc; - gpx_global_entry author; - gpx_global_entry email; - gpx_global_entry url; - gpx_global_entry urlname; - gpx_global_entry keywords; - /* time and bounds aren't here; they're recomputed. */ + gpx_global_entry name; + gpx_global_entry desc; + gpx_global_entry author; + gpx_global_entry email; + gpx_global_entry url; + gpx_global_entry urlname; + gpx_global_entry keywords; + /* time and bounds aren't here; they're recomputed. */ } *gpx_global ; static void -gpx_add_to_global(gpx_global_entry *ge, char *cdata) +gpx_add_to_global(gpx_global_entry *ge, char *cdata) { - queue *elem, *tmp; - gpx_global_entry * gep; - - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - if (0 == strcmp(cdata, gep->tagdata)) - return; - } - - gep = xcalloc(sizeof(*gep), 1); - QUEUE_INIT(&gep->queue); - gep->tagdata = xstrdup(cdata); - ENQUEUE_TAIL(&ge->queue, &gep->queue); + queue *elem, *tmp; + gpx_global_entry * gep; + + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + if (0 == strcmp(cdata, gep->tagdata)) { + return; + } + } + + gep = xcalloc(sizeof(*gep), 1); + QUEUE_INIT(&gep->queue); + gep->tagdata = xstrdup(cdata); + ENQUEUE_TAIL(&ge->queue, &gep->queue); } static void gpx_rm_from_global(gpx_global_entry *ge) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); - xfree(g->tagdata); - xfree(g); - } + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gpx_global_entry *g = (gpx_global_entry *) dequeue(elem); + xfree(g->tagdata); + xfree(g); + } } static void gpx_write_gdata(gpx_global_entry *ge, const char *tag) { - queue *elem, *tmp; - gpx_global_entry * gep; - - if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { - return; - } - - gbfprintf(ofd, "<%s>", tag); - QUEUE_FOR_EACH(&ge->queue, elem, tmp) { - gep = BASE_STRUCT(elem, gpx_global_entry, queue); - gbfprintf(ofd, "%s", gep->tagdata); - /* Some tags we just output once. */ - if ((0 == strcmp(tag, "url")) || - (0 == strcmp(tag, "email"))) { - break; - } - gbfprintf(ofd, " "); - } - gbfprintf(ofd, "\n", tag); + queue *elem, *tmp; + gpx_global_entry * gep; + + if (!gpx_global || QUEUE_EMPTY(&ge->queue)) { + return; + } + + gbfprintf(ofd, "<%s>", tag); + QUEUE_FOR_EACH(&ge->queue, elem, tmp) { + gep = BASE_STRUCT(elem, gpx_global_entry, queue); + gbfprintf(ofd, "%s", gep->tagdata); + /* Some tags we just output once. */ + if ((0 == strcmp(tag, "url")) || + (0 == strcmp(tag, "email"))) { + break; + } + gbfprintf(ofd, " "); + } + gbfprintf(ofd, "\n", tag); } typedef struct tag_mapping { - tag_type tag_type; /* enum from above for this tag */ - int tag_passthrough; /* true if we don't generate this */ - const char *tag_name; /* xpath-ish tag name */ - unsigned long crc; /* Crc32 of tag_name */ + tag_type tag_type; /* enum from above for this tag */ + int tag_passthrough; /* true if we don't generate this */ + const char *tag_name; /* xpath-ish tag name */ + unsigned long crc; /* Crc32 of tag_name */ } tag_mapping; /* @@ -278,29 +279,29 @@ typedef struct tag_mapping { */ tag_mapping tag_path_map[] = { - { tt_gpx, 0, "/gpx", 0UL }, - { tt_name, 0, "/gpx/name", 0UL }, - { tt_desc, 0, "/gpx/desc", 0UL }, - { tt_author, 0, "/gpx/author", 0UL }, - { tt_email, 0, "/gpx/email", 0UL }, - { tt_url, 0, "/gpx/url", 0UL }, - { tt_urlname, 0, "/gpx/urlname", 0UL }, - { tt_keywords, 0, "/gpx/keywords", 0UL }, - - { tt_wpt, 0, "/gpx/wpt", 0UL }, - { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, - { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, - { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, - { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, - { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, - { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, - { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, - { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ - { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ - { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, - { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, - - /* Double up the GPX 1.0 and GPX 1.1 styles */ + { tt_gpx, 0, "/gpx", 0UL }, + { tt_name, 0, "/gpx/name", 0UL }, + { tt_desc, 0, "/gpx/desc", 0UL }, + { tt_author, 0, "/gpx/author", 0UL }, + { tt_email, 0, "/gpx/email", 0UL }, + { tt_url, 0, "/gpx/url", 0UL }, + { tt_urlname, 0, "/gpx/urlname", 0UL }, + { tt_keywords, 0, "/gpx/keywords", 0UL }, + + { tt_wpt, 0, "/gpx/wpt", 0UL }, + { tt_wpt_ele, 0, "/gpx/wpt/ele", 0UL }, + { tt_wpt_time, 0, "/gpx/wpt/time", 0UL }, + { tt_wpt_name, 0, "/gpx/wpt/name", 0UL }, + { tt_wpt_cmt, 0, "/gpx/wpt/cmt", 0UL }, + { tt_wpt_desc, 0, "/gpx/wpt/desc", 0UL }, + { tt_wpt_url, 0, "/gpx/wpt/url", 0UL }, + { tt_wpt_urlname, 0, "/gpx/wpt/urlname", 0UL }, + { tt_wpt_link, 0, "/gpx/wpt/link", 0UL }, /* GPX 1.1 */ + { tt_wpt_link_text, 0, "/gpx/wpt/link/text", 0UL }, /* GPX 1.1 */ + { tt_wpt_sym, 0, "/gpx/wpt/sym", 0UL }, + { tt_wpt_type, 1, "/gpx/wpt/type", 0UL }, + + /* Double up the GPX 1.0 and GPX 1.1 styles */ #define GEOTAG(type,name) \ {type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:" name, 0UL }, \ {type, 1, "/gpx/wpt/extensions/cache/" name, 0UL }, \ @@ -311,886 +312,884 @@ tag_mapping tag_path_map[] = { #define GARMIN_RTE_EXT "/gpx/rte/rtept/extensions/gpxxx:RoutePointExtension" // GEOTAG( tt_cache, "cache"), - { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, - - GEOTAG( tt_cache_name, "name"), - GEOTAG( tt_cache_container, "container"), - GEOTAG( tt_cache_type, "type"), - GEOTAG( tt_cache_difficulty, "difficulty"), - GEOTAG( tt_cache_terrain, "terrain"), - GEOTAG( tt_cache_hint, "encoded_hints"), - GEOTAG( tt_cache_hint, "hints"), /* opencaching.de */ - GEOTAG( tt_cache_desc_short, "short_description"), - GEOTAG( tt_cache_desc_long, "long_description"), - GEOTAG( tt_cache_placer, "owner"), - { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, - { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, - { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, - { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, - { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, - { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, - - { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, - - { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, - { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, - { tt_garmin_wpt_temperature, 0, GARMIN_TRK_EXT "/gpxtpx:atemp", 0UL }, - { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, - { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, - { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, - { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, - { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, - { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, - { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, - { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, - { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, - { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, - - // In Garmin space, but in core of waypoint. - { tt_trk_trkseg_trkpt_heartrate, 0, GARMIN_TRK_EXT "/gpxtpx:hr", 0UL }, - { tt_trk_trkseg_trkpt_cadence, 0, GARMIN_TRK_EXT "/gpxtpx:cad", 0UL }, - - { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth", 0UL }, // in centimeters. - { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status", 0UL }, - - { tt_rte, 0, "/gpx/rte", 0UL }, - { tt_rte_name, 0, "/gpx/rte/name", 0UL }, - { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, - { tt_rte_number, 0, "/gpx/rte/number", 0UL }, - { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, - { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, - { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, - { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, - { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, - { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, - { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, - { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, - { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, - - { tt_trk, 0, "/gpx/trk", 0UL }, - { tt_trk_name, 0, "/gpx/trk/name", 0UL }, - { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, - { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, - { tt_trk_number, 0, "/gpx/trk/number", 0UL }, - { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, - { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, - { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, - { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, - { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, - { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, - { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, - { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, - { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, - { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, - { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, - - { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth", 0UL }, // in centimeters. - - /* Common to tracks, routes, and waypts */ - { tt_fix, 0, "/gpx/wpt/fix", 0UL }, - { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, - { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, - { tt_sat, 0, "/gpx/wpt/sat", 0UL }, - { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, - { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, - { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, - { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, - { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, - { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, - { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, - {0, 0, NULL, 0UL} + { tt_cache, 1, "/gpx/wpt/groundspeak:cache" }, + + GEOTAG(tt_cache_name, "name"), + GEOTAG(tt_cache_container, "container"), + GEOTAG(tt_cache_type, "type"), + GEOTAG(tt_cache_difficulty, "difficulty"), + GEOTAG(tt_cache_terrain, "terrain"), + GEOTAG(tt_cache_hint, "encoded_hints"), + GEOTAG(tt_cache_hint, "hints"), /* opencaching.de */ + GEOTAG(tt_cache_desc_short, "short_description"), + GEOTAG(tt_cache_desc_long, "long_description"), + GEOTAG(tt_cache_placer, "owner"), + { tt_cache_log_wpt, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:log_wpt"}, + { tt_cache_log_wpt, 1, "/gpx/wpt/extensions/cache/logs/log/log_wpt"}, + { tt_cache_log_type, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:type"}, + { tt_cache_log_type, 1, "/gpx/wpt/extensions/cache/logs/log/type"}, + { tt_cache_log_date, 1, "/gpx/wpt/groundspeak:cache/groundspeak:logs/groundspeak:log/groundspeak:date"}, + { tt_cache_log_date, 1, "/gpx/wpt/extensions/cache/logs/log/date"}, + + { tt_wpt_extensions, 0, "/gpx/wpt/extensions", 0UL }, + + { tt_garmin_wpt_extensions, 0, GARMIN_WPT_EXT, 0UL }, + { tt_garmin_wpt_proximity, 0, GARMIN_WPT_EXT "/gpxx:Proximity", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_WPT_EXT "/gpxx:Temperature", 0UL }, + { tt_garmin_wpt_temperature, 0, GARMIN_TRK_EXT "/gpxtpx:atemp", 0UL }, + { tt_garmin_wpt_depth, 0, GARMIN_WPT_EXT "/gpxx:Depth", 0UL }, + { tt_garmin_wpt_display_mode, 0, GARMIN_WPT_EXT "/gpxx:DisplayMode", 0UL }, + { tt_garmin_wpt_categories, 0, GARMIN_WPT_EXT "/gpxx:Categories", 0UL }, + { tt_garmin_wpt_category, 0, GARMIN_WPT_EXT "/gpxx:Categories/gpxx:Category", 0UL }, + { tt_garmin_wpt_addr, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:StreetAddress", 0UL }, + { tt_garmin_wpt_city, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:City", 0UL }, + { tt_garmin_wpt_state, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:State", 0UL }, + { tt_garmin_wpt_country, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:Country", 0UL }, + { tt_garmin_wpt_postal_code, 0, GARMIN_WPT_EXT "/gpxx:Address/gpxx:PostalCode", 0UL }, + { tt_garmin_wpt_phone_nr, 0, GARMIN_WPT_EXT "/gpxx:PhoneNumber", 0UL }, + + // In Garmin space, but in core of waypoint. + { tt_trk_trkseg_trkpt_heartrate, 0, GARMIN_TRK_EXT "/gpxtpx:hr", 0UL }, + { tt_trk_trkseg_trkpt_cadence, 0, GARMIN_TRK_EXT "/gpxtpx:cad", 0UL }, + + { tt_humminbird_wpt_depth, 0, "/gpx/wpt/extensions/h:depth", 0UL }, // in centimeters. + { tt_humminbird_wpt_status, 0, "/gpx/wpt/extensions/h:status", 0UL }, + + { tt_rte, 0, "/gpx/rte", 0UL }, + { tt_rte_name, 0, "/gpx/rte/name", 0UL }, + { tt_rte_desc, 0, "/gpx/rte/desc", 0UL }, + { tt_rte_number, 0, "/gpx/rte/number", 0UL }, + { tt_rte_rtept, 0, "/gpx/rte/rtept", 0UL }, + { tt_rte_rtept_ele, 0, "/gpx/rte/rtept/ele", 0UL }, + { tt_rte_rtept_time, 0, "/gpx/rte/rtept/time", 0UL }, + { tt_rte_rtept_name, 0, "/gpx/rte/rtept/name", 0UL }, + { tt_rte_rtept_cmt, 0, "/gpx/rte/rtept/cmt", 0UL }, + { tt_rte_rtept_desc, 0, "/gpx/rte/rtept/desc", 0UL }, + { tt_rte_rtept_url, 0, "/gpx/rte/rtept/url", 0UL }, + { tt_rte_rtept_urlname, 0, "/gpx/rte/rtept/urlname", 0UL }, + { tt_rte_rtept_sym, 0, "/gpx/rte/rtept/sym", 0UL }, + + { tt_trk, 0, "/gpx/trk", 0UL }, + { tt_trk_name, 0, "/gpx/trk/name", 0UL }, + { tt_trk_desc, 0, "/gpx/trk/desc", 0UL }, + { tt_trk_trkseg, 0, "/gpx/trk/trkseg", 0UL }, + { tt_trk_number, 0, "/gpx/trk/number", 0UL }, + { tt_trk_trkseg_trkpt, 0, "/gpx/trk/trkseg/trkpt", 0UL }, + { tt_trk_trkseg_trkpt_ele, 0, "/gpx/trk/trkseg/trkpt/ele", 0UL }, + { tt_trk_trkseg_trkpt_time, 0, "/gpx/trk/trkseg/trkpt/time", 0UL }, + { tt_trk_trkseg_trkpt_name, 0, "/gpx/trk/trkseg/trkpt/name", 0UL }, + { tt_trk_trkseg_trkpt_cmt, 0, "/gpx/trk/trkseg/trkpt/cmt", 0UL }, + { tt_trk_trkseg_trkpt_desc, 0, "/gpx/trk/trkseg/trkpt/desc", 0UL }, + { tt_trk_trkseg_trkpt_url, 0, "/gpx/trk/trkseg/trkpt/url", 0UL }, + { tt_trk_trkseg_trkpt_urlname, 0, "/gpx/trk/trkseg/trkpt/urlname", 0UL }, + { tt_trk_trkseg_trkpt_sym, 0, "/gpx/trk/trkseg/trkpt/sym", 0UL }, + { tt_trk_trkseg_trkpt_course, 0, "/gpx/trk/trkseg/trkpt/course", 0UL }, + { tt_trk_trkseg_trkpt_speed, 0, "/gpx/trk/trkseg/trkpt/speed", 0UL }, + + { tt_humminbird_trk_trkseg_trkpt_depth, 0, "/gpx/trk/trkseg/trkpt/extensions/h:depth", 0UL }, // in centimeters. + + /* Common to tracks, routes, and waypts */ + { tt_fix, 0, "/gpx/wpt/fix", 0UL }, + { tt_fix, 0, "/gpx/trk/trkseg/trkpt/fix", 0UL }, + { tt_fix, 0, "/gpx/rte/rtept/fix", 0UL }, + { tt_sat, 0, "/gpx/wpt/sat", 0UL }, + { tt_sat, 0, "/gpx/trk/trkseg/trkpt/sat", 0UL }, + { tt_sat, 0, "/gpx/rte/rtept/sat", 0UL }, + { tt_pdop, 0, "/gpx/wpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/trk/trkseg/trkpt/pdop", 0UL }, + { tt_pdop, 0, "/gpx/rte/rtept/pdop", 0UL }, + { tt_hdop, 0, "/gpx/wpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/trk/trkseg/trkpt/hdop", 0UL }, + { tt_hdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + { tt_vdop, 0, "/gpx/wpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/trk/trkseg/trkpt/vdop", 0UL }, + { tt_vdop, 0, "/gpx/rte/rtept/hdop", 0UL }, + {0, 0, NULL, 0UL} }; static tag_type get_tag(const char *t, int *passthrough) { - tag_mapping *tm; - unsigned long tcrc = get_crc32_s(t); - - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { - *passthrough = tm->tag_passthrough; - return tm->tag_type; - } - } - *passthrough = 1; - return tt_unknown; + tag_mapping *tm; + unsigned long tcrc = get_crc32_s(t); + + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + if ((tcrc == tm->crc) && (0 == strcmp(tm->tag_name, t))) { + *passthrough = tm->tag_passthrough; + return tm->tag_type; + } + } + *passthrough = 1; + return tt_unknown; } static void prescan_tags(void) { - tag_mapping *tm; - for (tm = tag_path_map; tm->tag_type != 0; tm++) { - tm->crc = get_crc32_s(tm->tag_name); - } + tag_mapping *tm; + for (tm = tag_path_map; tm->tag_type != 0; tm++) { + tm->crc = get_crc32_s(tm->tag_name); + } } static void tag_gpx(const char **attrv) { - const char **avp; - for (avp = &attrv[0]; *avp; avp += 2) { - if (strcmp(avp[0], "version") == 0) { - gpx_version = avp[1]; - } - else if (strcmp(avp[0], "src") == 0) { - gpx_creator = avp[1]; - } - /* - * Our handling of schemaLocation really is weird. - * If we see we have a "normal" GPX 1.1 header, on read, - * flip our default on write to use that and don't append - * it to the rest... - */ - else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { - if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { - if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { - xfree(xsi_schema_loc); - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); - } - continue; - } - if (0 == strstr(xsi_schema_loc, avp[1])) { - xsi_schema_loc = xstrappend(xsi_schema_loc, " "); - xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); - } - } - } + const char **avp; + for (avp = &attrv[0]; *avp; avp += 2) { + if (strcmp(avp[0], "version") == 0) { + gpx_version = avp[1]; + } else if (strcmp(avp[0], "src") == 0) { + gpx_creator = avp[1]; + } + /* + * Our handling of schemaLocation really is weird. + * If we see we have a "normal" GPX 1.1 header, on read, + * flip our default on write to use that and don't append + * it to the rest... + */ + else if (strcmp(avp[0], "xsi:schemaLocation") == 0) { + if (0 == strcmp(avp[1], DEFAULT_XSI_SCHEMA_LOC_11)) { + if (0 == strcmp(xsi_schema_loc, DEFAULT_XSI_SCHEMA_LOC)) { + xfree(xsi_schema_loc); + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC_11); + } + continue; + } + if (0 == strstr(xsi_schema_loc, avp[1])) { + xsi_schema_loc = xstrappend(xsi_schema_loc, " "); + xsi_schema_loc = xstrappend(xsi_schema_loc, avp[1]); + } + } + } } static void tag_wpt(const char **attrv) { - const char **avp = &attrv[0]; - - wpt_tmp = waypt_new(); - - cur_tag = NULL; - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &wpt_tmp->longitude); - } - avp+=2; - } - fs_ptr = &wpt_tmp->fs; + const char **avp = &attrv[0]; + + wpt_tmp = waypt_new(); + + cur_tag = NULL; + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &wpt_tmp->longitude); + } + avp+=2; + } + fs_ptr = &wpt_tmp->fs; } static void tag_cache_desc(const char ** attrv) { - const char **avp; - - cache_descr_is_html = 0; - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "html") == 0) { - if (strcmp(avp[1], "True") == 0) { - cache_descr_is_html = 1; - } - } - } + const char **avp; + + cache_descr_is_html = 0; + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "html") == 0) { + if (strcmp(avp[1], "True") == 0) { + cache_descr_is_html = 1; + } + } + } } static void tag_gs_cache(const char **attrv) { - const char **avp; - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - - for (avp = &attrv[0]; *avp; avp+=2) { - if (strcmp(avp[0], "id") == 0) { - gc_data->id = atoi(avp[1]); - } else if (strcmp(avp[0], "available") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - gc_data->is_available = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - gc_data->is_available = status_false; - } - } else if (strcmp(avp[0], "archived") == 0) { - if (case_ignore_strcmp(avp[1], "True") == 0) { - gc_data->is_archived = status_true; - } - else if (case_ignore_strcmp(avp[1], "False") == 0) { - gc_data->is_archived = status_false; - } - } - } + const char **avp; + geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); + + for (avp = &attrv[0]; *avp; avp+=2) { + if (strcmp(avp[0], "id") == 0) { + gc_data->id = atoi(avp[1]); + } else if (strcmp(avp[0], "available") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + gc_data->is_available = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + gc_data->is_available = status_false; + } + } else if (strcmp(avp[0], "archived") == 0) { + if (case_ignore_strcmp(avp[1], "True") == 0) { + gc_data->is_archived = status_true; + } else if (case_ignore_strcmp(avp[1], "False") == 0) { + gc_data->is_archived = status_false; + } + } + } } static void start_something_else(const char *el, const char **attrv) { - const char **avp = attrv; - char **avcp = NULL; - int attr_count = 0; - xml_tag *new_tag; - fs_xml *fs_gpx; - - if ( !fs_ptr ) { - return; - } - - new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); - new_tag->tagname = xstrdup(el); - - /* count attributes */ - while (*avp) { - attr_count++; - avp++; - } - - /* copy attributes */ - avp = attrv; - new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); - avcp = new_tag->attributes; - while (*avp) { - *avcp = xstrdup(*avp); - avcp++; - avp++; - } - *avcp = NULL; - - if ( cur_tag ) { - if ( cur_tag->child ) { - cur_tag = cur_tag->child; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = cur_tag->parent; - } - else { - cur_tag->child = new_tag; - new_tag->parent = cur_tag; - } - } - else { - fs_gpx = (fs_xml *)fs_chain_find( *fs_ptr, FS_GPX ); - - if ( fs_gpx && fs_gpx->tag ) { - cur_tag = fs_gpx->tag; - while ( cur_tag->sibling ) { - cur_tag = cur_tag->sibling; - } - cur_tag->sibling = new_tag; - new_tag->parent = NULL; - } - else { - fs_gpx = fs_xml_alloc(FS_GPX); - fs_gpx->tag = new_tag; - fs_chain_add( fs_ptr, (format_specific_data *)fs_gpx ); - new_tag->parent = NULL; - } - } - cur_tag = new_tag; + const char **avp = attrv; + char **avcp = NULL; + int attr_count = 0; + xml_tag *new_tag; + fs_xml *fs_gpx; + + if (!fs_ptr) { + return; + } + + new_tag = (xml_tag *)xcalloc(sizeof(xml_tag),1); + new_tag->tagname = xstrdup(el); + + /* count attributes */ + while (*avp) { + attr_count++; + avp++; + } + + /* copy attributes */ + avp = attrv; + new_tag->attributes = (char **)xcalloc(sizeof(char *),attr_count+1); + avcp = new_tag->attributes; + while (*avp) { + *avcp = xstrdup(*avp); + avcp++; + avp++; + } + *avcp = NULL; + + if (cur_tag) { + if (cur_tag->child) { + cur_tag = cur_tag->child; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = cur_tag->parent; + } else { + cur_tag->child = new_tag; + new_tag->parent = cur_tag; + } + } else { + fs_gpx = (fs_xml *)fs_chain_find(*fs_ptr, FS_GPX); + + if (fs_gpx && fs_gpx->tag) { + cur_tag = fs_gpx->tag; + while (cur_tag->sibling) { + cur_tag = cur_tag->sibling; + } + cur_tag->sibling = new_tag; + new_tag->parent = NULL; + } else { + fs_gpx = fs_xml_alloc(FS_GPX); + fs_gpx->tag = new_tag; + fs_chain_add(fs_ptr, (format_specific_data *)fs_gpx); + new_tag->parent = NULL; + } + } + cur_tag = new_tag; } static void end_something_else() { - if ( cur_tag ) { - cur_tag = cur_tag->parent; - } + if (cur_tag) { + cur_tag = cur_tag->parent; + } } static void tag_log_wpt(const char **attrv) { - waypoint * lwp_tmp; - const char **avp = &attrv[0]; - - /* create a new waypoint */ - lwp_tmp = waypt_new(); - - /* extract the lat/lon attributes */ - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->latitude); - } - else if (strcmp(avp[0], "lon") == 0) { - sscanf(avp[1], "%lf", - &lwp_tmp->longitude); - } - avp+=2; - } - /* Make a new shortname. Since this is a groundspeak extension, - we assume that GCBLAH is the current shortname format and that - wpt_tmp refers to the currently parsed waypoint. Unfortunatley, - we need to keep track of log_wpt counts so we don't collide with - dupe shortnames. - */ - - if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { - /* copy of the shortname */ - lwp_tmp->shortname = xcalloc(7, 1); - sprintf(lwp_tmp->shortname, "%-4.4s%02d", - &wpt_tmp->shortname[2], logpoint_ct++); - - waypt_add(lwp_tmp); - } + waypoint * lwp_tmp; + const char **avp = &attrv[0]; + + /* create a new waypoint */ + lwp_tmp = waypt_new(); + + /* extract the lat/lon attributes */ + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->latitude); + } else if (strcmp(avp[0], "lon") == 0) { + sscanf(avp[1], "%lf", + &lwp_tmp->longitude); + } + avp+=2; + } + /* Make a new shortname. Since this is a groundspeak extension, + we assume that GCBLAH is the current shortname format and that + wpt_tmp refers to the currently parsed waypoint. Unfortunatley, + we need to keep track of log_wpt counts so we don't collide with + dupe shortnames. + */ + + if ((wpt_tmp->shortname) && (strlen(wpt_tmp->shortname) > 2)) { + /* copy of the shortname */ + lwp_tmp->shortname = xcalloc(7, 1); + sprintf(lwp_tmp->shortname, "%-4.4s%02d", + &wpt_tmp->shortname[2], logpoint_ct++); + + waypt_add(lwp_tmp); + } } static void gpx_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - char *e; - char *ep; - int passthrough; - int tag; - const char *el = xml_convert_to_char_string(xml_el); - const char **attr = xml_convert_attrs_to_char_string(xml_attr); - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - - /* - * Reset end-of-string without actually emptying/reallocing cdatastr. - */ - *(char *) cdatastr.mem = 0; - - tag = get_tag(current_tag.mem, &passthrough); - switch (tag) { - case tt_gpx: - tag_gpx(attr); - break; - case tt_wpt: - tag_wpt(attr); - break; - case tt_wpt_link: - if (0 == strcmp(attr[0], "href")) { - link_url = attr[1]; - } - break; - case tt_wpt_link_text: - link_text = cdatastr.mem; - break; - case tt_rte: - rte_head = route_head_alloc(); - route_add_head(rte_head); - fs_ptr = &rte_head->fs; - break; - case tt_rte_rtept: - tag_wpt(attr); - break; - case tt_trk: - trk_head = route_head_alloc(); - track_add_head(trk_head); - fs_ptr = &trk_head->fs; - break; - case tt_trk_trkseg_trkpt: - tag_wpt(attr); - if (next_trkpt_is_new_seg) { - wpt_tmp->wpt_flags.new_trkseg = 1; - next_trkpt_is_new_seg = 0; - } - break; - case tt_unknown: - start_something_else(el, attr); - return; - case tt_cache: - tag_gs_cache(attr); - break; - case tt_cache_log_wpt: - if (opt_logpoint) - tag_log_wpt(attr); - break; - case tt_cache_desc_long: - case tt_cache_desc_short: - tag_cache_desc(attr); - break; - case tt_cache_placer: - if (*attr && (0 == strcmp(attr[0], "id"))) { - waypt_alloc_gc_data(wpt_tmp)->placer_id = atoi(attr[1]); - } - default: - break; - } - if (passthrough) { - start_something_else(el, attr); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attr); + char *e; + char *ep; + int passthrough; + int tag; + const char *el = xml_convert_to_char_string(xml_el); + const char **attr = xml_convert_attrs_to_char_string(xml_attr); + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + + /* + * Reset end-of-string without actually emptying/reallocing cdatastr. + */ + *(char *) cdatastr.mem = 0; + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + case tt_gpx: + tag_gpx(attr); + break; + case tt_wpt: + tag_wpt(attr); + break; + case tt_wpt_link: + if (0 == strcmp(attr[0], "href")) { + link_url = attr[1]; + } + break; + case tt_wpt_link_text: + link_text = cdatastr.mem; + break; + case tt_rte: + rte_head = route_head_alloc(); + route_add_head(rte_head); + fs_ptr = &rte_head->fs; + break; + case tt_rte_rtept: + tag_wpt(attr); + break; + case tt_trk: + trk_head = route_head_alloc(); + track_add_head(trk_head); + fs_ptr = &trk_head->fs; + break; + case tt_trk_trkseg_trkpt: + tag_wpt(attr); + if (next_trkpt_is_new_seg) { + wpt_tmp->wpt_flags.new_trkseg = 1; + next_trkpt_is_new_seg = 0; + } + break; + case tt_unknown: + start_something_else(el, attr); + return; + case tt_cache: + tag_gs_cache(attr); + break; + case tt_cache_log_wpt: + if (opt_logpoint) { + tag_log_wpt(attr); + } + break; + case tt_cache_desc_long: + case tt_cache_desc_short: + tag_cache_desc(attr); + break; + case tt_cache_placer: + if (*attr && (0 == strcmp(attr[0], "id"))) { + waypt_alloc_gc_data(wpt_tmp)->placer_id = atoi(attr[1]); + } + default: + break; + } + if (passthrough) { + start_something_else(el, attr); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attr); } struct -gs_type_mapping{ - geocache_type type; - const char *name; + gs_type_mapping { + geocache_type type; + const char *name; } gs_type_map[] = { - { gt_traditional, "Traditional Cache" }, - { gt_traditional, "Traditional" }, /* opencaching.de */ - { gt_multi, "Multi-cache" }, - { gt_multi, "Multi" }, /* opencaching.de */ - { gt_virtual, "Virtual Cache" }, - { gt_virtual, "Virtual" }, /* opencaching.de */ - { gt_event, "Event Cache" }, - { gt_event, "Event" }, /* opencaching.de */ - { gt_webcam, "Webcam Cache" }, - { gt_webcam, "Webcam" }, /* opencaching.de */ - { gt_suprise, "Unknown Cache" }, - { gt_earth, "Earthcache" }, - { gt_earth, "Earth" }, /* opencaching.de */ - { gt_cito, "Cache In Trash Out Event" }, - { gt_letterbox, "Letterbox Hybrid" }, - { gt_locationless, "Locationless (Reverse) Cache" }, - { gt_ape, "Project APE Cache" }, - { gt_mega, "Mega-Event Cache" }, - { gt_wherigo, "Wherigo Cache" }, - - { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ + { gt_traditional, "Traditional Cache" }, + { gt_traditional, "Traditional" }, /* opencaching.de */ + { gt_multi, "Multi-cache" }, + { gt_multi, "Multi" }, /* opencaching.de */ + { gt_virtual, "Virtual Cache" }, + { gt_virtual, "Virtual" }, /* opencaching.de */ + { gt_event, "Event Cache" }, + { gt_event, "Event" }, /* opencaching.de */ + { gt_webcam, "Webcam Cache" }, + { gt_webcam, "Webcam" }, /* opencaching.de */ + { gt_suprise, "Unknown Cache" }, + { gt_earth, "Earthcache" }, + { gt_earth, "Earth" }, /* opencaching.de */ + { gt_cito, "Cache In Trash Out Event" }, + { gt_letterbox, "Letterbox Hybrid" }, + { gt_locationless, "Locationless (Reverse) Cache" }, + { gt_ape, "Project APE Cache" }, + { gt_mega, "Mega-Event Cache" }, + { gt_wherigo, "Wherigo Cache" }, + + { gt_benchmark, "Benchmark" }, /* Not Groundspeak; for GSAK */ }; struct -gs_container_mapping{ - geocache_container type; - const char *name; + gs_container_mapping { + geocache_container type; + const char *name; } gs_container_map[] = { - { gc_other, "Unknown" }, - { gc_other, "Other" }, /* Synonym on read. */ - { gc_micro, "Micro" }, - { gc_regular, "Regular" }, - { gc_large, "Large" }, - { gc_small, "Small" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_other, "Other" }, /* Synonym on read. */ + { gc_micro, "Micro" }, + { gc_regular, "Regular" }, + { gc_large, "Large" }, + { gc_small, "Small" }, + { gc_virtual, "Virtual" } }; geocache_type gs_mktype(const char *t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { - return gs_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_type_map[i].name)) { + return gs_type_map[i].type; + } + } + return gt_unknown; } const char * gs_get_cachetype(geocache_type t) { - int i; - int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_type_map[i].type) { - return gs_type_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_type_map) / sizeof(gs_type_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_type_map[i].type) { + return gs_type_map[i].name; + } + } + return "Unknown"; } geocache_container gs_mkcont(const char *t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { - return gs_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, gs_container_map[i].name)) { + return gs_container_map[i].type; + } + } + return gc_unknown; } const char * gs_get_container(geocache_container t) { - int i; - int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); - - for (i = 0; i < sz; i++) { - if (t == gs_container_map[i].type) { - return gs_container_map[i].name; - } - } - return "Unknown"; + int i; + int sz = sizeof(gs_container_map) / sizeof(gs_container_map[0]); + + for (i = 0; i < sz; i++) { + if (t == gs_container_map[i].type) { + return gs_container_map[i].name; + } + } + return "Unknown"; } -time_t -xml_parse_time( const char *cdatastr, int *microsecs ) +time_t +xml_parse_time(const char *cdatastr, int *microsecs) { - int off_hr = 0; - int off_min = 0; - int off_sign = 1; - char *offsetstr = NULL; - char *pointstr = NULL; - struct tm tm; - time_t rv = 0; - char *timestr = xstrdup( cdatastr ); - - memset(&tm, 0, sizeof(tm)); - - offsetstr = strchr( timestr, 'Z' ); - if ( offsetstr ) { - /* zulu time; offsets stay at defaults */ - *offsetstr = '\0'; - } else { - offsetstr = strchr( timestr, '+' ); - if ( offsetstr ) { - /* positive offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", &off_hr, &off_min ); - } else { - offsetstr = strchr( timestr, 'T' ); - if ( offsetstr ) { - offsetstr = strchr( offsetstr, '-' ); - if ( offsetstr ) { - /* negative offset; parse it */ - *offsetstr = '\0'; - sscanf( offsetstr+1, "%d:%d", - &off_hr, &off_min ); - off_sign = -1; - } - } - } - } - - pointstr = strchr( timestr, '.' ); - if ( pointstr ) { - if (microsecs) { - double fsec; - sscanf(pointstr, "%le", &fsec); - /* Round to avoid FP jitter */ - *microsecs = .5 + (fsec * 1000000.0) ; - } - *pointstr = '\0'; - } - - sscanf(timestr, "%d-%d-%dT%d:%d:%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday, - &tm.tm_hour, - &tm.tm_min, - &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - - rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; - - xfree(timestr); - - return rv; + int off_hr = 0; + int off_min = 0; + int off_sign = 1; + char *offsetstr = NULL; + char *pointstr = NULL; + struct tm tm; + time_t rv = 0; + char *timestr = xstrdup(cdatastr); + + memset(&tm, 0, sizeof(tm)); + + offsetstr = strchr(timestr, 'Z'); + if (offsetstr) { + /* zulu time; offsets stay at defaults */ + *offsetstr = '\0'; + } else { + offsetstr = strchr(timestr, '+'); + if (offsetstr) { + /* positive offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", &off_hr, &off_min); + } else { + offsetstr = strchr(timestr, 'T'); + if (offsetstr) { + offsetstr = strchr(offsetstr, '-'); + if (offsetstr) { + /* negative offset; parse it */ + *offsetstr = '\0'; + sscanf(offsetstr+1, "%d:%d", + &off_hr, &off_min); + off_sign = -1; + } + } + } + } + + pointstr = strchr(timestr, '.'); + if (pointstr) { + if (microsecs) { + double fsec; + sscanf(pointstr, "%le", &fsec); + /* Round to avoid FP jitter */ + *microsecs = .5 + (fsec * 1000000.0) ; + } + *pointstr = '\0'; + } + + sscanf(timestr, "%d-%d-%dT%d:%d:%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + + rv = mkgmtime(&tm) - off_sign*off_hr*3600 - off_sign*off_min*60; + + xfree(timestr); + + return rv; } static void gpx_end(void *data, const XML_Char *xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - char *s = strrchr(current_tag.mem, '/'); - float x; - char *cdatastrp = cdatastr.mem; - int passthrough; - static time_t gc_log_date; - tag_type tag; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - - tag = get_tag(current_tag.mem, &passthrough); - switch(tag) { - /* - * First, the tags that are file-global. - */ - case tt_name: - gpx_add_to_global(&gpx_global->name, cdatastrp); - break; - case tt_desc: - gpx_add_to_global(&gpx_global->desc, cdatastrp); - break; - case tt_author: - gpx_add_to_global(&gpx_global->author, cdatastrp); - break; - case tt_email: - gpx_add_to_global(&gpx_global->email, cdatastrp); - if (gpx_email == NULL) { - gpx_email = xstrdup(cdatastrp); - } - break; - case tt_url: - gpx_add_to_global(&gpx_global->url, cdatastrp); - break; - case tt_urlname: - gpx_add_to_global(&gpx_global->urlname, cdatastrp); - break; - case tt_keywords: - gpx_add_to_global(&gpx_global->keywords, cdatastrp); - break; - - /* - * Waypoint-specific tags. - */ - case tt_wpt: - waypt_add(wpt_tmp); - logpoint_ct = 0; - cur_tag = NULL; - wpt_tmp = NULL; - break; - case tt_cache_name: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_cache_container: - waypt_alloc_gc_data(wpt_tmp)->container = gs_mkcont(cdatastrp); - break; - case tt_cache_type: - waypt_alloc_gc_data(wpt_tmp)->type = gs_mktype(cdatastrp); - break; - case tt_cache_difficulty: - sscanf(cdatastrp, "%f", &x); - waypt_alloc_gc_data(wpt_tmp)->diff = x * 10; - break; - case tt_cache_hint: - rtrim(cdatastrp); - if (cdatastrp[0]) { - waypt_alloc_gc_data(wpt_tmp)->hint = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_long: - rtrim(cdatastrp); - if (cdatastrp[0]) { - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - gc_data->desc_long.is_html = cache_descr_is_html; - gc_data->desc_long.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_desc_short: - rtrim(cdatastrp); - if (cdatastrp[0]) { - geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); - gc_data->desc_short.is_html = cache_descr_is_html; - gc_data->desc_short.utfstring = xstrdup(cdatastrp); - } - break; - case tt_cache_terrain: - sscanf(cdatastrp, "%f", &x); - waypt_alloc_gc_data(wpt_tmp)->terr = x * 10; - break; - case tt_cache_placer: - waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(cdatastrp); - break; - case tt_cache_log_date: - gc_log_date = xml_parse_time( cdatastrp, NULL ); - break; - /* - * "Found it" logs follow the date according to the schema, - * if this is the first "found it" for this waypt, just use the - * last date we saw in this log. - */ - case tt_cache_log_type: - if ((0 == strcmp(cdatastrp, "Found it")) && - (0 == wpt_tmp->gc_data->last_found)) { - waypt_alloc_gc_data(wpt_tmp)->last_found = gc_log_date; - } - gc_log_date = 0; - break; - - /* - * Garmin-waypoint-specific tags. - */ - case tt_garmin_wpt_proximity: - case tt_garmin_wpt_temperature: - case tt_garmin_wpt_depth: - case tt_garmin_wpt_display_mode: - case tt_garmin_wpt_category: - case tt_garmin_wpt_addr: - case tt_garmin_wpt_city: - case tt_garmin_wpt_state: - case tt_garmin_wpt_country: - case tt_garmin_wpt_postal_code: - case tt_garmin_wpt_phone_nr: - garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); - break; - - /* - * Humminbird-waypoint-specific tags. - */ - case tt_humminbird_wpt_depth: - case tt_humminbird_trk_trkseg_trkpt_depth: - WAYPT_SET(wpt_tmp, depth, atof(cdatastrp) / 100.0) - break; - /* - * Route-specific tags. - */ - case tt_rte_name: - rte_head->rte_name = xstrdup(cdatastrp); - break; - case tt_rte: - break; - case tt_rte_rtept: - route_add_wpt(rte_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_rte_desc: - rte_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_rte_number: - rte_head->rte_num = atoi(cdatastrp); - break; - /* - * Track-specific tags. - */ - case tt_trk_name: - trk_head->rte_name = xstrdup(cdatastrp); - break; - case tt_trk: - break; - case tt_trk_trkseg: - next_trkpt_is_new_seg = 1; - break; - case tt_trk_trkseg_trkpt: - track_add_wpt(trk_head, wpt_tmp); - wpt_tmp = NULL; - break; - case tt_trk_desc: - trk_head->rte_desc = xstrdup(cdatastrp); - break; - case tt_trk_number: - trk_head->rte_num = atoi(cdatastrp); - break; - case tt_trk_trkseg_trkpt_course: - WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_speed: - WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); - break; - case tt_trk_trkseg_trkpt_heartrate: - wpt_tmp->heartrate = atof(cdatastrp); - break; - case tt_trk_trkseg_trkpt_cadence: - wpt_tmp->cadence = atof(cdatastrp); - break; - - /* - * Items that are actually in multiple categories. - */ - case tt_wpt_ele: - case tt_rte_rtept_ele: - case tt_trk_trkseg_trkpt_ele: - sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); - break; - case tt_wpt_name: - case tt_rte_rtept_name: - case tt_trk_trkseg_trkpt_name: - wpt_tmp->shortname = xstrdup(cdatastrp); - break; - case tt_wpt_sym: - case tt_rte_rtept_sym: - case tt_trk_trkseg_trkpt_sym: - wpt_tmp->icon_descr = xstrdup(cdatastrp); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case tt_wpt_time: - case tt_trk_trkseg_trkpt_time: - case tt_rte_rtept_time: - wpt_tmp->creation_time = xml_parse_time( cdatastrp, &wpt_tmp->microseconds ); - break; - case tt_wpt_cmt: - case tt_rte_rtept_cmt: - case tt_trk_trkseg_trkpt_cmt: - wpt_tmp->description = xstrdup(cdatastrp); - break; - case tt_wpt_desc: - case tt_trk_trkseg_trkpt_desc: - case tt_rte_rtept_desc: - if (wpt_tmp->notes != NULL) xfree(wpt_tmp->notes); - wpt_tmp->notes = xstrdup(cdatastrp); - break; - case tt_pdop: - wpt_tmp->pdop = atof(cdatastrp); - break; - case tt_hdop: - wpt_tmp->hdop = atof(cdatastrp); - break; - case tt_vdop: - wpt_tmp->vdop = atof(cdatastrp); - break; - case tt_sat: - wpt_tmp->sat = atof(cdatastrp); - break; - case tt_fix: - wpt_tmp->fix = atoi(cdatastrp)-1; - if ( wpt_tmp->fix < fix_2d) { - if (!case_ignore_strcmp(cdatastrp, "none")) - wpt_tmp->fix = fix_none; - else if (!case_ignore_strcmp(cdatastrp, "dgps")) - wpt_tmp->fix = fix_dgps; - else if (!case_ignore_strcmp(cdatastrp, "pps")) - wpt_tmp->fix = fix_pps; - else - wpt_tmp->fix = fix_unknown; - } - break; - case tt_wpt_url: - case tt_trk_trkseg_trkpt_url: - case tt_rte_rtept_url: - wpt_tmp->url = xstrdup(cdatastrp); - break; - case tt_wpt_urlname: - case tt_trk_trkseg_trkpt_urlname: - case tt_rte_rtept_urlname: - wpt_tmp->url_link_text = xstrdup(cdatastrp); - break; - case tt_wpt_link: -//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: -//TODO: implement GPX 1.1 case tt_rte_rtept_link: - { - char *lt = link_text; - if (lt) { - lt = xstrdup(lrtrim(link_text)); - } - - waypt_add_url(wpt_tmp, xstrdup(link_url), lt); - link_text = NULL; - } - break; - case tt_unknown: - end_something_else(); - *s = 0; - return; - default: - break; - } - - if (passthrough) { - end_something_else(); - } - - *s = 0; - xml_free_converted_string(el); + const char *el = xml_convert_to_char_string(xml_el); + char *s = strrchr(current_tag.mem, '/'); + float x; + char *cdatastrp = cdatastr.mem; + int passthrough; + static time_t gc_log_date; + tag_type tag; + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + + tag = get_tag(current_tag.mem, &passthrough); + switch (tag) { + /* + * First, the tags that are file-global. + */ + case tt_name: + gpx_add_to_global(&gpx_global->name, cdatastrp); + break; + case tt_desc: + gpx_add_to_global(&gpx_global->desc, cdatastrp); + break; + case tt_author: + gpx_add_to_global(&gpx_global->author, cdatastrp); + break; + case tt_email: + gpx_add_to_global(&gpx_global->email, cdatastrp); + if (gpx_email == NULL) { + gpx_email = xstrdup(cdatastrp); + } + break; + case tt_url: + gpx_add_to_global(&gpx_global->url, cdatastrp); + break; + case tt_urlname: + gpx_add_to_global(&gpx_global->urlname, cdatastrp); + break; + case tt_keywords: + gpx_add_to_global(&gpx_global->keywords, cdatastrp); + break; + + /* + * Waypoint-specific tags. + */ + case tt_wpt: + waypt_add(wpt_tmp); + logpoint_ct = 0; + cur_tag = NULL; + wpt_tmp = NULL; + break; + case tt_cache_name: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_cache_container: + waypt_alloc_gc_data(wpt_tmp)->container = gs_mkcont(cdatastrp); + break; + case tt_cache_type: + waypt_alloc_gc_data(wpt_tmp)->type = gs_mktype(cdatastrp); + break; + case tt_cache_difficulty: + sscanf(cdatastrp, "%f", &x); + waypt_alloc_gc_data(wpt_tmp)->diff = x * 10; + break; + case tt_cache_hint: + rtrim(cdatastrp); + if (cdatastrp[0]) { + waypt_alloc_gc_data(wpt_tmp)->hint = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_long: + rtrim(cdatastrp); + if (cdatastrp[0]) { + geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); + gc_data->desc_long.is_html = cache_descr_is_html; + gc_data->desc_long.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_desc_short: + rtrim(cdatastrp); + if (cdatastrp[0]) { + geocache_data *gc_data = waypt_alloc_gc_data(wpt_tmp); + gc_data->desc_short.is_html = cache_descr_is_html; + gc_data->desc_short.utfstring = xstrdup(cdatastrp); + } + break; + case tt_cache_terrain: + sscanf(cdatastrp, "%f", &x); + waypt_alloc_gc_data(wpt_tmp)->terr = x * 10; + break; + case tt_cache_placer: + waypt_alloc_gc_data(wpt_tmp)->placer = xstrdup(cdatastrp); + break; + case tt_cache_log_date: + gc_log_date = xml_parse_time(cdatastrp, NULL); + break; + /* + * "Found it" logs follow the date according to the schema, + * if this is the first "found it" for this waypt, just use the + * last date we saw in this log. + */ + case tt_cache_log_type: + if ((0 == strcmp(cdatastrp, "Found it")) && + (0 == wpt_tmp->gc_data->last_found)) { + waypt_alloc_gc_data(wpt_tmp)->last_found = gc_log_date; + } + gc_log_date = 0; + break; + + /* + * Garmin-waypoint-specific tags. + */ + case tt_garmin_wpt_proximity: + case tt_garmin_wpt_temperature: + case tt_garmin_wpt_depth: + case tt_garmin_wpt_display_mode: + case tt_garmin_wpt_category: + case tt_garmin_wpt_addr: + case tt_garmin_wpt_city: + case tt_garmin_wpt_state: + case tt_garmin_wpt_country: + case tt_garmin_wpt_postal_code: + case tt_garmin_wpt_phone_nr: + garmin_fs_xml_convert(tt_garmin_wpt_extensions, tag, cdatastrp, wpt_tmp); + break; + + /* + * Humminbird-waypoint-specific tags. + */ + case tt_humminbird_wpt_depth: + case tt_humminbird_trk_trkseg_trkpt_depth: + WAYPT_SET(wpt_tmp, depth, atof(cdatastrp) / 100.0) + break; + /* + * Route-specific tags. + */ + case tt_rte_name: + rte_head->rte_name = xstrdup(cdatastrp); + break; + case tt_rte: + break; + case tt_rte_rtept: + route_add_wpt(rte_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_rte_desc: + rte_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_rte_number: + rte_head->rte_num = atoi(cdatastrp); + break; + /* + * Track-specific tags. + */ + case tt_trk_name: + trk_head->rte_name = xstrdup(cdatastrp); + break; + case tt_trk: + break; + case tt_trk_trkseg: + next_trkpt_is_new_seg = 1; + break; + case tt_trk_trkseg_trkpt: + track_add_wpt(trk_head, wpt_tmp); + wpt_tmp = NULL; + break; + case tt_trk_desc: + trk_head->rte_desc = xstrdup(cdatastrp); + break; + case tt_trk_number: + trk_head->rte_num = atoi(cdatastrp); + break; + case tt_trk_trkseg_trkpt_course: + WAYPT_SET(wpt_tmp, course, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_speed: + WAYPT_SET(wpt_tmp, speed, atof(cdatastrp)); + break; + case tt_trk_trkseg_trkpt_heartrate: + wpt_tmp->heartrate = atof(cdatastrp); + break; + case tt_trk_trkseg_trkpt_cadence: + wpt_tmp->cadence = atof(cdatastrp); + break; + + /* + * Items that are actually in multiple categories. + */ + case tt_wpt_ele: + case tt_rte_rtept_ele: + case tt_trk_trkseg_trkpt_ele: + sscanf(cdatastrp, "%lf", &wpt_tmp->altitude); + break; + case tt_wpt_name: + case tt_rte_rtept_name: + case tt_trk_trkseg_trkpt_name: + wpt_tmp->shortname = xstrdup(cdatastrp); + break; + case tt_wpt_sym: + case tt_rte_rtept_sym: + case tt_trk_trkseg_trkpt_sym: + wpt_tmp->icon_descr = xstrdup(cdatastrp); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case tt_wpt_time: + case tt_trk_trkseg_trkpt_time: + case tt_rte_rtept_time: + wpt_tmp->creation_time = xml_parse_time(cdatastrp, &wpt_tmp->microseconds); + break; + case tt_wpt_cmt: + case tt_rte_rtept_cmt: + case tt_trk_trkseg_trkpt_cmt: + wpt_tmp->description = xstrdup(cdatastrp); + break; + case tt_wpt_desc: + case tt_trk_trkseg_trkpt_desc: + case tt_rte_rtept_desc: + if (wpt_tmp->notes != NULL) { + xfree(wpt_tmp->notes); + } + wpt_tmp->notes = xstrdup(cdatastrp); + break; + case tt_pdop: + wpt_tmp->pdop = atof(cdatastrp); + break; + case tt_hdop: + wpt_tmp->hdop = atof(cdatastrp); + break; + case tt_vdop: + wpt_tmp->vdop = atof(cdatastrp); + break; + case tt_sat: + wpt_tmp->sat = atof(cdatastrp); + break; + case tt_fix: + wpt_tmp->fix = atoi(cdatastrp)-1; + if (wpt_tmp->fix < fix_2d) { + if (!case_ignore_strcmp(cdatastrp, "none")) { + wpt_tmp->fix = fix_none; + } else if (!case_ignore_strcmp(cdatastrp, "dgps")) { + wpt_tmp->fix = fix_dgps; + } else if (!case_ignore_strcmp(cdatastrp, "pps")) { + wpt_tmp->fix = fix_pps; + } else { + wpt_tmp->fix = fix_unknown; + } + } + break; + case tt_wpt_url: + case tt_trk_trkseg_trkpt_url: + case tt_rte_rtept_url: + wpt_tmp->url = xstrdup(cdatastrp); + break; + case tt_wpt_urlname: + case tt_trk_trkseg_trkpt_urlname: + case tt_rte_rtept_urlname: + wpt_tmp->url_link_text = xstrdup(cdatastrp); + break; + case tt_wpt_link: +//TODO: implement GPX 1.1 case tt_trk_trkseg_trkpt_link: +//TODO: implement GPX 1.1 case tt_rte_rtept_link: + { + char *lt = link_text; + if (lt) { + lt = xstrdup(lrtrim(link_text)); + } + + waypt_add_url(wpt_tmp, xstrdup(link_url), lt); + link_text = NULL; + } + break; + case tt_unknown: + end_something_else(); + *s = 0; + return; + default: + break; + } + + if (passthrough) { + end_something_else(); + } + + *s = 0; + xml_free_converted_string(el); } #if ! HAVE_LIBEXPAT static void gpx_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } -static void -gpx_rd_deinit(void) +static void +gpx_rd_deinit(void) { } @@ -1199,327 +1198,325 @@ gpx_rd_deinit(void) static void gpx_cdata(void *dta, const XML_Char *xml_el, int len) { - char *estr; - int *cdatalen; - char **cdata; - xml_tag *tmp_tag; - size_t slen = strlen(cdatastr.mem); - const char *s = xml_convert_to_char_string_n(xml_el, &len); - - vmem_realloc(&cdatastr, 1 + len + slen); - estr = ((char *) cdatastr.mem) + slen; - memcpy(estr, s, len); - estr[len] = 0; - - if (!cur_tag) - return; - - if ( cur_tag->child ) { - tmp_tag = cur_tag->child; - while ( tmp_tag->sibling ) { - tmp_tag = tmp_tag->sibling; - } - cdata = &(tmp_tag->parentcdata); - cdatalen = &(tmp_tag->parentcdatalen); - } - else { - cdata = &(cur_tag->cdata); - cdatalen = &(cur_tag->cdatalen); - } - estr = *cdata; - *cdata = xrealloc(*cdata, *cdatalen + len + 1); - estr = *cdata + *cdatalen; - memcpy( estr, s, len ); - *(estr+len) = '\0'; - *cdatalen += len; - - xml_free_converted_string(s); + char *estr; + int *cdatalen; + char **cdata; + xml_tag *tmp_tag; + size_t slen = strlen(cdatastr.mem); + const char *s = xml_convert_to_char_string_n(xml_el, &len); + + vmem_realloc(&cdatastr, 1 + len + slen); + estr = ((char *) cdatastr.mem) + slen; + memcpy(estr, s, len); + estr[len] = 0; + + if (!cur_tag) { + return; + } + + if (cur_tag->child) { + tmp_tag = cur_tag->child; + while (tmp_tag->sibling) { + tmp_tag = tmp_tag->sibling; + } + cdata = &(tmp_tag->parentcdata); + cdatalen = &(tmp_tag->parentcdatalen); + } else { + cdata = &(cur_tag->cdata); + cdatalen = &(cur_tag->cdatalen); + } + estr = *cdata; + *cdata = xrealloc(*cdata, *cdatalen + len + 1); + estr = *cdata + *cdatalen; + memcpy(estr, s, len); + *(estr+len) = '\0'; + *cdatalen += len; + + xml_free_converted_string(s); } static void gpx_rd_init(const char *fname) { - if ( fname[0] ) { - fd = gbfopen(fname, "r", MYNAME); - input_fname = fname; - } - else { - fd = NULL; - input_string = fname+1; - input_string_len = strlen(input_string); - input_fname = NULL; - } - - - file_time = 0; - current_tag = vmem_alloc(1, 0); - *((char *)current_tag.mem) = '\0'; - - prescan_tags(); - - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; - - if (!xsi_schema_loc) { - xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); - } - if (!xsi_schema_loc) { - fatal("gpx: Unable to allocate %ld bytes of memory.\n", - (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); - } - - if (NULL == gpx_global) { - gpx_global = xcalloc(sizeof(*gpx_global), 1); - QUEUE_INIT(&gpx_global->name.queue); - QUEUE_INIT(&gpx_global->desc.queue); - QUEUE_INIT(&gpx_global->author.queue); - QUEUE_INIT(&gpx_global->email.queue); - QUEUE_INIT(&gpx_global->url.queue); - QUEUE_INIT(&gpx_global->urlname.queue); - QUEUE_INIT(&gpx_global->keywords.queue); - } - - XML_SetElementHandler(psr, gpx_start, gpx_end); - XML_SetCharacterDataHandler(psr, gpx_cdata); - fs_ptr = NULL; + if (fname[0]) { + fd = gbfopen(fname, "r", MYNAME); + input_fname = fname; + } else { + fd = NULL; + input_string = fname+1; + input_string_len = strlen(input_string); + input_fname = NULL; + } + + + file_time = 0; + current_tag = vmem_alloc(1, 0); + *((char *)current_tag.mem) = '\0'; + + prescan_tags(); + + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; + + if (!xsi_schema_loc) { + xsi_schema_loc = xstrdup(DEFAULT_XSI_SCHEMA_LOC); + } + if (!xsi_schema_loc) { + fatal("gpx: Unable to allocate %ld bytes of memory.\n", + (unsigned long) strlen(DEFAULT_XSI_SCHEMA_LOC) + 1); + } + + if (NULL == gpx_global) { + gpx_global = xcalloc(sizeof(*gpx_global), 1); + QUEUE_INIT(&gpx_global->name.queue); + QUEUE_INIT(&gpx_global->desc.queue); + QUEUE_INIT(&gpx_global->author.queue); + QUEUE_INIT(&gpx_global->email.queue); + QUEUE_INIT(&gpx_global->url.queue); + QUEUE_INIT(&gpx_global->urlname.queue); + QUEUE_INIT(&gpx_global->keywords.queue); + } + + XML_SetElementHandler(psr, gpx_start, gpx_end); + XML_SetCharacterDataHandler(psr, gpx_cdata); + fs_ptr = NULL; } -static -void -gpx_rd_deinit(void) +static +void +gpx_rd_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - /* - * Don't free schema_loc. It really is important that we preserve - * this across reads or else merges/copies of files with different - * schemas won't retain the headers. - * - * moved to gpx_exit - - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - */ - - if ( gpx_email ) { - xfree(gpx_email); - gpx_email = NULL; - } - if ( gpx_author ) { - xfree(gpx_author); - gpx_author = NULL; - } - if (fd) { - gbfclose(fd); - } - XML_ParserFree(psr); - psr = NULL; - wpt_tmp = NULL; - cur_tag = NULL; - input_fname = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + /* + * Don't free schema_loc. It really is important that we preserve + * this across reads or else merges/copies of files with different + * schemas won't retain the headers. + * + * moved to gpx_exit + + if ( xsi_schema_loc ) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + */ + + if (gpx_email) { + xfree(gpx_email); + gpx_email = NULL; + } + if (gpx_author) { + xfree(gpx_author); + gpx_author = NULL; + } + if (fd) { + gbfclose(fd); + } + XML_ParserFree(psr); + psr = NULL; + wpt_tmp = NULL; + cur_tag = NULL; + input_fname = NULL; } #endif static void gpx_wr_init(const char *fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void gpx_wr_deinit(void) { - gbfclose(ofd); - mkshort_del_handle(&mkshort_handle); + gbfclose(ofd); + mkshort_del_handle(&mkshort_handle); } void gpx_read(void) { #if HAVE_LIBEXPAT - int len; - int done = 0; - char *buf = xmalloc(MY_CBUF_SZ); - int result = 0; - int extra; - - while (!done) { - if ( fd ) { - /* - * The majority of this block (in fact, all but the - * call to XML_Parse) are a disgusting hack to - * correct defective GPX files that Geocaching.com - * issues as pocket queries. They contain escape - * characters as entities (�-) which makes - * them not validate which croaks expat and torments - * users. - * - * Look for '&' in the last maxentlength chars. If - * we find it, strip it, then read byte-at-a-time - * until we find a non-entity. - */ - char *badchar; - char *semi; - int maxentlength = 8; - len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); - done = gbfeof(fd) || !len; - buf[len] = '\0'; - if (len < maxentlength) { - maxentlength = len; - } - badchar = buf+len-maxentlength; - badchar = strchr( badchar, '&' ); - extra = maxentlength - 1; /* for terminator */ - while ( badchar && len < MY_CBUF_SZ-1) { - semi = strchr( badchar, ';'); - while ( extra && !semi ) { - len += gbfread( buf+len, 1, 1, fd); - buf[len]='\0'; - extra--; - if ( buf[len-1] == ';') - semi= buf+len-1; - } - badchar = strchr( badchar+1, '&' ); - } - { - char hex[]="0123456789abcdef"; - badchar = strstr( buf, "&#x" ); - while ( badchar ) { - int val = 0; - char *hexit = badchar+3; - semi = strchr( badchar, ';' ); - if ( semi ) { - while (*hexit && *hexit != ';') { - char hc = isalpha(*hexit) ? tolower (*hexit) : *hexit; - val *= 16; - val += strchr( hex, hc)-hex; - hexit++; - } - - if ( val < 32 ) { - warning( MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)" ); - memmove( badchar, semi+1, strlen(semi+1)+1 ); - len -= (semi-badchar)+1; - badchar--; - } - } - badchar = strstr( badchar+1, "&#x" ); - } - } - result = XML_Parse(psr, buf, len, done); - } - else if (input_string) { - done = 0; - result = XML_Parse(psr, input_string, - input_string_len, done ); - done = 1; - } - else { - done = 1; - result = -1; - } - if (!result) { - fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", - (int) XML_GetCurrentLineNumber(psr), - input_fname ? input_fname : "unknown file", - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - xfree(buf); + int len; + int done = 0; + char *buf = xmalloc(MY_CBUF_SZ); + int result = 0; + int extra; + + while (!done) { + if (fd) { + /* + * The majority of this block (in fact, all but the + * call to XML_Parse) are a disgusting hack to + * correct defective GPX files that Geocaching.com + * issues as pocket queries. They contain escape + * characters as entities (�-) which makes + * them not validate which croaks expat and torments + * users. + * + * Look for '&' in the last maxentlength chars. If + * we find it, strip it, then read byte-at-a-time + * until we find a non-entity. + */ + char *badchar; + char *semi; + int maxentlength = 8; + len = gbfread(buf, 1, MY_CBUF_SZ - maxentlength, fd); + done = gbfeof(fd) || !len; + buf[len] = '\0'; + if (len < maxentlength) { + maxentlength = len; + } + badchar = buf+len-maxentlength; + badchar = strchr(badchar, '&'); + extra = maxentlength - 1; /* for terminator */ + while (badchar && len < MY_CBUF_SZ-1) { + semi = strchr(badchar, ';'); + while (extra && !semi) { + len += gbfread(buf+len, 1, 1, fd); + buf[len]='\0'; + extra--; + if (buf[len-1] == ';') { + semi= buf+len-1; + } + } + badchar = strchr(badchar+1, '&'); + } + { + char hex[]="0123456789abcdef"; + badchar = strstr(buf, "&#x"); + while (badchar) { + int val = 0; + char *hexit = badchar+3; + semi = strchr(badchar, ';'); + if (semi) { + while (*hexit && *hexit != ';') { + char hc = isalpha(*hexit) ? tolower(*hexit) : *hexit; + val *= 16; + val += strchr(hex, hc)-hex; + hexit++; + } + + if (val < 32) { + warning(MYNAME ": Ignoring illegal character %s;\n\tConsider emailing %s at <%s>\n\tabout illegal characters in their GPX files.\n", badchar, gpx_author?gpx_author:"(unknown author)", gpx_email?gpx_email:"(unknown email address)"); + memmove(badchar, semi+1, strlen(semi+1)+1); + len -= (semi-badchar)+1; + badchar--; + } + } + badchar = strstr(badchar+1, "&#x"); + } + } + result = XML_Parse(psr, buf, len, done); + } else if (input_string) { + done = 0; + result = XML_Parse(psr, input_string, + input_string_len, done); + done = 1; + } else { + done = 1; + result = -1; + } + if (!result) { + fatal(MYNAME ": XML parse error at line %d of '%s' : %s\n", + (int) XML_GetCurrentLineNumber(psr), + input_fname ? input_fname : "unknown file", + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + xfree(buf); #endif /* HAVE_LIBEXPAT */ } static void -fprint_tag_and_attrs( const char *prefix, const char *suffix, xml_tag *tag ) +fprint_tag_and_attrs(const char *prefix, const char *suffix, xml_tag *tag) { - char **pa; - gbfprintf( ofd, "%s%s", prefix, tag->tagname ); - pa = tag->attributes; - if ( pa ) { - while ( *pa ) { - gbfprintf( ofd, " %s=\"%s\"", pa[0], pa[1] ); - pa += 2; - } - } - gbfprintf( ofd, "%s", suffix ); + char **pa; + gbfprintf(ofd, "%s%s", prefix, tag->tagname); + pa = tag->attributes; + if (pa) { + while (*pa) { + gbfprintf(ofd, " %s=\"%s\"", pa[0], pa[1]); + pa += 2; + } + } + gbfprintf(ofd, "%s", suffix); } static void -fprint_xml_chain( xml_tag *tag, const waypoint *wpt ) +fprint_xml_chain(xml_tag *tag, const waypoint *wpt) { - char *tmp_ent; - while ( tag ) { - if ( !tag->cdata && !tag->child ) { - fprint_tag_and_attrs( "<", " />", tag ); - } - else { - fprint_tag_and_attrs( "<", ">", tag ); - - if ( tag->cdata ) { - tmp_ent = xml_entitize( tag->cdata ); - gbfprintf( ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - if ( tag->child ) { - fprint_xml_chain(tag->child, wpt); - } - if ( wpt && wpt->gc_data->exported && - strcmp(tag->tagname, "groundspeak:cache" ) == 0 ) { - xml_write_time( ofd, wpt->gc_data->exported, 0, - "groundspeak:exported" ); - } - gbfprintf( ofd, "\n", tag->tagname); - } - if ( tag->parentcdata ) { - tmp_ent = xml_entitize(tag->parentcdata); - gbfprintf(ofd, "%s", tmp_ent ); - xfree(tmp_ent); - } - tag = tag->sibling; - } -} - -void free_gpx_extras( xml_tag *tag ) + char *tmp_ent; + while (tag) { + if (!tag->cdata && !tag->child) { + fprint_tag_and_attrs("<", " />", tag); + } else { + fprint_tag_and_attrs("<", ">", tag); + + if (tag->cdata) { + tmp_ent = xml_entitize(tag->cdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + if (tag->child) { + fprint_xml_chain(tag->child, wpt); + } + if (wpt && wpt->gc_data->exported && + strcmp(tag->tagname, "groundspeak:cache") == 0) { + xml_write_time(ofd, wpt->gc_data->exported, 0, + "groundspeak:exported"); + } + gbfprintf(ofd, "\n", tag->tagname); + } + if (tag->parentcdata) { + tmp_ent = xml_entitize(tag->parentcdata); + gbfprintf(ofd, "%s", tmp_ent); + xfree(tmp_ent); + } + tag = tag->sibling; + } +} + +void free_gpx_extras(xml_tag *tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag *next = NULL; + char **ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } /* @@ -1528,31 +1525,31 @@ void free_gpx_extras( xml_tag *tag ) static void write_gpx_url(const waypoint *waypointp) { - char *tmp_ent; - - if (waypointp->url == NULL) { - return; - } - - if (gpx_wversion_num > 10) { - url_link *tail; - for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { - tmp_ent = xml_entitize(tail->url); - gbfprintf(ofd, " \n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "text", - tail->url_link_text); - gbfprintf(ofd, " \n"); - xfree(tmp_ent); - } - } else { - tmp_ent = xml_entitize(waypointp->url); - gbfprintf(ofd, " %s%s\n", - urlbase ? urlbase : "", tmp_ent); - write_optional_xml_entity(ofd, " ", "urlname", - waypointp->url_link_text); - xfree(tmp_ent); - } + char *tmp_ent; + + if (waypointp->url == NULL) { + return; + } + + if (gpx_wversion_num > 10) { + url_link *tail; + for (tail = (url_link *)&waypointp->url_next; tail; tail = tail->url_next) { + tmp_ent = xml_entitize(tail->url); + gbfprintf(ofd, " \n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "text", + tail->url_link_text); + gbfprintf(ofd, " \n"); + xfree(tmp_ent); + } + } else { + tmp_ent = xml_entitize(waypointp->url); + gbfprintf(ofd, " %s%s\n", + urlbase ? urlbase : "", tmp_ent); + write_optional_xml_entity(ofd, " ", "urlname", + waypointp->url_link_text); + xfree(tmp_ent); + } } /* @@ -1563,456 +1560,475 @@ write_gpx_url(const waypoint *waypointp) static void gpx_write_common_acc(const waypoint *waypointp, const char *indent) { - const char *fix = NULL; - - switch (waypointp->fix) { - case fix_2d: - fix = "2d"; - break; - case fix_3d: - fix = "3d"; - break; - case fix_dgps: - fix = "dgps"; - break; - case fix_pps: - fix = "pps"; - break; - case fix_none: - fix = "none"; - break; - /* GPX spec says omit if we don't know. */ - case fix_unknown: - default: - break; - } - if (fix) { - gbfprintf(ofd, "%s%s\n", indent, fix); - } - if (waypointp->sat > 0) { - gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); - } - if (waypointp->hdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); - } - if (waypointp->vdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); - } - if (waypointp->pdop) { - gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); - } + const char *fix = NULL; + + switch (waypointp->fix) { + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + case fix_none: + fix = "none"; + break; + /* GPX spec says omit if we don't know. */ + case fix_unknown: + default: + break; + } + if (fix) { + gbfprintf(ofd, "%s%s\n", indent, fix); + } + if (waypointp->sat > 0) { + gbfprintf(ofd, "%s%d\n", indent, waypointp->sat); + } + if (waypointp->hdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->hdop); + } + if (waypointp->vdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->vdop); + } + if (waypointp->pdop) { + gbfprintf(ofd, "%s%f\n", indent, waypointp->pdop); + } } static void gpx_write_common_position(const waypoint *waypointp, const char *indent) { - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, "%s%f\n", - indent, waypointp->altitude); - } - if (waypointp->creation_time) { - gbfprintf(ofd, indent); - xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); - } + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, "%s%f\n", + indent, waypointp->altitude); + } + if (waypointp->creation_time) { + gbfprintf(ofd, indent); + xml_write_time(ofd, waypointp->creation_time, waypointp->microseconds, "time"); + } } static void gpx_write_common_extensions(const waypoint *waypointp, const char *indent) { - if (((opt_humminbirdext || opt_garminext) && (waypointp->depth != 0 || waypointp->temperature != 0)) - || (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0))) { - gbfprintf(ofd, "%s\n", indent); - if (waypointp->depth != 0) { - if (opt_humminbirdext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->depth*100.0); - if (opt_garminext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->depth); - } - if (waypointp->temperature != 0) { - if (opt_humminbirdext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->temperature); - if (opt_garminext) - gbfprintf(ofd, "%s %f\n", - indent, waypointp->temperature); - } - if (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0)) { - gbfprintf(ofd, "%s \n", indent); - if (waypointp->heartrate != 0) - gbfprintf(ofd, "%s %u\n", - indent, waypointp->heartrate); - if (waypointp->cadence != 0) - gbfprintf(ofd, "%s %u\n", - indent, waypointp->cadence); - gbfprintf(ofd, "%s \n", indent); - } - gbfprintf(ofd, "%s\n", indent); - } + if (((opt_humminbirdext || opt_garminext) && (waypointp->depth != 0 || waypointp->temperature != 0)) + || (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0))) { + gbfprintf(ofd, "%s\n", indent); + if (waypointp->depth != 0) { + if (opt_humminbirdext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->depth*100.0); + if (opt_garminext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->depth); + } + if (waypointp->temperature != 0) { + if (opt_humminbirdext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->temperature); + if (opt_garminext) + gbfprintf(ofd, "%s %f\n", + indent, waypointp->temperature); + } + if (opt_garminext && (waypointp->heartrate != 0 || waypointp->cadence != 0)) { + gbfprintf(ofd, "%s \n", indent); + if (waypointp->heartrate != 0) + gbfprintf(ofd, "%s %u\n", + indent, waypointp->heartrate); + if (waypointp->cadence != 0) + gbfprintf(ofd, "%s %u\n", + indent, waypointp->cadence); + gbfprintf(ofd, "%s \n", indent); + } + gbfprintf(ofd, "%s\n", indent); + } } static void gpx_write_common_description(const waypoint *waypointp, const char *indent, - const char *oname) + const char *oname) { - write_optional_xml_entity(ofd, indent, "name", oname); - write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); - if (waypointp->notes && waypointp->notes[0]) - write_xml_entity(ofd, indent, "desc", waypointp->notes); - else - write_optional_xml_entity(ofd, indent, "desc", waypointp->description); - write_gpx_url(waypointp); - write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); + write_optional_xml_entity(ofd, indent, "name", oname); + write_optional_xml_entity(ofd, indent, "cmt", waypointp->description); + if (waypointp->notes && waypointp->notes[0]) { + write_xml_entity(ofd, indent, "desc", waypointp->notes); + } else { + write_optional_xml_entity(ofd, indent, "desc", waypointp->description); + } + write_gpx_url(waypointp); + write_optional_xml_entity(ofd, indent , "sym", waypointp->icon_descr); } static void gpx_waypt_pr(const waypoint *waypointp) { - const char *oname; - char *odesc; - fs_xml *fs_gpx; - garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = waypointp->notes; - if (!odesc) { - odesc = waypointp->description; - } - if (!odesc) { - odesc = waypointp->shortname; - } - - oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", oname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - gmsd = GMSD_FIND(waypointp); - if ( fs_gpx ) { - if (! gmsd) fprint_xml_chain( fs_gpx->tag, waypointp ); - } - if (gmsd && (gpx_wversion_num > 10)) { - /* MapSource doesn't accepts extensions from 1.0 */ - garmin_fs_xml_fprint(ofd, waypointp); - } - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, "\n"); + const char *oname; + char *odesc; + fs_xml *fs_gpx; + garmin_fs_t *gmsd; /* gARmIN sPECIAL dATA */ + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = waypointp->notes; + if (!odesc) { + odesc = waypointp->description; + } + if (!odesc) { + odesc = waypointp->shortname; + } + + oname = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, odesc) : + waypointp->shortname; + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", oname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + gmsd = GMSD_FIND(waypointp); + if (fs_gpx) { + if (! gmsd) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + } + if (gmsd && (gpx_wversion_num > 10)) { + /* MapSource doesn't accepts extensions from 1.0 */ + garmin_fs_xml_fprint(ofd, waypointp); + } + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, "\n"); } static void gpx_track_hdr(const route_head *rte) { - fs_xml *fs_gpx; - current_trk_head = rte; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, "%d\n", rte->rte_num); - } - - if (gpx_wversion_num > 10) { - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } - } + fs_xml *fs_gpx; + current_trk_head = rte; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, "%d\n", rte->rte_num); + } + + if (gpx_wversion_num > 10) { + fs_gpx = (fs_xml *)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } + } } static void gpx_track_disp(const waypoint *waypointp) { - fs_xml *fs_gpx; - int first_in_trk; - first_in_trk = waypointp->Q.prev == ¤t_trk_head->waypoint_list; - - if (waypointp->wpt_flags.new_trkseg) { - if (!first_in_trk) { - gbfprintf(ofd, "\n"); - } - gbfprintf(ofd, "\n"); - } - - gbfprintf(ofd, "\n", - waypointp->latitude, - waypointp->longitude); - - gpx_write_common_position(waypointp, " "); - - /* These were accidentally removed from 1.1 */ - if (gpx_wversion_num == 10) { - if WAYPT_HAS(waypointp, course) { - gbfprintf(ofd, " %f\n", - waypointp->course); - } - if WAYPT_HAS(waypointp, speed) { - gbfprintf(ofd, " %f\n", - waypointp->speed); - } - } - - /* GPX doesn't require a name on output, so if we made one up - * on input, we might as well say nothing. - */ - gpx_write_common_description(waypointp, " ", - waypointp->wpt_flags.shortname_is_synthetic ? - NULL : waypointp->shortname); - gpx_write_common_acc(waypointp, " "); - - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } - - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, "\n"); + fs_xml *fs_gpx; + int first_in_trk; + first_in_trk = waypointp->Q.prev == ¤t_trk_head->waypoint_list; + + if (waypointp->wpt_flags.new_trkseg) { + if (!first_in_trk) { + gbfprintf(ofd, "\n"); + } + gbfprintf(ofd, "\n"); + } + + gbfprintf(ofd, "\n", + waypointp->latitude, + waypointp->longitude); + + gpx_write_common_position(waypointp, " "); + + /* These were accidentally removed from 1.1 */ + if (gpx_wversion_num == 10) { + if WAYPT_HAS(waypointp, course) { + gbfprintf(ofd, " %f\n", + waypointp->course); + } + if WAYPT_HAS(waypointp, speed) { + gbfprintf(ofd, " %f\n", + waypointp->speed); + } + } + + /* GPX doesn't require a name on output, so if we made one up + * on input, we might as well say nothing. + */ + gpx_write_common_description(waypointp, " ", + waypointp->wpt_flags.shortname_is_synthetic ? + NULL : waypointp->shortname); + gpx_write_common_acc(waypointp, " "); + + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } + + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, "\n"); } static void gpx_track_tlr(const route_head *rte) { - if (!QUEUE_EMPTY(¤t_trk_head->waypoint_list)) { - gbfprintf(ofd, "\n"); - } - gbfprintf(ofd, "\n"); - current_trk_head = NULL; + if (!QUEUE_EMPTY(¤t_trk_head->waypoint_list)) { + gbfprintf(ofd, "\n"); + } + gbfprintf(ofd, "\n"); + current_trk_head = NULL; } static void gpx_track_pr() { - track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); + track_disp_all(gpx_track_hdr, gpx_track_tlr, gpx_track_disp); } static void gpx_route_hdr(const route_head *rte) { - fs_xml *fs_gpx; - - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "name", rte->rte_name); - write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); - if (rte->rte_num) { - gbfprintf(ofd, " %d\n", rte->rte_num); - } - - if (gpx_wversion_num > 10) { - fs_gpx = (fs_xml *)fs_chain_find( rte->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, NULL ); - } - } + fs_xml *fs_gpx; + + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "name", rte->rte_name); + write_optional_xml_entity(ofd, " ", "desc", rte->rte_desc); + if (rte->rte_num) { + gbfprintf(ofd, " %d\n", rte->rte_num); + } + + if (gpx_wversion_num > 10) { + fs_gpx = (fs_xml *)fs_chain_find(rte->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, NULL); + } + } } static void gpx_route_disp(const waypoint *waypointp) { - fs_xml *fs_gpx; + fs_xml *fs_gpx; - gbfprintf(ofd, " \n", - waypointp->latitude, - waypointp->longitude); + gbfprintf(ofd, " \n", + waypointp->latitude, + waypointp->longitude); - gpx_write_common_position(waypointp, " "); - gpx_write_common_description(waypointp, " ", waypointp->shortname); - gpx_write_common_acc(waypointp, " "); + gpx_write_common_position(waypointp, " "); + gpx_write_common_description(waypointp, " ", waypointp->shortname); + gpx_write_common_acc(waypointp, " "); - fs_gpx = (fs_xml *)fs_chain_find( waypointp->fs, FS_GPX ); - if ( fs_gpx ) { - fprint_xml_chain( fs_gpx->tag, waypointp ); - } + fs_gpx = (fs_xml *)fs_chain_find(waypointp->fs, FS_GPX); + if (fs_gpx) { + fprint_xml_chain(fs_gpx->tag, waypointp); + } - gpx_write_common_extensions(waypointp, " "); - gbfprintf(ofd, " \n"); + gpx_write_common_extensions(waypointp, " "); + gbfprintf(ofd, " \n"); } static void gpx_route_tlr(const route_head *rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void gpx_route_pr() { - /* output routes */ - route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); + /* output routes */ + route_disp_all(gpx_route_hdr, gpx_route_tlr, gpx_route_disp); } static void gpx_waypt_bound_calc(const waypoint *waypointp) { - waypt_add_to_bounds(&all_bounds, waypointp); + waypt_add_to_bounds(&all_bounds, waypointp); } static void gpx_write_bounds(void) { - waypt_init_bounds(&all_bounds); - - waypt_disp_all(gpx_waypt_bound_calc); - route_disp_all(NULL, NULL, gpx_waypt_bound_calc); - track_disp_all(NULL, NULL, gpx_waypt_bound_calc); - - if (waypt_bounds_valid(&all_bounds)) { - gbfprintf(ofd, "\n", - all_bounds.min_lat, all_bounds.min_lon, - all_bounds.max_lat, all_bounds.max_lon); - } + waypt_init_bounds(&all_bounds); + + waypt_disp_all(gpx_waypt_bound_calc); + route_disp_all(NULL, NULL, gpx_waypt_bound_calc); + track_disp_all(NULL, NULL, gpx_waypt_bound_calc); + + if (waypt_bounds_valid(&all_bounds)) { + gbfprintf(ofd, "\n", + all_bounds.min_lat, all_bounds.min_lon, + all_bounds.max_lat, all_bounds.max_lon); + } } static void gpx_write(void) { - time_t now = 0; - int short_length; - - if (opt_humminbirdext || opt_garminext) - gpx_wversion = (char *)"1.1"; - - gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; - - if (gpx_wversion_num <= 0) { - fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); - } - - now = current_time(); - - short_length = atoi(snlen); - - if (suppresswhite) { - setshort_whitespace_ok(mkshort_handle, 0); - } - - setshort_length(mkshort_handle, short_length); - - gbfprintf(ofd, "\n", global_opts.charset_name); - gbfprintf(ofd, "\n", xsi_schema_loc); - } else { - gbfprintf(ofd, - " xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", - gpx_wversion[0], gpx_wversion[2], - gpx_wversion[0], gpx_wversion[2]); - } - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - gpx_write_gdata(&gpx_global->name, "name"); - gpx_write_gdata(&gpx_global->desc, "desc"); - /* In GPX 1.1, author changed from a string to a PersonType. - * since it's optional, we just drop it instead of rewriting it. - */ - if (gpx_wversion_num < 11) { - gpx_write_gdata(&gpx_global->author, "author"); - } - gpx_write_gdata(&gpx_global->email, "email"); - gpx_write_gdata(&gpx_global->url, "url"); - gpx_write_gdata(&gpx_global->urlname, "urlname"); - xml_write_time( ofd, now, 0, "time" ); - gpx_write_gdata(&gpx_global->keywords, "keywords"); - - gpx_write_bounds(); - - if (gpx_wversion_num > 10) { - gbfprintf(ofd, "\n"); - } - - waypt_disp_all(gpx_waypt_pr); - gpx_route_pr(); - gpx_track_pr(); - - gbfprintf(ofd, "\n"); + time_t now = 0; + int short_length; + + if (opt_humminbirdext || opt_garminext) { + gpx_wversion = (char *)"1.1"; + } + + gpx_wversion_num = strtod(gpx_wversion, NULL) * 10; + + if (gpx_wversion_num <= 0) { + fatal(MYNAME ": gpx version number of '%s' not valid.\n", gpx_wversion); + } + + now = current_time(); + + short_length = atoi(snlen); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_handle, 0); + } + + setshort_length(mkshort_handle, short_length); + + gbfprintf(ofd, "\n", global_opts.charset_name); + gbfprintf(ofd, "\n", xsi_schema_loc); + } else { + gbfprintf(ofd, + " xsi:schemaLocation=" DEFAULT_XSI_SCHEMA_LOC_FMT">\n", + gpx_wversion[0], gpx_wversion[2], + gpx_wversion[0], gpx_wversion[2]); + } + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + gpx_write_gdata(&gpx_global->name, "name"); + gpx_write_gdata(&gpx_global->desc, "desc"); + /* In GPX 1.1, author changed from a string to a PersonType. + * since it's optional, we just drop it instead of rewriting it. + */ + if (gpx_wversion_num < 11) { + gpx_write_gdata(&gpx_global->author, "author"); + } + gpx_write_gdata(&gpx_global->email, "email"); + gpx_write_gdata(&gpx_global->url, "url"); + gpx_write_gdata(&gpx_global->urlname, "urlname"); + xml_write_time(ofd, now, 0, "time"); + gpx_write_gdata(&gpx_global->keywords, "keywords"); + + gpx_write_bounds(); + + if (gpx_wversion_num > 10) { + gbfprintf(ofd, "\n"); + } + + waypt_disp_all(gpx_waypt_pr); + gpx_route_pr(); + gpx_track_pr(); + + gbfprintf(ofd, "\n"); } static void gpx_free_gpx_global(void) { - gpx_rm_from_global(&gpx_global->name); - gpx_rm_from_global(&gpx_global->desc); - gpx_rm_from_global(&gpx_global->author); - gpx_rm_from_global(&gpx_global->email); - gpx_rm_from_global(&gpx_global->url); - gpx_rm_from_global(&gpx_global->urlname); - gpx_rm_from_global(&gpx_global->keywords); - xfree(gpx_global); + gpx_rm_from_global(&gpx_global->name); + gpx_rm_from_global(&gpx_global->desc); + gpx_rm_from_global(&gpx_global->author); + gpx_rm_from_global(&gpx_global->email); + gpx_rm_from_global(&gpx_global->url); + gpx_rm_from_global(&gpx_global->urlname); + gpx_rm_from_global(&gpx_global->keywords); + xfree(gpx_global); } static void gpx_exit(void) { - if ( xsi_schema_loc ) { - xfree(xsi_schema_loc); - xsi_schema_loc = NULL; - } - - if (gpx_global) { - gpx_free_gpx_global(); - gpx_global = NULL; - } + if (xsi_schema_loc) { + xfree(xsi_schema_loc); + xsi_schema_loc = NULL; + } + + if (gpx_global) { + gpx_free_gpx_global(); + gpx_global = NULL; + } } static arglist_t gpx_args[] = { - { "snlen", &snlen, "Length of generated shortnames", - "32", ARGTYPE_INT, "1", NULL }, - { "suppresswhite", &suppresswhite, - "No whitespace in generated shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logpoint", &opt_logpoint, - "Create waypoints from geocache log entries", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "urlbase", &urlbase, "Base URL for link tag in output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - { "gpxver", &gpx_wversion, "Target GPX version for output", - "1.0", ARGTYPE_STRING, ARG_NOMINMAX}, - { "humminbirdextensions", &opt_humminbirdext, - "Add info (depth) as Humminbird extension", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - { "garminextensions", &opt_garminext, - "Add info (depth) as Garmin extension", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "snlen", &snlen, "Length of generated shortnames", + "32", ARGTYPE_INT, "1", NULL + }, + { + "suppresswhite", &suppresswhite, + "No whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logpoint", &opt_logpoint, + "Create waypoints from geocache log entries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &urlbase, "Base URL for link tag in output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "gpxver", &gpx_wversion, "Target GPX version for output", + "1.0", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "humminbirdextensions", &opt_humminbirdext, + "Add info (depth) as Humminbird extension", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "garminextensions", &opt_garminext, + "Add info (depth) as Garmin extension", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t gpx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gpx_rd_init, - gpx_wr_init, - gpx_rd_deinit, - gpx_wr_deinit, - gpx_read, - gpx_write, - gpx_exit, - gpx_args, - CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + gpx_rd_init, + gpx_wr_init, + gpx_rd_deinit, + gpx_wr_deinit, + gpx_read, + gpx_write, + gpx_exit, + gpx_args, + CET_CHARSET_UTF8, 0 /* non-fixed to create non UTF-8 XML's for testing | CET-REVIEW */ }; diff --git a/gpsbabel/grtcirc.c b/gpsbabel/grtcirc.c index 44ecf1adf..70f534e3a 100644 --- a/gpsbabel/grtcirc.c +++ b/gpsbabel/grtcirc.c @@ -25,16 +25,18 @@ static const double EARTH_RAD = 6378137.0; -static void crossproduct( double x1, double y1, double z1, - double x2, double y2, double z2, - double *xa, double *ya, double *za ) { - *xa = y1*z2-y2*z1; - *ya = z1*x2-z2*x1; - *za = x1*y2-y1*x2; +static void crossproduct(double x1, double y1, double z1, + double x2, double y2, double z2, + double *xa, double *ya, double *za) +{ + *xa = y1*z2-y2*z1; + *ya = z1*x2-z2*x1; + *za = x1*y2-y1*x2; } -static double dotproduct( double x1, double y1, double z1, - double x2, double y2, double z2 ) { +static double dotproduct(double x1, double y1, double z1, + double x2, double y2, double z2) +{ return (x1*x2+y1*y2+z1*z2); } @@ -49,140 +51,158 @@ static double dotproduct( double x1, double y1, double z1, * time, so why not leave the expression human-readable? */ -double radtomiles( double rads ) { - const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; - return (rads*radmiles); +double radtomiles(double rads) +{ + const double radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0; + return (rads*radmiles); } -double radtometers( double rads ) { - return ( rads * EARTH_RAD ); +double radtometers(double rads) +{ + return (rads * EARTH_RAD); } -double gcdist( double lat1, double lon1, double lat2, double lon2 ) +double gcdist(double lat1, double lon1, double lat2, double lon2) { - double res; - double sdlat, sdlon; + double res; + double sdlat, sdlon; - errno = 0; + errno = 0; - sdlat = sin((lat1 - lat2) / 2.0); - sdlon = sin((lon1 - lon2) / 2.0); + sdlat = sin((lat1 - lat2) / 2.0); + sdlon = sin((lon1 - lon2) / 2.0); - res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); + res = sqrt(sdlat * sdlat + cos(lat1) * cos(lat2) * sdlon * sdlon); - if (res > 1.0) { - res = 1.0; - } else if (res < -1.0) { - res = -1.0; - } + if (res > 1.0) { + res = 1.0; + } else if (res < -1.0) { + res = -1.0; + } - res = asin(res); + res = asin(res); - if ( + if ( #if defined isnan - /* This is a C99-ism. */ - (isnan(res)) || + /* This is a C99-ism. */ + (isnan(res)) || #endif - (errno == EDOM)) { /* this should never happen: */ - errno = 0; /* Math argument out of domain of + (errno == EDOM)) { /* this should never happen: */ + errno = 0; /* Math argument out of domain of function, */ - return 0; /* or value returned is not a number */ - } + return 0; /* or value returned is not a number */ + } - return 2.0 * res; + return 2.0 * res; } -/* This value is the heading you'd leave point 1 at to arrive at point 2. +/* This value is the heading you'd leave point 1 at to arrive at point 2. * Inputs and outputs are in radians. */ -double heading( double lat1, double lon1, double lat2, double lon2 ) { +double heading(double lat1, double lon1, double lat2, double lon2) +{ double v1, v2; v1 = sin(lon1 - lon2) * cos(lat2); v2 = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon1 - lon2); /* rounding error protection */ - if (fabs(v1) < 1e-15) v1 = 0.0; - if (fabs(v2) < 1e-15) v2 = 0.0; + if (fabs(v1) < 1e-15) { + v1 = 0.0; + } + if (fabs(v2) < 1e-15) { + v2 = 0.0; + } return atan2(v1, v2); } /* As above, but outputs is in degrees from 0 - 359. Inputs are still radians. */ -double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ) +double heading_true_degrees(double lat1, double lon1, double lat2, double lon2) { double h = 360.0 - DEG(heading(lat1, lon1, lat2, lon2)); - if (h >= 360.0) h -= 360.0; + if (h >= 360.0) { + h -= 360.0; + } return h; } - + double linedist(double lat1, double lon1, - double lat2, double lon2, - double lat3, double lon3 ) { + double lat2, double lon2, + double lat3, double lon3) +{ static double _lat1 = -9999; static double _lat2 = -9999; static double _lon1 = -9999; static double _lon2 = -9999; - + static double x1,y1,z1; static double x2,y2,z2; static double xa,ya,za,la; - + double x3,y3,z3; double xp,yp,zp,lp; - + double xa1,ya1,za1; double xa2,ya2,za2; - + double d1, d2; double c1, c2; double dot; int newpoints; - + /* degrees to radians */ - lat1 = RAD(lat1); lon1 = RAD(lon1); - lat2 = RAD(lat2); lon2 = RAD(lon2); - lat3 = RAD(lat3); lon3 = RAD(lon3); + lat1 = RAD(lat1); + lon1 = RAD(lon1); + lat2 = RAD(lat2); + lon2 = RAD(lon2); + lat3 = RAD(lat3); + lon3 = RAD(lon3); newpoints = 1; - if ( lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { + if (lat1 == _lat1 && lat2 == _lat2 && lon1 == _lon1 && lon2 == _lon2) { newpoints = 0; - } - else { + } else { _lat1 = lat1; _lat2 = lat2; _lon1 = lon1; _lon2 = lon2; } - + /* polar to ECEF rectangular */ - if ( newpoints ) { - x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); - x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + if (newpoints) { + x1 = cos(lon1)*cos(lat1); + y1 = sin(lat1); + z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); + y2 = sin(lat2); + z2 = sin(lon2)*cos(lat2); } - x3 = cos(lon3)*cos(lat3); y3 = sin(lat3); z3 = sin(lon3)*cos(lat3); - - if ( newpoints ) { - /* 'a' is the axis; the line that passes through the center of the earth - * and is perpendicular to the great circle through point 1 and point 2 - * It is computed by taking the cross product of the '1' and '2' vectors.*/ - crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + x3 = cos(lon3)*cos(lat3); + y3 = sin(lat3); + z3 = sin(lon3)*cos(lat3); + + if (newpoints) { + /* 'a' is the axis; the line that passes through the center of the earth + * and is perpendicular to the great circle through point 1 and point 2 + * It is computed by taking the cross product of the '1' and '2' vectors.*/ + crossproduct(x1, y1, z1, x2, y2, z2, &xa, &ya, &za); la = sqrt(xa*xa+ya*ya+za*za); - if ( la ) { + if (la) { xa /= la; ya /= la; za /= la; } } - if ( la ) { + if (la) { /* dot is the component of the length of '3' that is along the axis. - * What's left is a non-normalized vector that lies in the plane of + * What's left is a non-normalized vector that lies in the plane of * 1 and 2. */ - + dot = dotproduct(x3,y3,z3,xa,ya,za); xp = x3-dot*xa; @@ -191,97 +211,94 @@ double linedist(double lat1, double lon1, lp = sqrt(xp*xp+yp*yp+zp*zp); - if ( lp ) { + if (lp) { /* After this, 'p' is normalized */ xp /= lp; yp /= lp; zp /= lp; - - crossproduct(x1,y1,z1,xp,yp,zp,&xa1,&ya1,&za1); - d1 = dotproduct( xa1, ya1, za1, xa, ya, za ); + + crossproduct(x1,y1,z1,xp,yp,zp,&xa1,&ya1,&za1); + d1 = dotproduct(xa1, ya1, za1, xa, ya, za); crossproduct(xp,yp,zp,x2,y2,z2,&xa2,&ya2,&za2); - d2 = dotproduct( xa2, ya2, za2, xa, ya, za ); - - if ( d1 >= 0 && d2 >= 0 ) { - /* rather than call gcdist and all its sines and cosines and - * worse, we can get the angle directly. It's the arctangent - * of the length of the component of vector 3 along the axis - * divided by the length of the component of vector 3 in the - * plane. We already have both of those numbers. - * - * atan2 would be overkill because lp and fabs(dot) are both - * known to be positive. */ - - return atan( fabs(dot)/lp ); + d2 = dotproduct(xa2, ya2, za2, xa, ya, za); + + if (d1 >= 0 && d2 >= 0) { + /* rather than call gcdist and all its sines and cosines and + * worse, we can get the angle directly. It's the arctangent + * of the length of the component of vector 3 along the axis + * divided by the length of the component of vector 3 in the + * plane. We already have both of those numbers. + * + * atan2 would be overkill because lp and fabs(dot) are both + * known to be positive. */ + + return atan(fabs(dot)/lp); } - + /* otherwise, get the distance from the closest endpoint */ - c1 = dotproduct( x1,y1,z1,xp,yp,zp ); - c2 = dotproduct( x2,y2,z2,xp,yp,zp ); + c1 = dotproduct(x1,y1,z1,xp,yp,zp); + c2 = dotproduct(x2,y2,z2,xp,yp,zp); d1 = fabs(d1); d2 = fabs(d2); - + /* This is a hack. d$n$ is proportional to the sine of the angle * between point $n$ and point p. That preserves orderedness up * to an angle of 90 degrees. c$n$ is proportional to the cosine * of the same angle; if the angle is over 90 degrees, c$n$ is * negative. In that case, we flop the sine across the y=1 axis - * so that the resulting value increases as the angle increases. - * + * so that the resulting value increases as the angle increases. + * * This only works because all of the points are on a unit sphere. */ - if ( c1 < 0 ) { - d1 = 2 - d1; + if (c1 < 0) { + d1 = 2 - d1; } - if ( c2 < 0 ) { - d2 = 2 - d2; + if (c2 < 0) { + d2 = 2 - d2; } - if ( fabs(d1) < fabs(d2)) { - return gcdist(lat1,lon1,lat3,lon3); - } - else { + if (fabs(d1) < fabs(d2)) { + return gcdist(lat1,lon1,lat3,lon3); + } else { return gcdist(lat2,lon2,lat3,lon3); } - } - else { + } else { /* lp is 0 when 3 is 90 degrees from the great circle */ return M_PI/2; - } - } - else { + } + } else { /* la is 0 when 1 and 2 are either the same point or 180 degrees apart */ dot = dotproduct(x1,y1,z1,x2,y2,z2); - if ( dot >= 0 ) { + if (dot >= 0) { return gcdist(lat1,lon1,lat3,lon3); - } - else { + } else { return 0; } } return 0; } -/* - * Compute the position of a point partially along the geodesic from +/* + * Compute the position of a point partially along the geodesic from * lat1,lon1 to lat2,lon2 - * + * * Ref: http://mathworld.wolfram.com/RotationFormula.html */ void linepart(double lat1, double lon1, - double lat2, double lon2, - double frac, - double *reslat, double *reslon ) { + double lat2, double lon2, + double frac, + double *reslat, double *reslon) +{ double x1,y1,z1; double x2,y2,z2; double xa,ya,za,la; double xr, yr, zr; double xx, yx, zx; - + double theta = 0; double phi = 0; double cosphi = 0; @@ -290,59 +307,76 @@ void linepart(double lat1, double lon1, /* result must be in degrees */ *reslat = lat1; *reslon = lon1; - + /* degrees to radians */ - lat1 = RAD(lat1); lon1 = RAD(lon1); - lat2 = RAD(lat2); lon2 = RAD(lon2); + lat1 = RAD(lat1); + lon1 = RAD(lon1); + lat2 = RAD(lat2); + lon2 = RAD(lon2); /* polar to ECEF rectangular */ - x1 = cos(lon1)*cos(lat1); y1 = sin(lat1); z1 = sin(lon1)*cos(lat1); - x2 = cos(lon2)*cos(lat2); y2 = sin(lat2); z2 = sin(lon2)*cos(lat2); + x1 = cos(lon1)*cos(lat1); + y1 = sin(lat1); + z1 = sin(lon1)*cos(lat1); + x2 = cos(lon2)*cos(lat2); + y2 = sin(lat2); + z2 = sin(lon2)*cos(lat2); /* 'a' is the axis; the line that passes through the center of the earth - * and is perpendicular to the great circle through point 1 and point 2 + * and is perpendicular to the great circle through point 1 and point 2 * It is computed by taking the cross product of the '1' and '2' vectors.*/ - crossproduct( x1, y1, z1, x2, y2, z2, &xa, &ya, &za ); + crossproduct(x1, y1, z1, x2, y2, z2, &xa, &ya, &za); la = sqrt(xa*xa+ya*ya+za*za); - if ( la ) { + if (la) { xa /= la; ya /= la; za /= la; } - /* if la is zero, the points are either equal or directly opposite + /* if la is zero, the points are either equal or directly opposite * each other. Either way, there's no single geodesic, so we punt. */ - if ( la ) { - crossproduct( x1, y1, z1, xa, ya, za, &xx, &yx, &zx ); - - - theta = atan2( dotproduct(xx,yx,zx,x2,y2,z2), - dotproduct(x1,y1,z1,x2,y2,z2)); - + if (la) { + crossproduct(x1, y1, z1, xa, ya, za, &xx, &yx, &zx); + + + theta = atan2(dotproduct(xx,yx,zx,x2,y2,z2), + dotproduct(x1,y1,z1,x2,y2,z2)); + phi = frac * theta; cosphi = cos(phi); sinphi = sin(phi); - - + + /* The second term of the formula from the mathworld reference is always * zero, because r (lat1,lon1) is always perpendicular to n (a here) */ xr = x1*cosphi + xx * sinphi; yr = y1*cosphi + yx * sinphi; zr = z1*cosphi + zx * sinphi; - - if ( xr > 1 ) xr = 1; - if ( xr < -1 ) xr = -1; - if ( yr > 1 ) yr = 1; - if ( yr < -1 ) yr = -1; - if ( zr > 1 ) zr = 1; - if ( zr < -1 ) zr = -1; - + + if (xr > 1) { + xr = 1; + } + if (xr < -1) { + xr = -1; + } + if (yr > 1) { + yr = 1; + } + if (yr < -1) { + yr = -1; + } + if (zr > 1) { + zr = 1; + } + if (zr < -1) { + zr = -1; + } + *reslat = DEG(asin(yr)); - if( xr == 0 && zr == 0 ) { + if (xr == 0 && zr == 0) { *reslon = 0; + } else { + *reslon = DEG(atan2(zr, xr)); } - else { - *reslon = DEG(atan2( zr, xr )); - } } } diff --git a/gpsbabel/grtcirc.h b/gpsbabel/grtcirc.h index c47e77dd4..791fc4110 100644 --- a/gpsbabel/grtcirc.h +++ b/gpsbabel/grtcirc.h @@ -18,25 +18,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #ifndef GRTCIRC_H #define GRTCIRC_H -double gcdist( double lat1, double lon1, double lat2, double lon2 ); -double heading( double lat1, double lon1, double lat2, double lon2 ); -double heading_true_degrees( double lat1, double lon1, double lat2, double lon2 ); +double gcdist(double lat1, double lon1, double lat2, double lon2); +double heading(double lat1, double lon1, double lat2, double lon2); +double heading_true_degrees(double lat1, double lon1, double lat2, double lon2); double linedist(double lat1, double lon1, - double lat2, double lon2, - double lat3, double lon3 ); + double lat2, double lon2, + double lat3, double lon3); -double radtometers( double rads ); -double radtomiles( double rads ); +double radtometers(double rads); +double radtomiles(double rads); void linepart(double lat1, double lon1, - double lat2, double lon2, - double frac, - double *reslat, double *reslon ); + double lat2, double lon2, + double frac, + double *reslat, double *reslon); /* Degrees to radians */ #define DEG(x) ((x)*180.0/M_PI) diff --git a/gpsbabel/gtm.c b/gpsbabel/gtm.c index a1f7a2a5e..4db74f355 100644 --- a/gpsbabel/gtm.c +++ b/gpsbabel/gtm.c @@ -57,9 +57,9 @@ static int start_new; static short int fread_bool(gbfile *fd) { - char buf[2]; - gbfread(buf, 2, 1, fd); - return le_read16(buf) ? 1 : 0; + char buf[2]; + gbfread(buf, 2, 1, fd); + return le_read16(buf) ? 1 : 0; } #endif @@ -71,39 +71,43 @@ fread_bool(gbfile *fd) static char * fread_string(gbfile *fd) { - char *val; - int len = fread_integer(fd); - - if (len == 0) return NULL; - - val = xmalloc(len+1); - gbfread(val, 1, len, fd); - while (len != 0 && val[len-1] == ' ') - len--; - val[len] = 0; - return val; + char *val; + int len = fread_integer(fd); + + if (len == 0) { + return NULL; + } + + val = xmalloc(len+1); + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') { + len--; + } + val[len] = 0; + return val; } static void fread_string_discard(gbfile *fd) { - char *temp = fread_string(fd); + char *temp = fread_string(fd); - if (temp != NULL) { - xfree(temp); - } + if (temp != NULL) { + xfree(temp); + } } static char * fread_fixedstring(gbfile *fd, int len) { - char *val = xmalloc(len+1); - - gbfread(val, 1, len, fd); - while (len != 0 && val[len-1] == ' ') - len--; - val[len] = 0; - return val; + char *val = xmalloc(len+1); + + gbfread(val, 1, len, fd); + while (len != 0 && val[len-1] == ' ') { + len--; + } + val[len] = 0; + return val; } /* Write functions, according to specification. */ @@ -111,10 +115,10 @@ fread_fixedstring(gbfile *fd, int len) static void fwrite_null(gbfile *fd, int len) { - char buf[1024]; + char buf[1024]; - memset(buf, 0, len); - gbfwrite(buf, 1, len, fd); + memset(buf, 0, len); + gbfwrite(buf, 1, len, fd); } #define fwrite_byte(a,b) gbfputc((signed char)(b), a) @@ -127,27 +131,29 @@ fwrite_null(gbfile *fd, int len) static void fwrite_string(gbfile *fd, const char *str) { - if (str && str[0]) { - int len = strlen(str); - fwrite_integer(fd, len); - gbfwrite(str, 1, len, fd); - } - else { - fwrite_integer(fd, 0); - } + if (str && str[0]) { + int len = strlen(str); + fwrite_integer(fd, len); + gbfwrite(str, 1, len, fd); + } else { + fwrite_integer(fd, 0); + } } void fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) { - int len = str ? strlen(str) : 0; - - if (len > fieldlen) - len = fieldlen; - if (str) - gbfwrite(str, 1, len, fd); - for (; len != fieldlen; len++) - gbfputc(' ', fd); + int len = str ? strlen(str) : 0; + + if (len > fieldlen) { + len = fieldlen; + } + if (str) { + gbfwrite(str, 1, len, fd); + } + for (; len != fieldlen; len++) { + gbfputc(' ', fd); + } } /* Auxiliar functions */ @@ -155,204 +161,312 @@ fwrite_fixedstring(gbfile *fd, const char *str, int fieldlen) void set_datum(int n) { - indatum = -1; - if (n < 1) {} - else if (n < 8) { indatum = 0; } /* Adindan */ - else if (n < 9) { indatum = 1; } /* Afgooye */ - else if (n < 10) { indatum = 2; } /* Ain el Abd */ - else if (n < 14) {} - else if (n < 23) { indatum = 6; } /* ARC 1950 */ - else if (n < 26) { indatum = 7; } /* ARC 1960 */ - else if (n < 27) { indatum = 8; } /* Ascension Island 58 */ - else if (n < 32) {} - else if (n < 33) { indatum = 13; } /* Australian Geo 84 */ - else if (n < 34) {} - else if (n < 35) { indatum = 15; } /* Bellevue IGN */ - else if (n < 36) { indatum = 16; } /* Bermuda 1957 */ - else if (n < 38) {} - else if (n < 39) { indatum = 17; } /* Bukit Rimpah */ - else if (n < 40) { indatum = 18; } /* Camp Area Astro */ - else if (n < 41) { indatum = 19; } /* Campo Inchauspe */ - else if (n < 42) { indatum = 22; } /* Canton Islan 1966 */ - else if (n < 43) { indatum = 23; } /* Cape */ - else if (n < 44) { indatum = 24; } /* Cape Canaveral */ - else if (n < 45) { indatum = 26; } /* Carthe */ - else if (n < 46) { indatum = 28; } /* Chatham */ - else if (n < 47) { indatum = 29; } /* Chua Astro */ - else if (n < 48) { indatum = 30; } /* Corrego Alegre*/ - else if (n < 50) {} - else if (n < 51) { indatum = 33; } /* Djakarta (Batavia) */ - else if (n < 52) { indatum = 34; } /* DOS 1968 */ - else if (n < 53) { indatum = 35; } /* Easter Island 1967 */ - else if (n < 54) {} - else if (n < 69) { indatum = 38; } /* European 1950 Mean */ - else if (n < 70) { indatum = 39; } /* European 1979 Mean */ - else if (n < 71) {} - else if (n < 72) { indatum = 41; } /* Gandajika */ - else if (n < 73) { indatum = 42; } /* Geodetic Datum 49 */ - else if (n < 74) {} - else if (n < 75) { indatum = 45; } /* Guam 1963 */ - else if (n < 76) { indatum = 46; } /* Gunung Segara */ - else if (n < 77) {} - else if (n < 78) { indatum = 49; } /* Hearth North */ - else if (n < 79) {} - else if (n < 80) { indatum = 50; } /* Hjorsey 1955 */ - else if (n < 81) { indatum = 51; } /* Hong Kong 1963 */ - else if (n < 82) { indatum = 52; } /* Hu-Tzu-Shan */ - else if (n < 89) { indatum = 53; } /* Indian */ - else if (n < 90) {} - else if (n < 91) { indatum = 55; } /* Ireland 1965 */ - else if (n < 92) {} - else if (n < 93) { indatum = 56; } /* ISTS 073 69 */ - else if (n < 94) { indatum = 57; } /* Johnston Island 61 */ - else if (n < 95) { indatum = 58; } /* Kandawala */ - else if (n < 96) { indatum = 59; } /* Kerguelen Island */ - else if (n < 97) { indatum = 60; } /* Kertau 48 */ - else if (n < 99) {} - else if (n < 100) { indatum = 61; } /* L.C. 5 Astro */ - else if (n < 101) {} - else if (n < 102) { indatum = 63; } /* Liberia 1964 */ - else if (n < 104) { indatum = 64; } /* Luzon */ - else if (n < 105) {} - else if (n < 106) { indatum = 65; } /* Mahe 1971 */ - else if (n < 107) {} - else if (n < 108) { indatum = 69; } /* Merchich */ - else if (n < 109) { indatum = 71; } /* Midway Astro 61 */ - else if (n < 111) { indatum = 73; } /* Minna */ - else if (n < 112) {} - else if (n < 115) { indatum = 75; } /* Nahrwan */ - else if (n < 116) { indatum = 76; } /* Naparima BWI */ - else if (n < 116) {} - else if (n < 119) { indatum = 3; } /* Alaska NAD27 */ - else if (n < 121) { indatum = 14; } /* Bahamas NAD27 */ - else if (n < 126) { indatum = 20; } /* Canada Mean NAD27 */ - else if (n < 127) { indatum = 21; } /* Canal Zone NAD27 */ - else if (n < 128) { indatum = 31; } /* Cuba NAD27 */ - else if (n < 129) { indatum = 44; } /* Greenland NAD27 */ - else if (n < 131) {} - else if (n < 132) { indatum = 20; } /* Canada Mean NAD27 */ - else if (n < 135) {} - else if (n < 136) { indatum = 70; } /* Mexico NAD27 */ - else if (n < 144) {} - else if (n < 145) { indatum = 80; } /* Old Egyptian */ - else if (n < 146) { indatum = 81; } /* Old Hawaiian */ - else if (n < 147) { indatum = 82; } /* Old Hawaiian Kauai */ - else if (n < 148) { indatum = 83; } /* Old Hawaiian Maui */ - else if (n < 149) { indatum = 81; } /* Old Hawaiian Mean */ - else if (n < 150) { indatum = 84; } /* Old Hawaiian Oahu */ - else if (n < 151) { indatum = 85; } /* Oman */ - else if (n < 156) { indatum = 86; } /* OSG Britain */ - else if (n < 157) { indatum = 87; } /* Pico de Las Nieves */ - else if (n < 158) { indatum = 88; } /* Pitcairn Astro 67 */ - else if (n < 171) {} - else if (n < 172) { indatum = 91; } /* Puerto Rico */ - else if (n < 173) { indatum = 92; } /* Pulkovo 1942 */ - else if (n < 174) { indatum = 94; } /* Quatar National */ - else if (n < 176) {} - else if (n < 177) { indatum = 95; } /* Rome 1940 */ - else if (n < 184) { indatum = 96; } /* S-42 (Pulkovo 1942) */ - else if (n < 185) {} - else if (n < 186) { indatum = 100; } /* Santo DOS */ - else if (n < 187) { indatum = 99; } /* Sao Braz */ - else if (n < 191) {} - else if (n < 193) { indatum = 105; } /* SAD-69/Mean */ - else if (n < 194) { indatum = 98; } /* SAD-69/Brazil */ - else if (n < 204) { indatum = 105; } /* SAD-69/Mean */ - else if (n < 205) { indatum = 106; } /* South Asia */ - else if (n < 206) { indatum = 109; } /* Tananarive 1926 */ - else if (n < 207) { indatum = 111; } /* Timbalai 1948 */ - else if (n < 211) { indatum = 112; } /* Tokyo mean */ - else if (n < 212) { indatum = 113; } /* Tristan Astro 1968 */ - else if (n < 213) { indatum = 115; } /* Viti Levu 1916 */ - else if (n < 215) {} - else if (n < 216) { indatum = 116; } /* Wake Eniwetok 1960 */ - else if (n < 217) { indatum = 117; } /* WGS 72 */ - else if (n < 218) { indatum = 118; } /* WGS 84 */ - else if (n < 219) { indatum = 119; } /* Yacare */ - else if (n < 220) { indatum = 120; } /* Zanderij */ - else if (n < 231) {} - else if (n < 232) { indatum = 98; } /* SAD-69/Brazil*/ - else if (n < 234) {} - else if (n < 235) { indatum = 117; } /* WGS 72 */ - else if (n < 236) { indatum = 0; } /* Adindan */ - else if (n < 237) { indatum = 2; } /* Ain el Abd */ - else if (n < 238) { indatum = 7; } /* ARC 1960 */ - else if (n < 239) { indatum = 8; } /* Ascension Island 58 */ - else if (n < 241) {} - else if (n < 242) { indatum = 52; } /* Hu-Tzu-Shan */ - else if (n < 245) { indatum = 53; } /* Indian */ - else if (n < 246) {} - else if (n < 247) { indatum = 57; } /* Johnston Island 61 */ - else if (n < 248) { indatum = 64; } /* Luzon */ - else if (n < 249) {} - else if (n < 250) { indatum = 75; } /* Nahrwan */ - else if (n < 251) { indatum = 76; } /* Naparima BWI */ - else if (n < 254) {} - else if (n < 255) { indatum = 82; } /* Old Hawaiian Kauai */ - else if (n < 256) { indatum = 83; } /* Old Hawaiian Maui */ - else if (n < 257) { indatum = 84; } /* Old Hawaiian Oahu */ - else if (n < 259) {} - else if (n < 260) { indatum = 101; } /* Sapper Hill 43 */ - else if (n < 261) { indatum = 111; } /* Timbalai 1948 */ - else if (n < 262) { indatum = 112; } /* Tokyo mean */ - else if (n < 263) { indatum = 116; } /* Wake Eniwetok 1960 */ - - if (indatum == -1) - warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); + indatum = -1; + if (n < 1) {} + else if (n < 8) { + indatum = 0; /* Adindan */ + } else if (n < 9) { + indatum = 1; /* Afgooye */ + } else if (n < 10) { + indatum = 2; /* Ain el Abd */ + } else if (n < 14) {} + else if (n < 23) { + indatum = 6; /* ARC 1950 */ + } else if (n < 26) { + indatum = 7; /* ARC 1960 */ + } else if (n < 27) { + indatum = 8; /* Ascension Island 58 */ + } else if (n < 32) {} + else if (n < 33) { + indatum = 13; /* Australian Geo 84 */ + } else if (n < 34) {} + else if (n < 35) { + indatum = 15; /* Bellevue IGN */ + } else if (n < 36) { + indatum = 16; /* Bermuda 1957 */ + } else if (n < 38) {} + else if (n < 39) { + indatum = 17; /* Bukit Rimpah */ + } else if (n < 40) { + indatum = 18; /* Camp Area Astro */ + } else if (n < 41) { + indatum = 19; /* Campo Inchauspe */ + } else if (n < 42) { + indatum = 22; /* Canton Islan 1966 */ + } else if (n < 43) { + indatum = 23; /* Cape */ + } else if (n < 44) { + indatum = 24; /* Cape Canaveral */ + } else if (n < 45) { + indatum = 26; /* Carthe */ + } else if (n < 46) { + indatum = 28; /* Chatham */ + } else if (n < 47) { + indatum = 29; /* Chua Astro */ + } else if (n < 48) { + indatum = 30; /* Corrego Alegre*/ + } else if (n < 50) {} + else if (n < 51) { + indatum = 33; /* Djakarta (Batavia) */ + } else if (n < 52) { + indatum = 34; /* DOS 1968 */ + } else if (n < 53) { + indatum = 35; /* Easter Island 1967 */ + } else if (n < 54) {} + else if (n < 69) { + indatum = 38; /* European 1950 Mean */ + } else if (n < 70) { + indatum = 39; /* European 1979 Mean */ + } else if (n < 71) {} + else if (n < 72) { + indatum = 41; /* Gandajika */ + } else if (n < 73) { + indatum = 42; /* Geodetic Datum 49 */ + } else if (n < 74) {} + else if (n < 75) { + indatum = 45; /* Guam 1963 */ + } else if (n < 76) { + indatum = 46; /* Gunung Segara */ + } else if (n < 77) {} + else if (n < 78) { + indatum = 49; /* Hearth North */ + } else if (n < 79) {} + else if (n < 80) { + indatum = 50; /* Hjorsey 1955 */ + } else if (n < 81) { + indatum = 51; /* Hong Kong 1963 */ + } else if (n < 82) { + indatum = 52; /* Hu-Tzu-Shan */ + } else if (n < 89) { + indatum = 53; /* Indian */ + } else if (n < 90) {} + else if (n < 91) { + indatum = 55; /* Ireland 1965 */ + } else if (n < 92) {} + else if (n < 93) { + indatum = 56; /* ISTS 073 69 */ + } else if (n < 94) { + indatum = 57; /* Johnston Island 61 */ + } else if (n < 95) { + indatum = 58; /* Kandawala */ + } else if (n < 96) { + indatum = 59; /* Kerguelen Island */ + } else if (n < 97) { + indatum = 60; /* Kertau 48 */ + } else if (n < 99) {} + else if (n < 100) { + indatum = 61; /* L.C. 5 Astro */ + } else if (n < 101) {} + else if (n < 102) { + indatum = 63; /* Liberia 1964 */ + } else if (n < 104) { + indatum = 64; /* Luzon */ + } else if (n < 105) {} + else if (n < 106) { + indatum = 65; /* Mahe 1971 */ + } else if (n < 107) {} + else if (n < 108) { + indatum = 69; /* Merchich */ + } else if (n < 109) { + indatum = 71; /* Midway Astro 61 */ + } else if (n < 111) { + indatum = 73; /* Minna */ + } else if (n < 112) {} + else if (n < 115) { + indatum = 75; /* Nahrwan */ + } else if (n < 116) { + indatum = 76; /* Naparima BWI */ + } else if (n < 116) {} + else if (n < 119) { + indatum = 3; /* Alaska NAD27 */ + } else if (n < 121) { + indatum = 14; /* Bahamas NAD27 */ + } else if (n < 126) { + indatum = 20; /* Canada Mean NAD27 */ + } else if (n < 127) { + indatum = 21; /* Canal Zone NAD27 */ + } else if (n < 128) { + indatum = 31; /* Cuba NAD27 */ + } else if (n < 129) { + indatum = 44; /* Greenland NAD27 */ + } else if (n < 131) {} + else if (n < 132) { + indatum = 20; /* Canada Mean NAD27 */ + } else if (n < 135) {} + else if (n < 136) { + indatum = 70; /* Mexico NAD27 */ + } else if (n < 144) {} + else if (n < 145) { + indatum = 80; /* Old Egyptian */ + } else if (n < 146) { + indatum = 81; /* Old Hawaiian */ + } else if (n < 147) { + indatum = 82; /* Old Hawaiian Kauai */ + } else if (n < 148) { + indatum = 83; /* Old Hawaiian Maui */ + } else if (n < 149) { + indatum = 81; /* Old Hawaiian Mean */ + } else if (n < 150) { + indatum = 84; /* Old Hawaiian Oahu */ + } else if (n < 151) { + indatum = 85; /* Oman */ + } else if (n < 156) { + indatum = 86; /* OSG Britain */ + } else if (n < 157) { + indatum = 87; /* Pico de Las Nieves */ + } else if (n < 158) { + indatum = 88; /* Pitcairn Astro 67 */ + } else if (n < 171) {} + else if (n < 172) { + indatum = 91; /* Puerto Rico */ + } else if (n < 173) { + indatum = 92; /* Pulkovo 1942 */ + } else if (n < 174) { + indatum = 94; /* Quatar National */ + } else if (n < 176) {} + else if (n < 177) { + indatum = 95; /* Rome 1940 */ + } else if (n < 184) { + indatum = 96; /* S-42 (Pulkovo 1942) */ + } else if (n < 185) {} + else if (n < 186) { + indatum = 100; /* Santo DOS */ + } else if (n < 187) { + indatum = 99; /* Sao Braz */ + } else if (n < 191) {} + else if (n < 193) { + indatum = 105; /* SAD-69/Mean */ + } else if (n < 194) { + indatum = 98; /* SAD-69/Brazil */ + } else if (n < 204) { + indatum = 105; /* SAD-69/Mean */ + } else if (n < 205) { + indatum = 106; /* South Asia */ + } else if (n < 206) { + indatum = 109; /* Tananarive 1926 */ + } else if (n < 207) { + indatum = 111; /* Timbalai 1948 */ + } else if (n < 211) { + indatum = 112; /* Tokyo mean */ + } else if (n < 212) { + indatum = 113; /* Tristan Astro 1968 */ + } else if (n < 213) { + indatum = 115; /* Viti Levu 1916 */ + } else if (n < 215) {} + else if (n < 216) { + indatum = 116; /* Wake Eniwetok 1960 */ + } else if (n < 217) { + indatum = 117; /* WGS 72 */ + } else if (n < 218) { + indatum = 118; /* WGS 84 */ + } else if (n < 219) { + indatum = 119; /* Yacare */ + } else if (n < 220) { + indatum = 120; /* Zanderij */ + } else if (n < 231) {} + else if (n < 232) { + indatum = 98; /* SAD-69/Brazil*/ + } else if (n < 234) {} + else if (n < 235) { + indatum = 117; /* WGS 72 */ + } else if (n < 236) { + indatum = 0; /* Adindan */ + } else if (n < 237) { + indatum = 2; /* Ain el Abd */ + } else if (n < 238) { + indatum = 7; /* ARC 1960 */ + } else if (n < 239) { + indatum = 8; /* Ascension Island 58 */ + } else if (n < 241) {} + else if (n < 242) { + indatum = 52; /* Hu-Tzu-Shan */ + } else if (n < 245) { + indatum = 53; /* Indian */ + } else if (n < 246) {} + else if (n < 247) { + indatum = 57; /* Johnston Island 61 */ + } else if (n < 248) { + indatum = 64; /* Luzon */ + } else if (n < 249) {} + else if (n < 250) { + indatum = 75; /* Nahrwan */ + } else if (n < 251) { + indatum = 76; /* Naparima BWI */ + } else if (n < 254) {} + else if (n < 255) { + indatum = 82; /* Old Hawaiian Kauai */ + } else if (n < 256) { + indatum = 83; /* Old Hawaiian Maui */ + } else if (n < 257) { + indatum = 84; /* Old Hawaiian Oahu */ + } else if (n < 259) {} + else if (n < 260) { + indatum = 101; /* Sapper Hill 43 */ + } else if (n < 261) { + indatum = 111; /* Timbalai 1948 */ + } else if (n < 262) { + indatum = 112; /* Tokyo mean */ + } else if (n < 263) { + indatum = 116; /* Wake Eniwetok 1960 */ + } + + if (indatum == -1) { + warning(MYNAME ": Unsupported datum (%d), won't convert to WGS84\n", n); + } } static const char *icon_descr[] = { -"", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", -"City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", -"Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", -"Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", -"Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", -"Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", -"Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", -"Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", -"Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", -"Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", -"Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", -"Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", -"Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", -"Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", -"Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", -"Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", -"Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", -"Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", -"Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", -"Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", -"Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", -"Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", -"Letter - S", "Letter - D", "Letter - N", -"Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", -"Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", -"Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", -"School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", -"Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", -"Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", -"Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", -"Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", -"Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", -"Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", -"Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", -"Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", -"Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", -"Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", -"Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", -"Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", -"1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", -"CheckPoint", NULL + "", "Airport", "Ball Park", "Bank", "Bar", "Boat Ramp", "Campground", "Car", + "City (Large)", "City (Medium)", "City (Small)", "Dam", "Danger Area", + "Drinking Water", "Fishing Area", "Gas Station", "Glider Area", "Golf Course", + "Heliport", "Hotel", "Animals", "Information", "Man Overboard", "Marina", + "Mine", "Medical Facility", "Parachute Area", "Park", "Parking Area", + "Picnic Area", "Private Field", "Residence", "Restaurant", "Restroom", + "Scenic Area", "School", "Seaplane Base", "Shipwreck", "Shopping Center", + "Short Tower", "Policy Station", "Ski Resort", "Soft Field", "Swimming Area", + "Tall Tower", "Telephone", "Tracback Point", "Ultralight Area", "Waypoint", + "Boat", "Exit", "Flag", "Duck", "Buoy", "Back Track", "Beach", "Bridge", + "Building", "Car Repair", "Cemetery", "Church", "Civil", "Convenience Store", + "Crossing", "Fast Food", "Forest", "Ghost Town", "Levee", "Military", + "Oil Field", "Post Office", "Rv Park", "Scales", "Summit", "Toll Booth", + "Trail Head", "Truck Stop", "Tunnel", "Highway", "Gate", "Fall", "Fence", + "Mata-Burro", "Fitness Center", "Movie Theater", "Live Theater", "Zoo", "Horn", + "Bowling", "Car Rental", "City (Capitol)", "Controlled Area", "Stadium", + "Museum", "Amusement Park", "Skull", "Department Store", "Pharmacy", "Pizza", + "Diver Down Flag 1", "Light", "Pin", "", "Pigsty", "Tree", "Bamboo", + "Banana Plant", "Arrow-Down", "Bifurcation", "Cavern", "River", "Rock", + "Arrow-Up", "Trunk", "Soccer Field", "Sporting Court", "Flag, Green", "Trench", + "Ship-Yellow", "Green Sign", "Swamp", "Lake", "Stop!", + "Fishing Hot Spot Facility", "Speed Reducer", "Stairway", "Cactus", "Ship-Red", + "Letter - S", "Letter - D", "Letter - N", + "Crossing", "Cross", "Flag, Red", "Curve1", "Curve2", "Curve3", "Curve4", + "Letter - W", "Letter - L", "Letter - R", "Radio Beacon", "Road Sign", + "Geocache", "Geocache Found", "Traffic Light", "Bus Station", "Train Station", + "School", "Mile Marker", "Conservation Area", "Waypoint", "Box", "Aerial", + "Auto Repair", "Boat", "Exit Ramp", "Fixed Nav Aid", "Floating Buoy", "Garden", + "Fish Farm", "Lighthouse", "Truck Service", "Resort", "Scuba", "Shooting", + "Sight Seeing", "Sounding", "Winery", "Navaid, Amber", "Navaid, Black", + "Navaid, Blue", "Navaid, Green", "Navaid, Green/Red", "Navaid, Green/White", + "Navaid, Orange", "Navaid, Red", "Navaid, Red/Green", "Navaid, Red/White", + "Navaid, Violet", "Navaid, White", "Navaid, White/Green", "Navaid, White/Red", + "Buoy, White", "Dot, White", "Red Square", "Red Diamond", "Green Square", + "Green Diamond", "Restricted Area", "Navaid (unlit)", "Dot (Small)", "Libraries", "Waypoint", "Waypoint1", + "Waypoint2", "Mark (1)", "Mark (2)", "Mark (3)", "Cross (Red)", "Store", + "Exclamation", "Flag (EUA)", "Flag (CAN)", "Flag (BRA)", "Man", "Animals", + "Deer Tracks", "Tree Stand", "Bridge", "Fence", "Intersection", + "Non Direct Beacon", "VHF Omni Range", "Vor/Tacan", "Vor-Dme", + "1st Approach Fix", "Localizer Outer", "Missed Appr. Pt", "Tacan", + "CheckPoint", NULL }; void convert_datum(double *lat, double *lon) { - double amt; - if (indatum != -1 && indatum != 118) { - GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, - lat, lon, &amt, indatum); - } + double amt; + if (indatum != -1 && indatum != 118) { + GPS_Math_Known_Datum_To_WGS84_M(*lat, *lon, 0.0, + lat, lon, &amt, indatum); + } } /* Callbacks */ @@ -360,330 +474,352 @@ void convert_datum(double *lat, double *lon) static void gtm_rd_init(const char *fname) { - int version; - char *name; - file_in = gbfopen_le(fname, "rb", MYNAME); - version = fread_integer(file_in); - name = fread_fixedstring(file_in, 10); - if (version == -29921) - fatal(MYNAME ": Uncompress the file first\n"); - if (strcmp(name, "TrackMaker") != 0) - fatal(MYNAME ": Invalid file format\n"); - if (version != 211) - fatal(MYNAME ": Invalid format version\n"); - xfree(name); - - /* Header */ - fread_discard(file_in, 15); - ws_count = fread_long(file_in); - fread_discard(file_in, 4); - wp_count = fread_long(file_in); - tr_count = fread_long(file_in); - rt_count = fread_long(file_in); - fread_discard(file_in, 16); - im_count = fread_long(file_in); - ts_count = fread_long(file_in); - fread_discard(file_in, 28); - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_string_discard(file_in); - - /* User Grid and Datum */ - fread_discard(file_in, 34); - set_datum(fread_integer(file_in)); - fread_discard(file_in, 22); + int version; + char *name; + file_in = gbfopen_le(fname, "rb", MYNAME); + version = fread_integer(file_in); + name = fread_fixedstring(file_in, 10); + if (version == -29921) { + fatal(MYNAME ": Uncompress the file first\n"); + } + if (strcmp(name, "TrackMaker") != 0) { + fatal(MYNAME ": Invalid file format\n"); + } + if (version != 211) { + fatal(MYNAME ": Invalid format version\n"); + } + xfree(name); + + /* Header */ + fread_discard(file_in, 15); + ws_count = fread_long(file_in); + fread_discard(file_in, 4); + wp_count = fread_long(file_in); + tr_count = fread_long(file_in); + rt_count = fread_long(file_in); + fread_discard(file_in, 16); + im_count = fread_long(file_in); + ts_count = fread_long(file_in); + fread_discard(file_in, 28); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_string_discard(file_in); + + /* User Grid and Datum */ + fread_discard(file_in, 34); + set_datum(fread_integer(file_in)); + fread_discard(file_in, 22); } -static void -gtm_rd_deinit(void) +static void +gtm_rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } -static void count_route_waypts(const waypoint *wpt) { rt_count++; } -static void count_track_waypts(const waypoint *wpt) { tr_count++; } +static void count_route_waypts(const waypoint *wpt) +{ + rt_count++; +} +static void count_track_waypts(const waypoint *wpt) +{ + tr_count++; +} static void gtm_wr_init(const char *fname) { - rt_count = tr_count = 0; - track_disp_all(NULL, NULL, count_track_waypts); - route_disp_all(NULL, NULL, count_route_waypts); - - file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ - - /* Header */ - fwrite_integer(file_out, 211); - fwrite_fixedstring(file_out, "TrackMaker", 10); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 8); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_long(file_out, 0); - fwrite_long(file_out, 16777215); - fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ - fwrite_long(file_out, 0); - fwrite_long(file_out, waypt_count()); /* num waypoints */ - fwrite_long(file_out, tr_count); - fwrite_long(file_out, rt_count); - fwrite_single(file_out, 0); /* maxlon */ - fwrite_single(file_out, 0); /* minlon */ - fwrite_single(file_out, 0); /* maxlat */ - fwrite_single(file_out, 0); /* minlat */ - fwrite_long(file_out, 0); - fwrite_long(file_out, track_count()); /* num tracklog styles */ - fwrite_single(file_out, 0); - fwrite_single(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_bool(file_out, 0); - fwrite_string(file_out, "Times New Roman"); - fwrite_string(file_out, ""); - fwrite_string(file_out, ""); - fwrite_string(file_out, ""); - - /* User Grid and Datum */ - fwrite_null(file_out, 34); - fwrite_integer(file_out, 217); /* WGS84 */ - fwrite_null(file_out, 22); + rt_count = tr_count = 0; + track_disp_all(NULL, NULL, count_track_waypts); + route_disp_all(NULL, NULL, count_route_waypts); + + file_out = gbfopen_le(fname, "wb", MYNAME); /* little endian */ + + /* Header */ + fwrite_integer(file_out, 211); + fwrite_fixedstring(file_out, "TrackMaker", 10); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 8); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_long(file_out, 0); + fwrite_long(file_out, 16777215); + fwrite_long(file_out, waypt_count() ? 4 : 0); /* num waypoint styles */ + fwrite_long(file_out, 0); + fwrite_long(file_out, waypt_count()); /* num waypoints */ + fwrite_long(file_out, tr_count); + fwrite_long(file_out, rt_count); + fwrite_single(file_out, 0); /* maxlon */ + fwrite_single(file_out, 0); /* minlon */ + fwrite_single(file_out, 0); /* maxlat */ + fwrite_single(file_out, 0); /* minlat */ + fwrite_long(file_out, 0); + fwrite_long(file_out, track_count()); /* num tracklog styles */ + fwrite_single(file_out, 0); + fwrite_single(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_bool(file_out, 0); + fwrite_string(file_out, "Times New Roman"); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + fwrite_string(file_out, ""); + + /* User Grid and Datum */ + fwrite_null(file_out, 34); + fwrite_integer(file_out, 217); /* WGS84 */ + fwrite_null(file_out, 22); } static void gtm_wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void gtm_read(void) { - route_head *first_trk_head = NULL; - route_head *trk_head = NULL; - route_head *rte_head = NULL; - waypoint *wpt; - int real_tr_count = 0; - char *route_name; - unsigned int icon; - int i; - - /* Image information */ - for (i = 0; i != im_count; i++) { - fread_string_discard(file_in); - fread_string_discard(file_in); - fread_discard(file_in, 30); - } - - /* Waypoints */ - for (i = 0; i != wp_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(file_in, 10); - wpt->description = fread_string(file_in); - icon = fread_integer(file_in); - if (icon < sizeof(icon_descr)/sizeof(char*)) - wpt->icon_descr = icon_descr[icon]; - fread_discard(file_in, 1); - wpt->creation_time = fread_long(file_in); - if (wpt->creation_time) - wpt->creation_time += EPOCH89DIFF; - fread_discard(file_in, 2); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - fread_discard(file_in, 2); - waypt_add(wpt); - } - - /* Waypoint Styles */ - if (wp_count) { - for (i = 0; i != ws_count; i++) { - fread_discard(file_in, 4); - fread_string_discard(file_in); - fread_discard(file_in, 24); - } - } - - /* Tracklogs */ - for (i = 0; i != tr_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->creation_time = fread_long(file_in); - if (wpt->creation_time) - wpt->creation_time += EPOCH89DIFF; - start_new = fread_byte(file_in); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - if (start_new || !trk_head) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - real_tr_count++; - if (!first_trk_head) - first_trk_head = trk_head; - } - track_add_wpt(trk_head, wpt); - } - - /* Tracklog styles */ - trk_head = first_trk_head; - for (i = 0; i != ts_count && i != real_tr_count; i++) { - trk_head->rte_name = fread_string(file_in); - fread_discard(file_in, 12); - trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); - } - - /* Routes */ - for (i = 0; i != rt_count; i++) { - wpt = waypt_new(); - wpt->latitude = fread_double(file_in); - wpt->longitude = fread_double(file_in); - convert_datum(&wpt->latitude, &wpt->longitude); - wpt->shortname = fread_fixedstring(file_in, 10); - wpt->description = fread_string(file_in); - route_name = fread_string(file_in); - icon = fread_integer(file_in); - if (icon < sizeof(icon_descr)/sizeof(char*)) - wpt->icon_descr = icon_descr[icon]; - fread_discard(file_in, 1); - start_new = fread_byte(file_in); - fread_discard(file_in, 6); - wpt->altitude = fread_single(file_in); - if (wpt->altitude == unknown_alt_gtm) - wpt->altitude = unknown_alt; - fread_discard(file_in, 2); - - if (start_new || !rte_head) { - rte_head = route_head_alloc(); - rte_head->rte_name = route_name; - route_add_head(rte_head); - } - else { - xfree(route_name); - } - route_add_wpt(rte_head, wpt); - } + route_head *first_trk_head = NULL; + route_head *trk_head = NULL; + route_head *rte_head = NULL; + waypoint *wpt; + int real_tr_count = 0; + char *route_name; + unsigned int icon; + int i; + + /* Image information */ + for (i = 0; i != im_count; i++) { + fread_string_discard(file_in); + fread_string_discard(file_in); + fread_discard(file_in, 30); + } + + /* Waypoints */ + for (i = 0; i != wp_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) { + wpt->icon_descr = icon_descr[icon]; + } + fread_discard(file_in, 1); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) { + wpt->creation_time += EPOCH89DIFF; + } + fread_discard(file_in, 2); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + fread_discard(file_in, 2); + waypt_add(wpt); + } + + /* Waypoint Styles */ + if (wp_count) { + for (i = 0; i != ws_count; i++) { + fread_discard(file_in, 4); + fread_string_discard(file_in); + fread_discard(file_in, 24); + } + } + + /* Tracklogs */ + for (i = 0; i != tr_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->creation_time = fread_long(file_in); + if (wpt->creation_time) { + wpt->creation_time += EPOCH89DIFF; + } + start_new = fread_byte(file_in); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + if (start_new || !trk_head) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + real_tr_count++; + if (!first_trk_head) { + first_trk_head = trk_head; + } + } + track_add_wpt(trk_head, wpt); + } + + /* Tracklog styles */ + trk_head = first_trk_head; + for (i = 0; i != ts_count && i != real_tr_count; i++) { + trk_head->rte_name = fread_string(file_in); + fread_discard(file_in, 12); + trk_head = (route_head *)QUEUE_NEXT(&trk_head->Q); + } + + /* Routes */ + for (i = 0; i != rt_count; i++) { + wpt = waypt_new(); + wpt->latitude = fread_double(file_in); + wpt->longitude = fread_double(file_in); + convert_datum(&wpt->latitude, &wpt->longitude); + wpt->shortname = fread_fixedstring(file_in, 10); + wpt->description = fread_string(file_in); + route_name = fread_string(file_in); + icon = fread_integer(file_in); + if (icon < sizeof(icon_descr)/sizeof(char*)) { + wpt->icon_descr = icon_descr[icon]; + } + fread_discard(file_in, 1); + start_new = fread_byte(file_in); + fread_discard(file_in, 6); + wpt->altitude = fread_single(file_in); + if (wpt->altitude == unknown_alt_gtm) { + wpt->altitude = unknown_alt; + } + fread_discard(file_in, 2); + + if (start_new || !rte_head) { + rte_head = route_head_alloc(); + rte_head->rte_name = route_name; + route_add_head(rte_head); + } else { + xfree(route_name); + } + route_add_wpt(rte_head, wpt); + } } int icon_from_descr(const char *descr) { - if (descr) { - int i; - for (i = 0; icon_descr[i]; i++) - if (strcmp(icon_descr[i], descr) == 0) - return i; - } - return 48; + if (descr) { + int i; + for (i = 0; icon_descr[i]; i++) + if (strcmp(icon_descr[i], descr) == 0) { + return i; + } + } + return 48; } static void write_waypt(const waypoint *wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_fixedstring(file_out, wpt->shortname, 10); - fwrite_string(file_out, wpt->description); - fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); - fwrite_byte(file_out, 3); - if (wpt->creation_time) - fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); - else - fwrite_long(file_out, 0); - fwrite_integer(file_out, 0); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - fwrite_integer(file_out, 0); + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + if (wpt->creation_time) { + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + } else { + fwrite_long(file_out, 0); + } + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + fwrite_integer(file_out, 0); } static void start_rte(const route_head *rte) { - rte_active = rte; - start_new = 1; + rte_active = rte; + start_new = 1; } static void write_trk_waypt(const waypoint *wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); - fwrite_byte(file_out, start_new); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - start_new = 0; + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_long(file_out, wpt->creation_time-EPOCH89DIFF); + fwrite_byte(file_out, start_new); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + start_new = 0; } static void write_trk_style(const route_head *trk) { - fwrite_string(file_out, trk->rte_name); - fwrite_byte(file_out, 1); - fwrite_long(file_out, 0); - fwrite_single(file_out, 0); - fwrite_byte(file_out, 0); - fwrite_integer(file_out, 0); + fwrite_string(file_out, trk->rte_name); + fwrite_byte(file_out, 1); + fwrite_long(file_out, 0); + fwrite_single(file_out, 0); + fwrite_byte(file_out, 0); + fwrite_integer(file_out, 0); } static void write_rte_waypt(const waypoint *wpt) { - fwrite_double(file_out, wpt->latitude); - fwrite_double(file_out, wpt->longitude); - fwrite_fixedstring(file_out, wpt->shortname, 10); - fwrite_string(file_out, wpt->description); - fwrite_string(file_out, rte_active->rte_name); - fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); - fwrite_byte(file_out, 3); - fwrite_byte(file_out, start_new); - fwrite_long(file_out, 0); - fwrite_integer(file_out, 0); - if (wpt->altitude == unknown_alt) - fwrite_single(file_out, unknown_alt_gtm); - else - fwrite_single(file_out, wpt->altitude); - fwrite_integer(file_out, 0); - start_new = 0; + fwrite_double(file_out, wpt->latitude); + fwrite_double(file_out, wpt->longitude); + fwrite_fixedstring(file_out, wpt->shortname, 10); + fwrite_string(file_out, wpt->description); + fwrite_string(file_out, rte_active->rte_name); + fwrite_integer(file_out, icon_from_descr(wpt->icon_descr)); + fwrite_byte(file_out, 3); + fwrite_byte(file_out, start_new); + fwrite_long(file_out, 0); + fwrite_integer(file_out, 0); + if (wpt->altitude == unknown_alt) { + fwrite_single(file_out, unknown_alt_gtm); + } else { + fwrite_single(file_out, wpt->altitude); + } + fwrite_integer(file_out, 0); + start_new = 0; } static void gtm_write(void) { - waypt_disp_all(write_waypt); - if (waypt_count()) - gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); - track_disp_all(start_rte, NULL, write_trk_waypt); - track_disp_all(write_trk_style, NULL, NULL); - route_disp_all(start_rte, NULL, write_rte_waypt); + waypt_disp_all(write_waypt); + if (waypt_count()) { + gbfwrite(WAYPOINTSTYLES, 1, sizeof(WAYPOINTSTYLES)-1, file_out); + } + track_disp_all(start_rte, NULL, write_trk_waypt); + track_disp_all(write_trk_style, NULL, NULL); + route_disp_all(start_rte, NULL, write_rte_waypt); } static arglist_t gtm_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t gtm_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - gtm_rd_init, - gtm_wr_init, - gtm_rd_deinit, - gtm_wr_deinit, - gtm_read, - gtm_write, - NULL, - gtm_args, + ff_type_file, + FF_CAP_RW_ALL, + gtm_rd_init, + gtm_wr_init, + gtm_rd_deinit, + gtm_wr_deinit, + gtm_read, + gtm_write, + NULL, + gtm_args, }; diff --git a/gpsbabel/gtrnctr.c b/gpsbabel/gtrnctr.c index 5c343ec51..bd292f808 100644 --- a/gpsbabel/gtrnctr.c +++ b/gpsbabel/gtrnctr.c @@ -49,18 +49,22 @@ static char *opt_sport, *opt_course; static arglist_t gtc_args[] = { - { "course", &opt_course, "Write course rather than history, default yes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX}, - { "sport", &opt_sport, "Sport: Biking (deflt), Running, MultiSport, Other", - "Biking", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "course", &opt_course, "Write course rather than history, default yes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "sport", &opt_sport, "Sport: Biking (deflt), Running, MultiSport, Other", + "Biking", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #if ! HAVE_LIBEXPAT static void gtc_rd_init(const char *fname) { - fatal(MYNAME ": this format does not support reading.\n"); + fatal(MYNAME ": this format does not support reading.\n"); } static void @@ -92,110 +96,110 @@ static xg_callback gtc_wpt_lat; static xg_callback gtc_wpt_long; static xg_tag_mapping gtc_map[] = { - /* courses tcx v1 & v2 */ - { gtc_trk_s, cb_start, "/Courses/Course" }, - { gtc_trk_ident,cb_cdata, "/Courses/Course/Name"}, - { gtc_trk_pnt_s,cb_start, "/Courses/Course/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/Courses/Course/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/Courses/Course/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" }, - - /* history tcx v2 (activities) */ - { gtc_trk_s, cb_start, "/Activities/Activity" }, - { gtc_trk_ident,cb_cdata, "/Activities/Activity/Id" }, - { gtc_trk_lap_s,cb_start, "/Activities/Activity/Lap" }, - { gtc_trk_lap_e,cb_end, "/Activities/Activity/Lap" }, - { gtc_trk_pnt_s,cb_start, "/Activities/Activity/Lap/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/Activities/Activity/Lap/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" }, - { gtc_trk_pwr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" }, - - /* history tcx v1 */ - { gtc_trk_s, cb_start, "/History/Run" }, - { gtc_trk_ident,cb_cdata, "/History/Run/Id" }, - { gtc_trk_lap_s,cb_start, "/History/Run/Lap" }, - { gtc_trk_lap_e,cb_end, "/History/Run/Lap" }, - { gtc_trk_pnt_s,cb_start, "/History/Run/Lap/Track/Trackpoint" }, - { gtc_trk_pnt_e,cb_end, "/History/Run/Lap/Track/Trackpoint" }, - { gtc_trk_utc, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" }, - { gtc_trk_lat, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, - { gtc_trk_long, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, - { gtc_trk_alt, cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" }, - { gtc_trk_hr, cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" }, - { gtc_trk_cad, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" }, - - { gtc_wpt_pnt_s,cb_start, "/Courses/Course/Lap/BeginPosition" }, - { gtc_wpt_pnt_e,cb_end, "/Courses/Course/Lap/BeginPosition" }, - { gtc_wpt_lat, cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" }, - { gtc_wpt_long, cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" }, - - { NULL, 0, NULL} + /* courses tcx v1 & v2 */ + { gtc_trk_s, cb_start, "/Courses/Course" }, + { gtc_trk_ident,cb_cdata, "/Courses/Course/Name"}, + { gtc_trk_pnt_s,cb_start, "/Courses/Course/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/Courses/Course/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/Courses/Course/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/Courses/Course/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_alt, cb_cdata, "/Courses/Course/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/Courses/Course/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/Courses/Course/Track/Trackpoint/Cadence" }, + + /* history tcx v2 (activities) */ + { gtc_trk_s, cb_start, "/Activities/Activity" }, + { gtc_trk_ident,cb_cdata, "/Activities/Activity/Id" }, + { gtc_trk_lap_s,cb_start, "/Activities/Activity/Lap" }, + { gtc_trk_lap_e,cb_end, "/Activities/Activity/Lap" }, + { gtc_trk_pnt_s,cb_start, "/Activities/Activity/Lap/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/Activities/Activity/Lap/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Cadence" }, + { gtc_trk_pwr, cb_cdata, "/Activities/Activity/Lap/Track/Trackpoint/Extensions/ns3:TPX/ns3:Watts" }, + + /* history tcx v1 */ + { gtc_trk_s, cb_start, "/History/Run" }, + { gtc_trk_ident,cb_cdata, "/History/Run/Id" }, + { gtc_trk_lap_s,cb_start, "/History/Run/Lap" }, + { gtc_trk_lap_e,cb_end, "/History/Run/Lap" }, + { gtc_trk_pnt_s,cb_start, "/History/Run/Lap/Track/Trackpoint" }, + { gtc_trk_pnt_e,cb_end, "/History/Run/Lap/Track/Trackpoint" }, + { gtc_trk_utc, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Time" }, + { gtc_trk_lat, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LatitudeDegrees" }, + { gtc_trk_long, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Position/LongitudeDegrees" }, + { gtc_trk_alt, cb_cdata, "/History/Run/Lap/Track/Trackpoint/AltitudeMeters" }, + { gtc_trk_hr, cb_cdata, "/History/Run/Lap/Track/Trackpoint/HeartRateBpm" }, + { gtc_trk_cad, cb_cdata, "/History/Run/Lap/Track/Trackpoint/Cadence" }, + + { gtc_wpt_pnt_s,cb_start, "/Courses/Course/Lap/BeginPosition" }, + { gtc_wpt_pnt_e,cb_end, "/Courses/Course/Lap/BeginPosition" }, + { gtc_wpt_lat, cb_cdata, "/Courses/Course/Lap/BeginPosition/LatitudeDegrees" }, + { gtc_wpt_long, cb_cdata, "/Courses/Course/Lap/BeginPosition/LongitudeDegrees" }, + + { NULL, 0, NULL} }; static const char * gtc_tags_to_ignore[] = { - "TrainingCenterDatabase", - "CourseFolder", - "Running", - "Biking", - "Other", - "Multisport", - NULL, + "TrainingCenterDatabase", + "CourseFolder", + "Running", + "Biking", + "Other", + "Multisport", + NULL, }; static void gtc_rd_init(const char *fname) { - xml_init(fname, gtc_map, NULL); - xml_ignore_tags(gtc_tags_to_ignore); + xml_init(fname, gtc_map, NULL); + xml_ignore_tags(gtc_tags_to_ignore); } static void gtc_read(void) { - xml_read(); + xml_read(); } static void gtc_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } #endif static void gtc_wr_init(const char *fname) { - int i; + int i; - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); - if(opt_sport) { - for(i = 0; i < MAX_SPORTS; i++) { - if(0 == case_ignore_strncmp(opt_sport, gtc_sportlist[i], 2)) { - gtc_sport = i; - break; - } - } - } - gtc_course_flag = atoi(opt_course); + if (opt_sport) { + for (i = 0; i < MAX_SPORTS; i++) { + if (0 == case_ignore_strncmp(opt_sport, gtc_sportlist[i], 2)) { + gtc_sport = i; + break; + } + } + } + gtc_course_flag = atoi(opt_course); } static void gtc_wr_deinit(void) { - gbfclose(ofd); - xfree(tdata); + gbfclose(ofd); + xfree(tdata); } static int gtc_indent_level; @@ -203,353 +207,361 @@ static int gtc_indent_level; static void gtc_write_xml(int indent, const char *fmt, ...) { - va_list args; + va_list args; - va_start(args, fmt); + va_start(args, fmt); - if (indent < 0) gtc_indent_level--; + if (indent < 0) { + gtc_indent_level--; + } - gbfprintf(ofd, "%*s", gtc_indent_level * 2, ""); - gbvfprintf(ofd, fmt, args); + gbfprintf(ofd, "%*s", gtc_indent_level * 2, ""); + gbvfprintf(ofd, fmt, args); - if (indent > 0) gtc_indent_level++; + if (indent > 0) { + gtc_indent_level++; + } - va_end(args); + va_end(args); } static void gtc_waypt_pr(const waypoint *wpt) { - if (wpt->wpt_flags.is_split != 0) { - gtc_write_xml(1, "\n"); - } else { - gtc_write_xml(1, "\n"); - } - - if (wpt->creation_time) { - char time_string[100]; - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, - XML_LONG_TIME); - if (time_string[0]) { - gtc_write_xml(0, "\n", - time_string); - } - } - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%f\n", wpt->latitude); - gtc_write_xml(0, "%f\n", wpt->longitude); - gtc_write_xml(-1, "\n"); - if (wpt->altitude != unknown_alt) { - gtc_write_xml(0, "%f\n", wpt->altitude); - } - if (wpt->heartrate) { - //gtc_write_xml(0, "%d\n", wpt->heartrate); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", wpt->heartrate); - gtc_write_xml(-1,"\n"); - } - if (wpt->cadence) { - gtc_write_xml(0, "%d\n", wpt->cadence); - } - - gtc_write_xml(-1, "\n"); + if (wpt->wpt_flags.is_split != 0) { + gtc_write_xml(1, "\n"); + } else { + gtc_write_xml(1, "\n"); + } + + if (wpt->creation_time) { + char time_string[100]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, + XML_LONG_TIME); + if (time_string[0]) { + gtc_write_xml(0, "\n", + time_string); + } + } + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%f\n", wpt->latitude); + gtc_write_xml(0, "%f\n", wpt->longitude); + gtc_write_xml(-1, "\n"); + if (wpt->altitude != unknown_alt) { + gtc_write_xml(0, "%f\n", wpt->altitude); + } + if (wpt->heartrate) { + //gtc_write_xml(0, "%d\n", wpt->heartrate); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", wpt->heartrate); + gtc_write_xml(-1,"\n"); + } + if (wpt->cadence) { + gtc_write_xml(0, "%d\n", wpt->cadence); + } + + gtc_write_xml(-1, "\n"); } static void gtc_fake_hdr(void) { - long secs = 0; - if (gtc_least_time && gtc_most_time) { - secs = gtc_most_time - gtc_least_time; - } - if(gtc_course_flag) { /* course format */ - - gtc_write_xml(0, "%d\n", secs); - gtc_write_xml(0, "%lf\n", - tdata->distance_meters ? tdata->distance_meters : 0); - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%lf\n", gtc_start_lat); - gtc_write_xml(0, "%lf\n", gtc_start_long); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0, "%lf\n", gtc_end_lat); - gtc_write_xml(0, "%lf\n", gtc_end_long); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->avg_hrt ? (int)(tdata->avg_hrt + .5): 100); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->max_hrt ? tdata->max_hrt : 200); - gtc_write_xml(-1,"\n"); - gtc_write_xml(0, "Active\n"); - - } else { /* activity (history) format */ - - gtc_write_xml(0, "%d\n", secs); - gtc_write_xml(0, "%lf\n", - tdata->distance_meters ? tdata->distance_meters : 1000); - gtc_write_xml(0, "0\n"); - gtc_write_xml(0, "0\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%g\n", - tdata->avg_hrt ? tdata->avg_hrt : 100); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1, "\n"); - gtc_write_xml(0,"%d\n", - tdata->max_hrt ? (int) tdata->max_hrt : 200); - gtc_write_xml(-1,"\n"); - gtc_write_xml(0, "Active\n"); - gtc_write_xml(0, "Manual\n"); - } + long secs = 0; + if (gtc_least_time && gtc_most_time) { + secs = gtc_most_time - gtc_least_time; + } + if (gtc_course_flag) { /* course format */ + + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "%lf\n", + tdata->distance_meters ? tdata->distance_meters : 0); + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%lf\n", gtc_start_lat); + gtc_write_xml(0, "%lf\n", gtc_start_long); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0, "%lf\n", gtc_end_lat); + gtc_write_xml(0, "%lf\n", gtc_end_long); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->avg_hrt ? (int)(tdata->avg_hrt + .5): 100); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->max_hrt ? tdata->max_hrt : 200); + gtc_write_xml(-1,"\n"); + gtc_write_xml(0, "Active\n"); + + } else { /* activity (history) format */ + + gtc_write_xml(0, "%d\n", secs); + gtc_write_xml(0, "%lf\n", + tdata->distance_meters ? tdata->distance_meters : 1000); + gtc_write_xml(0, "0\n"); + gtc_write_xml(0, "0\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%g\n", + tdata->avg_hrt ? tdata->avg_hrt : 100); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1, "\n"); + gtc_write_xml(0,"%d\n", + tdata->max_hrt ? (int) tdata->max_hrt : 200); + gtc_write_xml(-1,"\n"); + gtc_write_xml(0, "Active\n"); + gtc_write_xml(0, "Manual\n"); + } } static void -gtc_act_hdr( const route_head *rte) +gtc_act_hdr(const route_head *rte) { - gtc_write_xml(1, "\n", gtc_sportlist[gtc_sport]); - if (gtc_least_time) { - char time_string[100]; - xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); - gtc_write_xml(0, "%s\n", time_string); - gtc_write_xml(1, "\n", time_string); - } else { - gtc_write_xml(1, "\n"); - } - gtc_fake_hdr(); - gtc_write_xml(1,"\n"); + gtc_write_xml(1, "\n", gtc_sportlist[gtc_sport]); + if (gtc_least_time) { + char time_string[100]; + xml_fill_in_time(time_string, gtc_least_time, 0, XML_LONG_TIME); + gtc_write_xml(0, "%s\n", time_string); + gtc_write_xml(1, "\n", time_string); + } else { + gtc_write_xml(1, "\n"); + } + gtc_fake_hdr(); + gtc_write_xml(1,"\n"); } static void gtc_act_ftr(const route_head *rte) { - gtc_write_xml(-1, "\n"); - gtc_write_xml(-1, "\n"); - gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); } static void -gtc_crs_hdr( const route_head *rte) +gtc_crs_hdr(const route_head *rte) { - gtc_write_xml(1, "\n"); - if(rte->rte_name) { - char *name = xstrndup(rte->rte_name, GTC_MAX_NAME_LEN); - gtc_write_xml(0, "%s\n", name); - xfree(name); - } else { - gtc_write_xml(0, "New Course\n"); - } - /* write_optional_xml_entity(ofd, " ", "Name", rte->rte_name); */ - gtc_write_xml(1, "\n"); - gtc_fake_hdr(); - gtc_write_xml(-1, "\n"); - gtc_write_xml(1,"\n"); + gtc_write_xml(1, "\n"); + if (rte->rte_name) { + char *name = xstrndup(rte->rte_name, GTC_MAX_NAME_LEN); + gtc_write_xml(0, "%s\n", name); + xfree(name); + } else { + gtc_write_xml(0, "New Course\n"); + } + /* write_optional_xml_entity(ofd, " ", "Name", rte->rte_name); */ + gtc_write_xml(1, "\n"); + gtc_fake_hdr(); + gtc_write_xml(-1, "\n"); + gtc_write_xml(1,"\n"); } static void gtc_crs_ftr(const route_head *rte) { - gtc_write_xml(-1,"\n"); - gtc_write_xml(-1, "\n"); + gtc_write_xml(-1,"\n"); + gtc_write_xml(-1, "\n"); } static void gtc_lap_start(const route_head *rte) { - gtc_least_time = 0; - gtc_most_time = 0; + gtc_least_time = 0; + gtc_most_time = 0; } static void gtc_new_study_lap(const route_head *rte) { - track_recompute(rte, &tdata); /* called routine allocates space for tdata */ + track_recompute(rte, &tdata); /* called routine allocates space for tdata */ } static void gtc_study_lap(const waypoint *wpt) { - if (wpt->creation_time && (gtc_least_time == 0)) { - gtc_least_time = wpt->creation_time; - gtc_start_lat = wpt->latitude; - gtc_start_long = wpt->longitude; - } + if (wpt->creation_time && (gtc_least_time == 0)) { + gtc_least_time = wpt->creation_time; + gtc_start_lat = wpt->latitude; + gtc_start_long = wpt->longitude; + } - if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) { - gtc_least_time = wpt->creation_time; - gtc_start_lat = wpt->latitude; - gtc_start_long = wpt->longitude; - } - if (wpt->creation_time > gtc_most_time) { - gtc_most_time = wpt->creation_time; - gtc_end_lat = wpt->latitude; - gtc_end_long = wpt->longitude; - } + if (wpt->creation_time && (gtc_least_time > wpt->creation_time)) { + gtc_least_time = wpt->creation_time; + gtc_start_lat = wpt->latitude; + gtc_start_long = wpt->longitude; + } + if (wpt->creation_time > gtc_most_time) { + gtc_most_time = wpt->creation_time; + gtc_end_lat = wpt->latitude; + gtc_end_long = wpt->longitude; + } } void gtc_write(void) { - gtc_write_xml(0, "\n"); - gtc_write_xml(1, "\n"); + gtc_write_xml(0, "\n"); + gtc_write_xml(1, "\n"); - gtc_lap_start(NULL); - track_disp_all(NULL, NULL, gtc_study_lap); - track_disp_all(gtc_new_study_lap, NULL, NULL); + gtc_lap_start(NULL); + track_disp_all(NULL, NULL, gtc_study_lap); + track_disp_all(gtc_new_study_lap, NULL, NULL); - if(gtc_course_flag) { - gtc_write_xml(1, "\n"); - track_disp_all(gtc_crs_hdr, gtc_crs_ftr, gtc_waypt_pr); - gtc_write_xml(-1, "\n"); - } else { - gtc_write_xml(1, "\n"); - track_disp_all(gtc_act_hdr, gtc_act_ftr, gtc_waypt_pr); - gtc_write_xml(-1, "\n"); - } + if (gtc_course_flag) { + gtc_write_xml(1, "\n"); + track_disp_all(gtc_crs_hdr, gtc_crs_ftr, gtc_waypt_pr); + gtc_write_xml(-1, "\n"); + } else { + gtc_write_xml(1, "\n"); + track_disp_all(gtc_act_hdr, gtc_act_ftr, gtc_waypt_pr); + gtc_write_xml(-1, "\n"); + } - gtc_write_xml(-1, "\n"); + gtc_write_xml(-1, "\n"); } void gtc_trk_s(const char *unused, const char **attrv) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head = route_head_alloc(); + track_add_head(trk_head); } void gtc_trk_ident(const char *args, const char **unused) { - trk_head->rte_name = xstrdup(args); + trk_head->rte_name = xstrdup(args); } void gtc_trk_lap_s(const char *unused, const char **attrv) { - lap_ct++; - lap_s = 1; + lap_ct++; + lap_s = 1; } void gtc_trk_lap_e(const char *unused, const char **attrv) { - lap_s = 0; + lap_s = 0; } void gtc_trk_pnt_s(const char *unused, const char **attrv) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } void gtc_trk_pnt_e(const char *args, const char **unused) { - if(wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { - if (lap_s) { - /* Add the first point of an ActivityLap as - a waypoint as well as a trackpoint. */ - char cbuf[10]; - waypoint* wpt_lap_s = waypt_dupe(wpt_tmp); - snprintf(cbuf, sizeof(cbuf), "LAP%03d", lap_ct); - wpt_lap_s->shortname = xstrdup(cbuf); - waypt_add(wpt_lap_s); - } + if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { + if (lap_s) { + /* Add the first point of an ActivityLap as + a waypoint as well as a trackpoint. */ + char cbuf[10]; + waypoint* wpt_lap_s = waypt_dupe(wpt_tmp); + snprintf(cbuf, sizeof(cbuf), "LAP%03d", lap_ct); + wpt_lap_s->shortname = xstrdup(cbuf); + waypt_add(wpt_lap_s); + } - track_add_wpt(trk_head, wpt_tmp); - } - else waypt_free(wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); + } else { + waypt_free(wpt_tmp); + } - wpt_tmp = NULL; - lap_s = 0; + wpt_tmp = NULL; + lap_s = 0; } void gtc_trk_utc(const char *args, const char **unused) { - wpt_tmp->creation_time = xml_parse_time(args, NULL); + wpt_tmp->creation_time = xml_parse_time(args, NULL); } void gtc_trk_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } void gtc_trk_long(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } void gtc_trk_alt(const char *args, const char **unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } void gtc_trk_hr(const char *args, const char **unused) { - wpt_tmp->heartrate = atoi(args); + wpt_tmp->heartrate = atoi(args); } void gtc_trk_cad(const char *args, const char **unused) { - wpt_tmp->cadence = atoi(args); + wpt_tmp->cadence = atoi(args); } void gtc_trk_pwr(const char *args, const char **unused) { - wpt_tmp->power = atof(args); + wpt_tmp->power = atof(args); } void gtc_wpt_pnt_s(const char *unused, const char **attrv) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } void gtc_wpt_pnt_e(const char *args, const char **unused) { - if(wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) waypt_add(wpt_tmp); - else waypt_free(wpt_tmp); + if (wpt_tmp->longitude != 0. && wpt_tmp->latitude != 0.) { + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } - wpt_tmp = NULL; + wpt_tmp = NULL; } void gtc_wpt_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } void gtc_wpt_long(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } ff_vecs_t gtc_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - gtc_rd_init, - gtc_wr_init, - gtc_rd_deinit, - gtc_wr_deinit, - gtc_read, - gtc_write, - NULL, - gtc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + gtc_rd_init, + gtc_wr_init, + gtc_rd_deinit, + gtc_wr_deinit, + gtc_read, + gtc_write, + NULL, + gtc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/height.c b/gpsbabel/height.c index 191cdfd94..1853906e2 100755 --- a/gpsbabel/height.c +++ b/gpsbabel/height.c @@ -34,25 +34,35 @@ static double addf; static arglist_t height_args[] = { - {"add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)", - NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"wgs84tomsl", &wgs84tomslopt, "Converts WGS84 ellipsoidal height to orthometric height (MSL)", - NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "add", &addopt, "Adds a constant value to every altitude (meter, append \"f\" (x.xxf) for feet)", + NULL, ARGTYPE_BEGIN_REQ | ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "wgs84tomsl", &wgs84tomslopt, "Converts WGS84 ellipsoidal height to orthometric height (MSL)", + NULL, ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static double bilinear(double x1, double y1, double x2, double y2, double x, double y, double z11, double z12, double z21, double z22) { - double delta; + double delta; - if (y1 == y2 && x1 == x2 ) return (z11); - if (y1 == y2 && x1 != x2 ) return (z22*(x-x1)+z11*(x2-x))/(x2-x1); - if (x1 == x2 && y1 != y2 ) return (z22*(y-y1)+z11*(y2-y))/(y2-y1); + if (y1 == y2 && x1 == x2) { + return (z11); + } + if (y1 == y2 && x1 != x2) { + return (z22*(x-x1)+z11*(x2-x))/(x2-x1); + } + if (x1 == x2 && y1 != y2) { + return (z22*(y-y1)+z11*(y2-y))/(y2-y1); + } - delta=(y2-y1)*(x2-x1); + delta=(y2-y1)*(x2-x1); - return (z22*(y-y1)*(x-x1)+z12*(y2-y)*(x-x1)+z21*(y-y1)*(x2-x)+z11*(y2-y)*(x2-x))/delta; + return (z22*(y-y1)*(x-x1)+z12*(y2-y)*(x-x1)+z21*(y-y1)*(x2-x)+z11*(y2-y)*(x2-x))/delta; } @@ -61,106 +71,107 @@ static double wgs84_separation(double lat, double lon) { #define GEOID_ROW 19 #define GEOID_COL 37 - static const char geoid_delta[GEOID_COL*GEOID_ROW]={ - /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, - /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, - /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, - /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, - /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, - /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, - /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, - /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, - /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, - /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, - /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, - /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, - /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, - /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, - /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, - /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, - /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, - /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, - /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13}; - int ilat, ilon; - int ilat1, ilat2, ilon1, ilon2; - - /* sanity checks to prevent segfault on bad data */ - if ((lat > 90) || (lat < -90)) { - fatal(MYNAME ": Invalid latitude value (%f)\n", lat); - } - if (( lon > 180) || (lon < -180)) { - fatal(MYNAME ": Invalid longitude value (%f)\n", lon);; - } - - ilat=(int)floor(( 90.+lat)/10); - ilon=(int)floor((180.+lon)/10); - - ilat1=ilat; - ilon1=ilon; - ilat2=(ilat < GEOID_ROW-1)? ilat+1:ilat; - ilon2=(ilon < GEOID_COL-1)? ilon+1:ilon; - - return bilinear( - ilon1*10.-180.,ilat1*10.-90., - ilon2*10.-180.,ilat2*10.-90., - lon, lat, - (double)geoid_delta[ilon1+ilat1*GEOID_COL], - (double)geoid_delta[ilon2+ilat1*GEOID_COL], - (double)geoid_delta[ilon1+ilat2*GEOID_COL], - (double)geoid_delta[ilon2+ilat2*GEOID_COL] - ); + static const char geoid_delta[GEOID_COL*GEOID_ROW]= { + /* 90S */ -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, -30,-30,-30,-30,-30,-30,-30,-30,-30,-30,-30, + /* 80S */ -53,-54,-55,-52,-48,-42,-38,-38,-29,-26,-26,-24,-23,-21,-19,-16,-12, -8, -4, -1, 1, 4, 4, 6, 5, 4, 2, -6,-15,-24,-33,-40,-48,-50,-53,-52,-53, + /* 70S */ -61,-60,-61,-55,-49,-44,-38,-31,-25,-16, -6, 1, 4, 5, 4, 2, 6, 12, 16, 16, 17, 21, 20, 26, 26, 22, 16, 10, -1,-16,-29,-36,-46,-55,-54,-59,-61, + /* 60S */ -45,-43,-37,-32,-30,-26,-23,-22,-16,-10, -2, 10, 20, 20, 21, 24, 22, 17, 16, 19, 25, 30, 35, 35, 33, 30, 27, 10, -2,-14,-23,-30,-33,-29,-35,-43,-45, + /* 50S */ -15,-18,-18,-16,-17,-15,-10,-10, -8, -2, 6, 14, 13, 3, 3, 10, 20, 27, 25, 26, 34, 39, 45, 45, 38, 39, 28, 13, -1,-15,-22,-22,-18,-15,-14,-10,-15, + /* 40S */ 21, 6, 1, -7,-12,-12,-12,-10, -7, -1, 8, 23, 15, -2, -6, 6, 21, 24, 18, 26, 31, 33, 39, 41, 30, 24, 13, -2,-20,-32,-33,-27,-14, -2, 5, 20, 21, + /* 30S */ 46, 22, 5, -2, -8,-13,-10, -7, -4, 1, 9, 32, 16, 4, -8, 4, 12, 15, 22, 27, 34, 29, 14, 15, 15, 7, -9,-25,-37,-39,-23,-14, 15, 33, 34, 45, 46, + /* 20S */ 51, 27, 10, 0, -9,-11, -5, -2, -3, -1, 9, 35, 20, -5, -6, -5, 0, 13, 17, 23, 21, 8, -9,-10,-11,-20, -40,-47,-45,-25, 5, 23, 45, 58, 57, 63, 51, + /* 10S */ 36, 22, 11, 6, -1, -8,-10, -8,-11, -9, 1, 32, 4,-18,-13, -9, 4, 14, 12, 13, -2,-14,-25,-32,-38,-60, -75,-63,-26, 0, 35, 52, 68, 76, 64, 52, 36, + /* 00N */ 22, 16, 17, 13, 1,-12,-23,-20,-14, -3, 14, 10,-15,-27,-18, 3, 12, 20, 18, 12,-13, -9,-28,-49,-62,-89,-102,-63, -9, 33, 58, 73, 74, 63, 50, 32, 22, + /* 10N */ 13, 12, 11, 2,-11,-28,-38,-29,-10, 3, 1,-11,-41,-42,-16, 3, 17, 33, 22, 23, 2, -3, -7,-36,-59,-90, -95,-63,-24, 12, 53, 60, 58, 46, 36, 26, 13, + /* 20N */ 5, 10, 7, -7,-23,-39,-47,-34, -9,-10,-20,-45,-48,-32, -9, 17, 25, 31, 31, 26, 15, 6, 1,-29,-44,-61, -67,-59,-36,-11, 21, 39, 49, 39, 22, 10, 5, + /* 30N */ -7, -5, -8,-15,-28,-40,-42,-29,-22,-26,-32,-51,-40,-17, 17, 31, 34, 44, 36, 28, 29, 17, 12,-20,-15,-40, -33,-34,-34,-28, 7, 29, 43, 20, 4, -6, -7, + /* 40N */ -12,-10,-13,-20,-31,-34,-21,-16,-26,-34,-33,-35,-26, 2, 33, 59, 52, 51, 52, 48, 35, 40, 33, -9,-28,-39, -48,-59,-50,-28, 3, 23, 37, 18, -1,-11,-12, + /* 50N */ -8, 8, 8, 1,-11,-19,-16,-18,-22,-35,-40,-26,-12, 24, 45, 63, 62, 59, 47, 48, 42, 28, 12,-10,-19,-33, -43,-42,-43,-29, -2, 17, 23, 22, 6, 2, -8, + /* 60N */ 2, 9, 17, 10, 13, 1,-14,-30,-39,-46,-42,-21, 6, 29, 49, 65, 60, 57, 47, 41, 21, 18, 14, 7, -3,-22, -29,-32,-32,-26,-15, -2, 13, 17, 19, 6, 2, + /* 70N */ 2, 2, 1, -1, -3, -7,-14,-24,-27,-25,-19, 3, 24, 37, 47, 60, 61, 58, 51, 43, 29, 20, 12, 5, -2,-10, -14,-12,-10,-14,-12, -6, -2, 3, 6, 4, 2, + /* 80N */ 3, 1, -2, -3, -3, -3, -1, 3, 1, 5, 9, 11, 19, 27, 31, 34, 33, 34, 33, 34, 28, 23, 17, 13, 9, 4, 4, 1, -2, -2, 0, 2, 3, 2, 1, 1, 3, + /* 90N */ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13 + }; + int ilat, ilon; + int ilat1, ilat2, ilon1, ilon2; + + /* sanity checks to prevent segfault on bad data */ + if ((lat > 90) || (lat < -90)) { + fatal(MYNAME ": Invalid latitude value (%f)\n", lat); + } + if ((lon > 180) || (lon < -180)) { + fatal(MYNAME ": Invalid longitude value (%f)\n", lon);; + } + + ilat=(int)floor((90.+lat)/10); + ilon=(int)floor((180.+lon)/10); + + ilat1=ilat; + ilon1=ilon; + ilat2=(ilat < GEOID_ROW-1)? ilat+1:ilat; + ilon2=(ilon < GEOID_COL-1)? ilon+1:ilon; + + return bilinear( + ilon1*10.-180.,ilat1*10.-90., + ilon2*10.-180.,ilat2*10.-90., + lon, lat, + (double)geoid_delta[ilon1+ilat1*GEOID_COL], + (double)geoid_delta[ilon2+ilat1*GEOID_COL], + (double)geoid_delta[ilon1+ilat2*GEOID_COL], + (double)geoid_delta[ilon2+ilat2*GEOID_COL] + ); } static void correct_height(const waypoint *wpt) { - waypoint *waypointp = (waypoint *) wpt; + waypoint *waypointp = (waypoint *) wpt; - if (addopt) - waypointp->altitude += addf; + if (addopt) { + waypointp->altitude += addf; + } - if (wgs84tomslopt) - waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude); + if (wgs84tomslopt) { + waypointp->altitude -= wgs84_separation(waypointp->latitude, waypointp->longitude); + } } static void height_init(const char *args) { - char *unit; - - if (addopt) { - addf = strtod(addopt, &unit); - - if (*unit == 'f' || *unit== 'F') { - addf = FEET_TO_METERS(addf); - } - else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0')) { - fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit); - } - } - else { - addf = 0.0; - } + char *unit; + + if (addopt) { + addf = strtod(addopt, &unit); + + if (*unit == 'f' || *unit== 'F') { + addf = FEET_TO_METERS(addf); + } else if ((*unit != 'm') && (*unit != 'M') && (*unit != '\0')) { + fatal(MYNAME ": Invalid unit (\"%c\")! Please use \"m\" for meter or \"f\" for feet.\n", *unit); + } + } else { + addf = 0.0; + } } -static void +static void height_process(void) /* this procedure must be present in vecs */ { - waypt_disp_all(correct_height); - route_disp_all(NULL, NULL, correct_height); - track_disp_all(NULL, NULL, correct_height); + waypt_disp_all(correct_height); + route_disp_all(NULL, NULL, correct_height); + track_disp_all(NULL, NULL, correct_height); } filter_vecs_t height_vecs = { - height_init, - height_process, - NULL, - NULL, - height_args + height_init, + height_process, + NULL, + NULL, + height_args }; diff --git a/gpsbabel/hiketech.c b/gpsbabel/hiketech.c index c5f35b08d..1837611dd 100644 --- a/gpsbabel/hiketech.c +++ b/gpsbabel/hiketech.c @@ -31,7 +31,7 @@ static route_head *trk_head; static arglist_t hiketech_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Waypoints */ @@ -53,171 +53,171 @@ static xg_callback ht_trk_long; static xg_callback ht_trk_alt; static xg_tag_mapping ht_map[] = { - { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" }, - { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" }, - { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" }, - { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" }, - { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" }, - { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" }, - { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" }, - - { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" }, - { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" }, - { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" }, - { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" }, - { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" }, - { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" }, - { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" }, - { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" }, - { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" }, - { NULL, 0, NULL} + { ht_wpt_s, cb_start, "/hiketech/gpsdata/wpt" }, + { ht_wpt_e, cb_end, "/hiketech/gpsdata/wpt" }, + { ht_ident, cb_cdata, "/hiketech/gpsdata/wpt/ident" }, + { ht_sym, cb_cdata, "/hiketech/gpsdata/wpt/sym" }, + { ht_lat, cb_cdata, "/hiketech/gpsdata/wpt/lat" }, + { ht_long, cb_cdata, "/hiketech/gpsdata/wpt/long" }, + { ht_alt, cb_cdata, "/hiketech/gpsdata/wpt/alt" }, + + { ht_trk_s, cb_start, "/hiketech/gpsdata/trk" }, + { ht_trk_e, cb_end, "/hiketech/gpsdata/trk" }, + { ht_trk_ident, cb_cdata, "/hiketech/gpsdata/trk/ident" }, + { ht_trk_pnt_s, cb_start, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_pnt_e, cb_end, "/hiketech/gpsdata/trk/pnt" }, + { ht_trk_utc, cb_cdata, "/hiketech/gpsdata/trk/pnt/utc" }, + { ht_trk_lat, cb_cdata, "/hiketech/gpsdata/trk/pnt/lat" }, + { ht_trk_long, cb_cdata, "/hiketech/gpsdata/trk/pnt/long" }, + { ht_trk_alt, cb_cdata, "/hiketech/gpsdata/trk/pnt/alt" }, + { NULL, 0, NULL} }; static void hiketech_rd_init(const char *fname) { - xml_init(fname, ht_map, NULL); + xml_init(fname, ht_map, NULL); } static void hiketech_read(void) { - xml_read(); + xml_read(); } static void hiketech_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void hiketech_wr_init(const char *fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hiketech_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static void hiketech_trk_hdr(const route_head *rte) { - gbfprintf(ofd, "\n"); - write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); + gbfprintf(ofd, "\n"); + write_optional_xml_entity(ofd, " ", "ident", rte->rte_name); } static void hiketech_trk_tlr(const route_head *rte) { - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void hiketech_print_utc(time_t tm, const char *indent, const char *tag) { - char tbuf[80]; - strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); - gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); + char tbuf[80]; + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %I:%M:%S", gmtime(&tm)); + gbfprintf(ofd, "%s<%s>%s\n",indent,tag,tbuf,tag); } static void hiketech_trkpt_pr(const waypoint *waypointp) { - gbfprintf(ofd, " \n"); - if (waypointp->creation_time) { - hiketech_print_utc(waypointp->creation_time, " ", "utc"); - } - gbfprintf(ofd, " %f\n", waypointp->latitude); - gbfprintf(ofd, " %f\n", waypointp->longitude); - if (waypointp->altitude != unknown_alt) { - gbfprintf(ofd, " %f\n", - waypointp->altitude); - } - gbfprintf(ofd, " \n"); + gbfprintf(ofd, " \n"); + if (waypointp->creation_time) { + hiketech_print_utc(waypointp->creation_time, " ", "utc"); + } + gbfprintf(ofd, " %f\n", waypointp->latitude); + gbfprintf(ofd, " %f\n", waypointp->longitude); + if (waypointp->altitude != unknown_alt) { + gbfprintf(ofd, " %f\n", + waypointp->altitude); + } + gbfprintf(ofd, " \n"); } static void hiketech_waypt_pr(const waypoint *wpt) -{ - gbfprintf(ofd, "\n"); - write_xml_entity(ofd, "\t", "ident", wpt->shortname); - write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); - gbfprintf(ofd, "\t%f\n", wpt->latitude); - gbfprintf(ofd, "\t%f\n", wpt->longitude); - - /* - * These probably aren't technicallyconstants, but it's all - * we can do for now. - */ - gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); - gbfprintf(ofd, "\n"); +{ + gbfprintf(ofd, "\n"); + write_xml_entity(ofd, "\t", "ident", wpt->shortname); + write_optional_xml_entity(ofd, "\t", "sym", wpt->icon_descr); + gbfprintf(ofd, "\t%f\n", wpt->latitude); + gbfprintf(ofd, "\t%f\n", wpt->longitude); + + /* + * These probably aren't technicallyconstants, but it's all + * we can do for now. + */ + gbfprintf(ofd, "\t\n\t\tFAFFB4\n\t\tFF8000\n\t\n"); + gbfprintf(ofd, "\n"); } static void hiketech_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); - track_disp_all(NULL, NULL, hiketech_trkpt_pr); - waypt_disp_all(hiketech_waypt_pr); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + track_disp_all(hiketech_trk_hdr, hiketech_trk_tlr, hiketech_trkpt_pr); + track_disp_all(NULL, NULL, hiketech_trkpt_pr); + waypt_disp_all(hiketech_waypt_pr); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } static void ht_wpt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static void ht_ident(const char *args, const char **unused) { - wpt_tmp->shortname = xstrdup(args); + wpt_tmp->shortname = xstrdup(args); } static void ht_sym(const char *args, const char **unused) { - wpt_tmp->icon_descr = xstrdup(args); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; } static void ht_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static void ht_long(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static void ht_alt(const char *args, const char **unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } static void ht_wpt_e(const char *args, const char **unused) { - waypt_add(wpt_tmp); - wpt_tmp = NULL; + waypt_add(wpt_tmp); + wpt_tmp = NULL; } static void ht_trk_s(const char *args, const char **unused) { - trk_head = route_head_alloc(); - track_add_head(trk_head); + trk_head = route_head_alloc(); + track_add_head(trk_head); } static @@ -229,71 +229,71 @@ void ht_trk_e(const char *args, const char **unused) static void ht_trk_ident(const char *args, const char **unused) { - trk_head->rte_name = xstrdup(args); + trk_head->rte_name = xstrdup(args); } static void ht_trk_pnt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static void ht_trk_pnt_e(const char *args, const char **unused) { - track_add_wpt(trk_head, wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } static void ht_trk_utc(const char *args, const char **unused) { - struct tm tm; - time_t utc; + struct tm tm; + time_t utc; - sscanf(args, "%d-%d-%d %d:%d:%d", - &tm.tm_year, &tm.tm_mon, - &tm.tm_mday, &tm.tm_hour, - &tm.tm_min, &tm.tm_sec); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; + sscanf(args, "%d-%d-%d %d:%d:%d", + &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; - utc = mkgmtime(&tm); + utc = mkgmtime(&tm); - wpt_tmp->creation_time = utc; + wpt_tmp->creation_time = utc; } static void ht_trk_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static void ht_trk_long(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static void ht_trk_alt(const char *args, const char **unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } ff_vecs_t hiketech_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, - hiketech_rd_init, - hiketech_wr_init, - hiketech_rd_deinit, - hiketech_wr_deinit, - hiketech_read, - hiketech_write, - NULL, - hiketech_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, + hiketech_rd_init, + hiketech_wr_init, + hiketech_rd_deinit, + hiketech_wr_deinit, + hiketech_read, + hiketech_write, + NULL, + hiketech_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/holux.c b/gpsbabel/holux.c index ba1010c0c..2d3eecbcf 100644 --- a/gpsbabel/holux.c +++ b/gpsbabel/holux.c @@ -19,7 +19,7 @@ History: - 2002-09-15 J. Becker start programming + 2002-09-15 J. Becker start programming */ @@ -41,13 +41,13 @@ static short_handle mkshort_handle; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } @@ -57,11 +57,11 @@ static void rd_deinit(void) static void wr_init(const char *fname) { - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - HxWFile = xcalloc(GM100_WPO_FILE_SIZE, 1); + HxWFile = xcalloc(GM100_WPO_FILE_SIZE, 1); - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } @@ -69,118 +69,117 @@ wr_init(const char *fname) static void wr_deinit(void) -{ - mkshort_del_handle(&mkshort_handle); - gbfclose(file_out); +{ + mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); } static void data_read(void) { - char name[9], desc[90]; - double lat,lon; - unsigned char *HxWpt; - waypoint *wpt_tmp; - int iCount; - int iDataRead; - int iWptNum; - int iWptIndex; - WPT *pWptHxTmp; - struct tm tm; - struct tm *ptm; - - memset(&tm, 0, sizeof(tm)); - - HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); - - /* read the wpo file to the data-array */ - iDataRead = gbfread( HxWpt, 1, GM100_WPO_FILE_SIZE, file_in ); - - if (iDataRead == 0) - { - fatal(MYNAME ": Error reading data from %s.\n", file_in->name); - } + char name[9], desc[90]; + double lat,lon; + unsigned char *HxWpt; + waypoint *wpt_tmp; + int iCount; + int iDataRead; + int iWptNum; + int iWptIndex; + WPT *pWptHxTmp; + struct tm tm; + struct tm *ptm; + + memset(&tm, 0, sizeof(tm)); + + HxWpt = xcalloc(GM100_WPO_FILE_SIZE, 1); + + /* read the wpo file to the data-array */ + iDataRead = gbfread(HxWpt, 1, GM100_WPO_FILE_SIZE, file_in); + + if (iDataRead == 0) { + fatal(MYNAME ": Error reading data from %s.\n", file_in->name); + } + + iWptNum = le_read16(&((WPTHDR *)HxWpt)->num); + + /* Get the waypoints */ + for (iCount = 0; iCount < iWptNum ; iCount ++) { + wpt_tmp = waypt_new(); + + iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]); + pWptHxTmp = (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; + + wpt_tmp->altitude = 0; + strncpy(name,pWptHxTmp->name,sizeof(pWptHxTmp->name)); + name[sizeof(pWptHxTmp->name)]=0; + + strncpy(desc,pWptHxTmp->comment,sizeof(pWptHxTmp->comment)); + desc[sizeof(pWptHxTmp->comment)]=0; + + wpt_tmp->shortname = xstrdup(name); + wpt_tmp->description = xstrdup(desc); - iWptNum = le_read16(&((WPTHDR *)HxWpt)->num); - - /* Get the waypoints */ - for (iCount = 0; iCount < iWptNum ; iCount ++) - { - wpt_tmp = waypt_new(); - - iWptIndex = le_read16(&((WPTHDR *)HxWpt)->idx[iCount]); - pWptHxTmp = (WPT *)&HxWpt[OFFS_WPT + (sizeof(WPT) * iWptIndex)]; - - wpt_tmp->altitude = 0; - strncpy(name,pWptHxTmp->name,sizeof(pWptHxTmp->name)); - name[sizeof(pWptHxTmp->name)]=0; - - strncpy(desc,pWptHxTmp->comment,sizeof(pWptHxTmp->comment)); - desc[sizeof(pWptHxTmp->comment)]=0; - - wpt_tmp->shortname = xstrdup(name); - wpt_tmp->description = xstrdup(desc); - - wpt_tmp->creation_time = 0; - if (pWptHxTmp->date.year) - { + wpt_tmp->creation_time = 0; + if (pWptHxTmp->date.year) { #if 0 - /* Unless there's some endian swapping that I don't see, - * this can't be right. Then again, the definition of the - * the structure itself has a pretty serious disregard for - * host word size issues... - rjl - */ - ptm = gmtime((time_t*)&pWptHxTmp->time); + /* Unless there's some endian swapping that I don't see, + * this can't be right. Then again, the definition of the + * the structure itself has a pretty serious disregard for + * host word size issues... - rjl + */ + ptm = gmtime((time_t*)&pWptHxTmp->time); #else - time_t wt = le_read32(&pWptHxTmp->time); - ptm = gmtime(&wt); + time_t wt = le_read32(&pWptHxTmp->time); + ptm = gmtime(&wt); #endif - tm.tm_hour = ptm->tm_hour; - tm.tm_min = ptm->tm_min; - tm.tm_sec = ptm->tm_sec; - - tm.tm_mday = pWptHxTmp->date.day; - tm.tm_mon = pWptHxTmp->date.month - 1; - tm.tm_year = pWptHxTmp->date.year - 1900; - wpt_tmp->creation_time = mktime(&tm); - } - - lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; - lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - waypt_add(wpt_tmp); - } - xfree(HxWpt); + tm.tm_hour = ptm->tm_hour; + tm.tm_min = ptm->tm_min; + tm.tm_sec = ptm->tm_sec; + + tm.tm_mday = pWptHxTmp->date.day; + tm.tm_mon = pWptHxTmp->date.month - 1; + tm.tm_year = pWptHxTmp->date.year - 1900; + wpt_tmp->creation_time = mktime(&tm); + } + + lon = le_read32(&pWptHxTmp->pt.iLongitude) / 36000.0; + lat = (le_read32(&pWptHxTmp->pt.iLatitude) / 36000.0) * -1.0; + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + waypt_add(wpt_tmp); + } + xfree(HxWpt); } -char *mknshort (char *stIn,unsigned int sLen) +char *mknshort(char *stIn,unsigned int sLen) { - #define MAX_STRINGLEN 255 - static char strOut[MAX_STRINGLEN]; - char strTmp[MAX_STRINGLEN]; - char *shortstr = NULL; - - if (sLen > MAX_STRINGLEN) - return (stIn); - - if (stIn == NULL) - return NULL; - - setshort_length(mkshort_handle, sLen); - setshort_mustuniq(mkshort_handle, 0); - - shortstr = mkshort(mkshort_handle, stIn); - strcpy(strTmp,shortstr); - xfree(shortstr); - - memset(strOut,' ', MAX_STRINGLEN); - strncpy (strOut,strTmp,strlen(strTmp)); - return (strOut); +#define MAX_STRINGLEN 255 + static char strOut[MAX_STRINGLEN]; + char strTmp[MAX_STRINGLEN]; + char *shortstr = NULL; + + if (sLen > MAX_STRINGLEN) { + return (stIn); + } + + if (stIn == NULL) { + return NULL; + } + + setshort_length(mkshort_handle, sLen); + setshort_mustuniq(mkshort_handle, 0); + + shortstr = mkshort(mkshort_handle, stIn); + strcpy(strTmp,shortstr); + xfree(shortstr); + + memset(strOut,' ', MAX_STRINGLEN); + strncpy(strOut,strTmp,strlen(strTmp)); + return (strOut); } @@ -188,63 +187,66 @@ char *mknshort (char *stIn,unsigned int sLen) static void holux_disp(const waypoint *wpt) { - double lon,lat; - struct tm *tm; - short sIndex; - WPT *pWptHxTmp; - - lon =(double)wpt->longitude * 36000; - lat =(double)wpt->latitude * -36000; - - - /* round it to increase the accuracy */ - if (lon != 0) lon += (double)((int)lon/abs((int)lon)) * .5; - if (lat != 0) lat += (double)((int)lat/abs((int)lat)) * .5; - - sIndex = le_read16(&((WPTHDR *)HxWFile)->num); - ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ - le_write16(&((WPTHDR *)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ - ((WPTHDR *)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ - - - /* set Waypoint */ - pWptHxTmp = (WPT *)&HxWFile[OFFS_WPT + (sizeof(WPT) * sIndex)]; - - memset (pWptHxTmp->name,0x20,sizeof(pWptHxTmp->name)); - if (wpt->shortname != NULL) - strncpy(pWptHxTmp->name, mknshort(wpt->shortname,sizeof(pWptHxTmp->name)),sizeof(pWptHxTmp->name)); - else - sprintf(pWptHxTmp->name,"W%d",sIndex); - - memset (pWptHxTmp->comment,0x20,sizeof(pWptHxTmp->comment)); - if (wpt->description != NULL) - strncpy(pWptHxTmp->comment, mknshort(wpt->description,sizeof(pWptHxTmp->comment)),sizeof(pWptHxTmp->comment)); - - /*set the time */ - if (wpt->creation_time) - { - /* tm = gmtime(&wpt->creation_time);*/ /* I get the wrong result with gmtime ??? */ - tm = localtime(&wpt->creation_time); - pWptHxTmp->time = (tm->tm_hour * 3600) + (tm->tm_min * 60) +tm->tm_sec; - pWptHxTmp->date.day = tm->tm_mday; - pWptHxTmp->date.month = tm->tm_mon + 1; - pWptHxTmp->date.year = tm->tm_year + 1900; - } - else - { - pWptHxTmp->time = 0; - pWptHxTmp->date.day = 0; - pWptHxTmp->date.month = 0; - pWptHxTmp->date.year = 0; - } - - - le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); - le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); - pWptHxTmp->checked = 01; - pWptHxTmp->vocidx = (short)0xffff; - le_write16(&((WPTHDR *)HxWFile)->num, ++sIndex); - le_write16(&((WPTHDR *)HxWFile)->next, ++sIndex); + double lon,lat; + struct tm *tm; + short sIndex; + WPT *pWptHxTmp; + + lon =(double)wpt->longitude * 36000; + lat =(double)wpt->latitude * -36000; + + + /* round it to increase the accuracy */ + if (lon != 0) { + lon += (double)((int)lon/abs((int)lon)) * .5; + } + if (lat != 0) { + lat += (double)((int)lat/abs((int)lat)) * .5; + } + + sIndex = le_read16(&((WPTHDR *)HxWFile)->num); + ((WPTHDR *)HxWFile)->idx[sIndex] = sIndex; /* set the waypoint index */ + le_write16(&((WPTHDR *)HxWFile)->idx[sIndex], sIndex); /* set the waypoint index */ + ((WPTHDR *)HxWFile)->used[sIndex] = 0xff; /* Waypoint used */ + + + /* set Waypoint */ + pWptHxTmp = (WPT *)&HxWFile[OFFS_WPT + (sizeof(WPT) * sIndex)]; + + memset(pWptHxTmp->name,0x20,sizeof(pWptHxTmp->name)); + if (wpt->shortname != NULL) { + strncpy(pWptHxTmp->name, mknshort(wpt->shortname,sizeof(pWptHxTmp->name)),sizeof(pWptHxTmp->name)); + } else { + sprintf(pWptHxTmp->name,"W%d",sIndex); + } + + memset(pWptHxTmp->comment,0x20,sizeof(pWptHxTmp->comment)); + if (wpt->description != NULL) { + strncpy(pWptHxTmp->comment, mknshort(wpt->description,sizeof(pWptHxTmp->comment)),sizeof(pWptHxTmp->comment)); + } + + /*set the time */ + if (wpt->creation_time) { + /* tm = gmtime(&wpt->creation_time);*/ /* I get the wrong result with gmtime ??? */ + tm = localtime(&wpt->creation_time); + pWptHxTmp->time = (tm->tm_hour * 3600) + (tm->tm_min * 60) +tm->tm_sec; + pWptHxTmp->date.day = tm->tm_mday; + pWptHxTmp->date.month = tm->tm_mon + 1; + pWptHxTmp->date.year = tm->tm_year + 1900; + } else { + pWptHxTmp->time = 0; + pWptHxTmp->date.day = 0; + pWptHxTmp->date.month = 0; + pWptHxTmp->date.year = 0; + } + + + le_write32(&pWptHxTmp->pt.iLatitude,(unsigned int) lat); + le_write32(&pWptHxTmp->pt.iLongitude,(unsigned int) lon); + pWptHxTmp->checked = 01; + pWptHxTmp->vocidx = (short)0xffff; + le_write16(&((WPTHDR *)HxWFile)->num, ++sIndex); + le_write16(&((WPTHDR *)HxWFile)->next, ++sIndex); } @@ -254,55 +256,58 @@ static void holux_disp(const waypoint *wpt) static void data_write(void) { - int iWritten; - short sCount; - - /* init the waypoint area*/ - le_write32(&((WPTHDR *)HxWFile)->id, WPT_HDR_ID); - ((WPTHDR *)HxWFile)->num = 0; - ((WPTHDR *)HxWFile)->next = 0; - - /* clear index list */ - for (sCount = 0; sCount < MAXWPT; sCount++) - ((WPTHDR *)HxWFile)->idx[sCount] = (signed short)-1; - for (sCount = 0; sCount < MAXWPT; sCount++) - ((WPTHDR *)HxWFile)->used[sCount] = 0; - - /* init the route area */ - le_write32(&((RTEHDR *)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); - ((RTEHDR *)&HxWFile[ROUTESTART])->num = 0; - le_write16(&((RTEHDR *)&HxWFile[ROUTESTART])->next, 1); - ((RTEHDR *)&HxWFile[ROUTESTART])->rteno = (signed short)-1; - - /* clear index list */ - for (sCount = 0; sCount < MAXRTE; sCount++) - ((RTEHDR *)&HxWFile[ROUTESTART])->idx[sCount] = (signed short)-1; - for (sCount = 0; sCount < MAXRTE; sCount++) - ((RTEHDR *)&HxWFile[ROUTESTART])->used[sCount] = 0; - - waypt_disp_all(holux_disp); - - iWritten = gbfwrite (HxWFile, 1, GM100_WPO_FILE_SIZE,file_out); - if (iWritten == 0) - { - fatal(MYNAME ": Error writing data to %s.\n", file_out->name); - } - xfree(HxWFile); + int iWritten; + short sCount; + + /* init the waypoint area*/ + le_write32(&((WPTHDR *)HxWFile)->id, WPT_HDR_ID); + ((WPTHDR *)HxWFile)->num = 0; + ((WPTHDR *)HxWFile)->next = 0; + + /* clear index list */ + for (sCount = 0; sCount < MAXWPT; sCount++) { + ((WPTHDR *)HxWFile)->idx[sCount] = (signed short)-1; + } + for (sCount = 0; sCount < MAXWPT; sCount++) { + ((WPTHDR *)HxWFile)->used[sCount] = 0; + } + + /* init the route area */ + le_write32(&((RTEHDR *)&HxWFile[ROUTESTART])->id, RTE_HDR_ID); + ((RTEHDR *)&HxWFile[ROUTESTART])->num = 0; + le_write16(&((RTEHDR *)&HxWFile[ROUTESTART])->next, 1); + ((RTEHDR *)&HxWFile[ROUTESTART])->rteno = (signed short)-1; + + /* clear index list */ + for (sCount = 0; sCount < MAXRTE; sCount++) { + ((RTEHDR *)&HxWFile[ROUTESTART])->idx[sCount] = (signed short)-1; + } + for (sCount = 0; sCount < MAXRTE; sCount++) { + ((RTEHDR *)&HxWFile[ROUTESTART])->used[sCount] = 0; + } + + waypt_disp_all(holux_disp); + + iWritten = gbfwrite(HxWFile, 1, GM100_WPO_FILE_SIZE,file_out); + if (iWritten == 0) { + fatal(MYNAME ": Error writing data to %s.\n", file_out->name); + } + xfree(HxWFile); } ff_vecs_t holux_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/holux.h b/gpsbabel/holux.h index cab9e077c..8647566e2 100644 --- a/gpsbabel/holux.h +++ b/gpsbabel/holux.h @@ -18,8 +18,8 @@ */ - /* header file for the holux gm-100 wpo format */ - +/* header file for the holux gm-100 wpo format */ + #ifndef BYTE #define BYTE unsigned char #endif @@ -33,8 +33,8 @@ #endif -/* #define GM100_WPO_FILE_SIZE 25512 */ /* size of a holux gm-100 wpo file used by mapShow 1.4*/ -#define GM100_WPO_FILE_SIZE 25600 /* size of a holux gm-100 wpo file used by the GM-100*/ +/* #define GM100_WPO_FILE_SIZE 25512 */ /* size of a holux gm-100 wpo file used by mapShow 1.4*/ +#define GM100_WPO_FILE_SIZE 25600 /* size of a holux gm-100 wpo file used by the GM-100*/ #define ROUTESTART 23600 /* Offset for start of route */ #define MAXWPT 500 /* max number of waypoint */ @@ -45,73 +45,67 @@ #define RTE_HDR_ID 0xD87F59F0 /* route header */ - /* Offsets */ -#define OFFS_WPT 0x05E4 /* offet for waypoint table */ +/* Offsets */ +#define OFFS_WPT 0x05E4 /* offet for waypoint table */ -typedef struct tagWPTHDR -{ - DWORD id; /* WPT_HDR_ID */ - short num; /* Current wpt number */ - short next; /* next wpt number */ - short idx[MAXWPT]; /* saving wpt index here for each wpt, default was -1*/ - BYTE used[MAXWPT]; /* Have the match wpt been used (0xFF), Default was 0 */ -}WPTHDR; +typedef struct tagWPTHDR { + DWORD id; /* WPT_HDR_ID */ + short num; /* Current wpt number */ + short next; /* next wpt number */ + short idx[MAXWPT]; /* saving wpt index here for each wpt, default was -1*/ + BYTE used[MAXWPT]; /* Have the match wpt been used (0xFF), Default was 0 */ +} WPTHDR; -typedef struct tagPOINT -{ - signed int iLongitude; - signed int iLatitude; -}POINT; +typedef struct tagPOINT { + signed int iLongitude; + signed int iLatitude; +} POINT; -typedef struct tagDATE -{ - BYTE day; - BYTE month; - short year; -}HX_DATE; +typedef struct tagDATE { + BYTE day; + BYTE month; + short year; +} HX_DATE; -typedef struct tagWPT -{ - char name[8]; /* wpt name */ - char comment[12]; /* comment string */ - POINT pt; /* waypoint location */ - short vocidx; /* voice index, not used */ - short usecount; /* counter: times used by routes */ - HX_DATE date; /* date */ - unsigned time; /* time */ - char checked; /* Active or not */ - BYTE dummy[3]; /* fill bytes */ -}WPT; +typedef struct tagWPT { + char name[8]; /* wpt name */ + char comment[12]; /* comment string */ + POINT pt; /* waypoint location */ + short vocidx; /* voice index, not used */ + short usecount; /* counter: times used by routes */ + HX_DATE date; /* date */ + unsigned time; /* time */ + char checked; /* Active or not */ + BYTE dummy[3]; /* fill bytes */ +} WPT; -typedef struct tagRTEHDR -{ - DWORD id; /* RTE_HDR_ID */ - short num; /* Current route number */ - short next; /* next route number */ - signed short idx[MAXRTE]; /* saving route index here for each route, default was -1 */ - BYTE used[MAXRTE]; /* Have the wpt been used (0xFF), Default was 0 */ - signed short rteno; /* Saving navigationroute number here */ -}RTEHDR; +typedef struct tagRTEHDR { + DWORD id; /* RTE_HDR_ID */ + short num; /* Current route number */ + short next; /* next route number */ + signed short idx[MAXRTE]; /* saving route index here for each route, default was -1 */ + BYTE used[MAXRTE]; /* Have the wpt been used (0xFF), Default was 0 */ + signed short rteno; /* Saving navigationroute number here */ +} RTEHDR; -typedef struct tagRTE -{ - char name[8]; /* route name */ - char comment[12]; /* comment string */ - short wptnum; /* the total waypoint number */ - short wptidx[MAXWPTINRTE]; /* the waypoint index in this route */ - short reserved; - int date; /* date */ - int time; /* time */ -}RTE; +typedef struct tagRTE { + char name[8]; /* route name */ + char comment[12]; /* comment string */ + short wptnum; /* the total waypoint number */ + short wptidx[MAXWPTINRTE]; /* the waypoint index in this route */ + short reserved; + int date; /* date */ + int time; /* time */ +} RTE; diff --git a/gpsbabel/hsa_ndv.c b/gpsbabel/hsa_ndv.c index 867062280..83d8eb851 100644 --- a/gpsbabel/hsa_ndv.c +++ b/gpsbabel/hsa_ndv.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2004 HSA Systems, Sven Dowideit This program is free software; you can redistribute it and/or modify @@ -44,7 +44,7 @@ static gbfile *ofd; static arglist_t hsa_ndv_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; #define MYNAME "HsaNdv" @@ -55,7 +55,7 @@ arglist_t hsa_ndv_args[] = { static void hsa_ndv_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded HSA Endeavour support because expat was not installed.\n"); } static void @@ -67,238 +67,189 @@ hsa_ndv_read(void) static void hsa_ndv_start(void *data, const XML_Char *xml_el, const XML_Char **attr) { - const char *el = xml_convert_to_char_string(xml_el); - + const char *el = xml_convert_to_char_string(xml_el); + // printf("<%s>\n", el); - if (strcmp(el, "Export") == 0) - {//should only be one - } - else if (strcmp(el, "Route") == 0) - { - in_Route++; - } - else if (strcmp(el, "Chartwork") == 0) - { - in_ChartWork++; - } - else if (strcmp(el, "Object") == 0) - { - wpt_tmp = waypt_new(); - wpt_tmp->altitude = unknown_alt; - in_Object++; - } - //reset data :) - memset(cdatastr,0, MY_CBUF); - xml_free_converted_string(el); + if (strcmp(el, "Export") == 0) { + //should only be one + } else if (strcmp(el, "Route") == 0) { + in_Route++; + } else if (strcmp(el, "Chartwork") == 0) { + in_ChartWork++; + } else if (strcmp(el, "Object") == 0) { + wpt_tmp = waypt_new(); + wpt_tmp->altitude = unknown_alt; + in_Object++; + } + //reset data :) + memset(cdatastr,0, MY_CBUF); + xml_free_converted_string(el); } static void hsa_ndv_end(void *data, const XML_Char *xml_el) { - const char *el = xml_convert_to_char_string(xml_el); - if (in_Route) - { - if (strcmp(el, "Version") == 0) - {//don't really care - } - else if (strcmp(el, "Name") == 0) - { - routeName = xstrdup(cdatastr); - } - else if (strcmp(el, "LastModified") == 0) - {//don't really care - } - if (in_Object) - { - if (strcmp(el, "ClassName") == 0) - { - } - else if (strcmp(el, "Attr") == 0) - { - getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - getAttr(cdatastr, ATTR_USRMRK, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - } - else if (strcmp(el, "LegAttr") == 0) - { - } - else if (strcmp(el, "NumberOfVertexs") == 0) - { - } - else if (strcmp(el, "Latitude") == 0) - { - wpt_tmp->latitude = atof(cdatastr); - } - else if (strcmp(el, "Longitude") == 0) - { - wpt_tmp->longitude = atof(cdatastr); - } - } - } - - if (in_ChartWork) - { - if (strcmp(el, "Version") == 0) - {//don't really care - } - if (in_Object) - { - if (strcmp(el, "ClassName") == 0) - { + const char *el = xml_convert_to_char_string(xml_el); + if (in_Route) { + if (strcmp(el, "Version") == 0) { + //don't really care + } else if (strcmp(el, "Name") == 0) { + routeName = xstrdup(cdatastr); + } else if (strcmp(el, "LastModified") == 0) { + //don't really care + } + if (in_Object) { + if (strcmp(el, "ClassName") == 0) { + } else if (strcmp(el, "Attr") == 0) { + getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + getAttr(cdatastr, ATTR_USRMRK, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } else if (strcmp(el, "LegAttr") == 0) { + } else if (strcmp(el, "NumberOfVertexs") == 0) { + } else if (strcmp(el, "Latitude") == 0) { + wpt_tmp->latitude = atof(cdatastr); + } else if (strcmp(el, "Longitude") == 0) { + wpt_tmp->longitude = atof(cdatastr); + } + } + } + + if (in_ChartWork) { + if (strcmp(el, "Version") == 0) { + //don't really care + } + if (in_Object) { + if (strcmp(el, "ClassName") == 0) { // className = xstrdup(cdatastr); - } - else if (strcmp(el, "Attr") == 0) - { - //getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - //getAttr(cdatastr, ATTR_SHIPNAME, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); - } - else if (strcmp(el, "NumberOfVertexs") == 0) - { - } - else if (strcmp(el, "Latitude") == 0) - { - wpt_tmp->latitude = atof(cdatastr); - } - else if (strcmp(el, "Longitude") == 0) - { - wpt_tmp->longitude = atof(cdatastr); - } - else if (strcmp(el, "Time") == 0) - { - wpt_tmp->creation_time = atoi(cdatastr); - } - } - } - - //ignore everything else for now.. - memset(cdatastr,0, MY_CBUF); - - if (strcmp(el, "Object") == 0) - { - if (in_Route) - { - waypt_add(wpt_tmp); - } - else if (in_ChartWork) - { - //TODO: not sure how i want to handle this.. - } - in_Object--; - } - else if (strcmp(el, "Route") == 0) - { - in_Route--; - } - else if (strcmp(el, "Chartwork") == 0) - { - in_ChartWork--; - } - xml_free_converted_string(el); + } else if (strcmp(el, "Attr") == 0) { + //getAttr(cdatastr, ATTR_OBJECTNAME, &wpt_tmp->shortname, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + //getAttr(cdatastr, ATTR_SHIPNAME, &wpt_tmp->description, REPLACEMENT_SIRIUS_ATTR_SEPARATOR); + } else if (strcmp(el, "NumberOfVertexs") == 0) { + } else if (strcmp(el, "Latitude") == 0) { + wpt_tmp->latitude = atof(cdatastr); + } else if (strcmp(el, "Longitude") == 0) { + wpt_tmp->longitude = atof(cdatastr); + } else if (strcmp(el, "Time") == 0) { + wpt_tmp->creation_time = atoi(cdatastr); + } + } + } + + //ignore everything else for now.. + memset(cdatastr,0, MY_CBUF); + + if (strcmp(el, "Object") == 0) { + if (in_Route) { + waypt_add(wpt_tmp); + } else if (in_ChartWork) { + //TODO: not sure how i want to handle this.. + } + in_Object--; + } else if (strcmp(el, "Route") == 0) { + in_Route--; + } else if (strcmp(el, "Chartwork") == 0) { + in_ChartWork--; + } + xml_free_converted_string(el); } static void hsa_ndv_cdata(void *dta, const XML_Char *s, int len) { - char *estr; - estr = cdatastr + strlen(cdatastr); - memcpy(estr, s, len); + char *estr; + estr = cdatastr + strlen(cdatastr); + memcpy(estr, s, len); } static void hsa_ndv_rd_init(const char *fname) { - fd = gbfopen(fname, "r", MYNAME); + fd = gbfopen(fname, "r", MYNAME); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); - cdatastr = xcalloc(MY_CBUF,1); - XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, hsa_ndv_start, hsa_ndv_end); + cdatastr = xcalloc(MY_CBUF,1); + XML_SetCharacterDataHandler(psr, hsa_ndv_cdata); } static void hsa_ndv_read(void) { - int len; - char buf[MY_CBUF + 1]; - - while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) - { - char *bad; - - buf[len] = '\0'; - if (NULL != strstr(buf, "nver=1")) - {//its the older format, not xml - gbfseek(fd, 0, SEEK_SET); - readVersion4(fd); - break; - } - //grumble - have to remove \x1f's from sirius attributes - bad = buf; - while (NULL != (bad = strchr(bad, '\x1f'))) - { - *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; - } - if (!XML_Parse(psr, buf, len, gbfeof(fd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - - XML_ParserFree(psr); + int len; + char buf[MY_CBUF + 1]; + + while ((len = gbfread(buf, 1, sizeof(buf) - 1, fd))) { + char *bad; + + buf[len] = '\0'; + if (NULL != strstr(buf, "nver=1")) { + //its the older format, not xml + gbfseek(fd, 0, SEEK_SET); + readVersion4(fd); + break; + } + //grumble - have to remove \x1f's from sirius attributes + bad = buf; + while (NULL != (bad = strchr(bad, '\x1f'))) { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + if (!XML_Parse(psr, buf, len, gbfeof(fd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); } #endif static void getAttr(const char *data, const char *attr, char **val, char seperator) { - char *start; - if ((start = strstr(data, attr)) != NULL) - { - char *end; - int len; - - end = strchr(start, seperator); - if (end == NULL) - { - end = start + strlen(start);//assume we are teh last attr - } - - len = end-start - strlen(attr); - - *val = xcalloc(len+1, 1); - memcpy(*val, start+strlen(attr), len); - (*val)[len] = '\0'; - } - else - { - *val = xcalloc(1, 1); - (*val)[0] = '\0'; - } + char *start; + if ((start = strstr(data, attr)) != NULL) { + char *end; + int len; + + end = strchr(start, seperator); + if (end == NULL) { + end = start + strlen(start);//assume we are teh last attr + } + + len = end-start - strlen(attr); + + *val = xcalloc(len+1, 1); + memcpy(*val, start+strlen(attr), len); + (*val)[len] = '\0'; + } else { + *val = xcalloc(1, 1); + (*val)[0] = '\0'; + } } static void hsa_ndv_rd_deinit(void) { - if ( cdatastr ) { - xfree(cdatastr); - } - gbfclose(fd); + if (cdatastr) { + xfree(cdatastr); + } + gbfclose(fd); } static void hsa_ndv_wr_init(const char *fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void hsa_ndv_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static int legNum = 0; @@ -307,35 +258,35 @@ static void hsa_ndv_waypt_pr(const waypoint *waypointp) { - gbfprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); - gbfprintf(ofd, "\t\t\twaypnt\n"); + gbfprintf(ofd, "\t\t\twaypnt\n"); //ignore these for now, they are s57 specific // fprintf(ofd, "\t\t\t0\n"); // fprintf(ofd, "\t\t\t1\n"); // fprintf(ofd, "\t\t\t1089009023\n"); - gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); - gbfprintf(ofd, "\t\t\t\n", routeName); - gbfprintf(ofd, "\t\t\t1\n"); - gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); - gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); + gbfprintf(ofd, "\t\t\t\n", routeName, waypointp->shortname, legNum, waypointp->description); + gbfprintf(ofd, "\t\t\t\n", routeName); + gbfprintf(ofd, "\t\t\t1\n"); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->latitude); + gbfprintf(ofd, "\t\t\t%lf\n", waypointp->longitude); - gbfprintf(ofd, "\t\t\n"); + gbfprintf(ofd, "\t\t\n"); - legNum++; + legNum++; } static void hsa_ndv_write(void) { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\t\n"); - gbfprintf(ofd, "\t\t1.0000000\n"); - gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ - gbfprintf(ofd, "\t\t0\n"); - waypt_disp_all(hsa_ndv_waypt_pr); - gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\t\n"); + gbfprintf(ofd, "\t\t1.0000000\n"); + gbfprintf(ofd, "\t\tROUTENAME\n"); /*TODO: used filename? */ + gbfprintf(ofd, "\t\t0\n"); + waypt_disp_all(hsa_ndv_waypt_pr); + gbfprintf(ofd, "\t\n"); //later we'll import past tracks and chart objects? // fprintf(ofd, "\t\n"); @@ -344,21 +295,21 @@ hsa_ndv_write(void) // fprintf(ofd, "\t\n"); - gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); } ff_vecs_t HsaEndeavourNavigator_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - hsa_ndv_rd_init, - hsa_ndv_wr_init, - hsa_ndv_rd_deinit, - hsa_ndv_wr_deinit, - hsa_ndv_read, - hsa_ndv_write, - NULL, - hsa_ndv_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + hsa_ndv_rd_init, + hsa_ndv_wr_init, + hsa_ndv_rd_deinit, + hsa_ndv_wr_deinit, + hsa_ndv_read, + hsa_ndv_write, + NULL, + hsa_ndv_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ////////////////////////////////////////////////////////////////////////// @@ -381,179 +332,181 @@ static int readPositionRecord(gbfile* pFile, double* lat, double* lng, long* tim static void readVersion4(gbfile* pFile) { - while( TRUE ) - { - char recData[256] = {0}; - // get the position - double lat2, lng2 = 0; - - // set the pointer to the time stamp depending - // on whether we have a sounding array or not - long ts1, ts2; - long* pts1 = 0; - long* pts2 = 0; - - int soundArray = FALSE; - int numberOfVerticies = 0; - char className[256]; - char attr[1024]; - int Vertex; - - memset(attr, 0, sizeof(attr)); - - wpt_tmp = waypt_new(); - - // read the first record - if( !readRecord( pFile, EF_NVER_REC, recData) ) - // no first record then finished - break; - - // get the type - sscanf( (const char*)recData, "%d", &numberOfVerticies); - - // do we have a sounding array - if( *((const char *)recData + strlen(recData) - 1) == SOUNDARRAY_CHAR ) - { - soundArray = TRUE; - } - - if( soundArray ) - { - pts1 = &ts1; - pts2 = &ts2; - } - - // go through the vertices - for( Vertex = 0; Vertex < numberOfVerticies; Vertex++) - { - // read vertex position - if( !readPositionRecord( pFile, &lat2, &lng2, pts2) ) { - xfree(wpt_tmp); - return; - } - - wpt_tmp->longitude = lng2; - wpt_tmp->latitude = lat2; - break;//TODO: ignore more points for now - } - - - // read the class name - if( !readRecord( pFile, EF_CLNM_REC, className) ) { - xfree( wpt_tmp ); - return; - } - - // read the attributes name - if( !readRecord( pFile, EF_ATTR_REC, attr) ) { - xfree( wpt_tmp ); - return; - } - getAttr(attr, ATTR_OBJECTNAME, &wpt_tmp->shortname, '\x1f'); - getAttr(attr, ATTR_USRMRK, &wpt_tmp->description, '\x1f'); - - { - char *bad; - //remove \n and \x1f from description data - while (NULL != (bad = strchr(wpt_tmp->description, '\x1f'))) - { - *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; - } - while (NULL != (bad = strchr(wpt_tmp->description, '\n'))) - { - *bad = ' '; - } - while (NULL != (bad = strchr(wpt_tmp->description, '\r'))) - { - *bad = ' '; - } - } - - waypt_add(wpt_tmp); - } - - gbfclose(pFile); - return; + while (TRUE) { + char recData[256] = {0}; + // get the position + double lat2, lng2 = 0; + + // set the pointer to the time stamp depending + // on whether we have a sounding array or not + long ts1, ts2; + long* pts1 = 0; + long* pts2 = 0; + + int soundArray = FALSE; + int numberOfVerticies = 0; + char className[256]; + char attr[1024]; + int Vertex; + + memset(attr, 0, sizeof(attr)); + + wpt_tmp = waypt_new(); + + // read the first record + if (!readRecord(pFile, EF_NVER_REC, recData)) + // no first record then finished + { + break; + } + + // get the type + sscanf((const char*)recData, "%d", &numberOfVerticies); + + // do we have a sounding array + if (*((const char *)recData + strlen(recData) - 1) == SOUNDARRAY_CHAR) { + soundArray = TRUE; + } + + if (soundArray) { + pts1 = &ts1; + pts2 = &ts2; + } + + // go through the vertices + for (Vertex = 0; Vertex < numberOfVerticies; Vertex++) { + // read vertex position + if (!readPositionRecord(pFile, &lat2, &lng2, pts2)) { + xfree(wpt_tmp); + return; + } + + wpt_tmp->longitude = lng2; + wpt_tmp->latitude = lat2; + break;//TODO: ignore more points for now + } + + + // read the class name + if (!readRecord(pFile, EF_CLNM_REC, className)) { + xfree(wpt_tmp); + return; + } + + // read the attributes name + if (!readRecord(pFile, EF_ATTR_REC, attr)) { + xfree(wpt_tmp); + return; + } + getAttr(attr, ATTR_OBJECTNAME, &wpt_tmp->shortname, '\x1f'); + getAttr(attr, ATTR_USRMRK, &wpt_tmp->description, '\x1f'); + + { + char *bad; + //remove \n and \x1f from description data + while (NULL != (bad = strchr(wpt_tmp->description, '\x1f'))) { + *bad = REPLACEMENT_SIRIUS_ATTR_SEPARATOR; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\n'))) { + *bad = ' '; + } + while (NULL != (bad = strchr(wpt_tmp->description, '\r'))) { + *bad = ' '; + } + } + + waypt_add(wpt_tmp); + } + + gbfclose(pFile); + return; } // read a record to a file static int readRecord(gbfile* pFile, const char* pRecName, char *recData) { - // get the rec name - int len; - char recName[ED_REC_NAME_SIZE+1]; - char arrRecData[256]; + // get the rec name + int len; + char recName[ED_REC_NAME_SIZE+1]; + char arrRecData[256]; - for( len = 0; len < ED_REC_NAME_SIZE; len++) - { - int c = gbfgetc(pFile); + for (len = 0; len < ED_REC_NAME_SIZE; len++) { + int c = gbfgetc(pFile); - // if we hit EOF failed - if( c == EOF ) - return FALSE; + // if we hit EOF failed + if (c == EOF) { + return FALSE; + } - recName[len] = c; - } + recName[len] = c; + } - // if the record name is not the reqiured type then error - if( strncmp( recName, pRecName, ED_REC_NAME_SIZE) != 0 ) - return FALSE; + // if the record name is not the reqiured type then error + if (strncmp(recName, pRecName, ED_REC_NAME_SIZE) != 0) { + return FALSE; + } - // get the rec data - for( len = 0; TRUE; len++) - { - int c = gbfgetc( pFile); + // get the rec data + for (len = 0; TRUE; len++) { + int c = gbfgetc(pFile); - // if we hit EOF failed - if( c == EOF ) - return FALSE; + // if we hit EOF failed + if (c == EOF) { + return FALSE; + } - // hit end of line - if( c == EF_RECORD_DELIMTER ) - break; + // hit end of line + if (c == EF_RECORD_DELIMTER) { + break; + } - arrRecData[len] = c; - } + arrRecData[len] = c; + } - // get the rec data to a string - strncpy(recData, arrRecData, len); + // get the rec data to a string + strncpy(recData, arrRecData, len); - return TRUE; + return TRUE; } // read position -static int readPositionRecord(gbfile* pFile, double* lat, double* lng, - long* timeStamp) +static int readPositionRecord(gbfile* pFile, double* lat, double* lng, + long* timeStamp) { - // read the lat record - char recData[256] = {0}; - - if( !readRecord( pFile, EF_LAT_REC, recData) ) - // no lat record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%lf", lat); - - // read the lng record - if( !readRecord( pFile, EF_LONG_REC, recData) ) - // no first record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%lf", lng); - - // if we are to read a time record - if( timeStamp ) - { - // read the lng record - if( !readRecord( pFile, EF_TIME_REC, recData) ) - // no first record then finished - return FALSE; - - // read the latitude - sscanf( (const char*)recData, "%ld", timeStamp); - } - - return TRUE; + // read the lat record + char recData[256] = {0}; + + if (!readRecord(pFile, EF_LAT_REC, recData)) + // no lat record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%lf", lat); + + // read the lng record + if (!readRecord(pFile, EF_LONG_REC, recData)) + // no first record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%lf", lng); + + // if we are to read a time record + if (timeStamp) { + // read the lng record + if (!readRecord(pFile, EF_TIME_REC, recData)) + // no first record then finished + { + return FALSE; + } + + // read the latitude + sscanf((const char*)recData, "%ld", timeStamp); + } + + return TRUE; } diff --git a/gpsbabel/html.c b/gpsbabel/html.c index ee1cc53be..5d018a8af 100644 --- a/gpsbabel/html.c +++ b/gpsbabel/html.c @@ -37,17 +37,27 @@ static char *altunits = NULL; static arglist_t html_args[] = { - { "stylesheet", &stylesheet, - "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "encrypt", &html_encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "degformat", °format, - "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, - { "altunits", &altunits, - "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "stylesheet", &stylesheet, + "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "encrypt", &html_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; @@ -55,241 +65,241 @@ arglist_t html_args[] = { static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void html_disp(const waypoint *wpt) { - char tbuf[1024]; - char *cout; - time_t tm = wpt->creation_time; - gbint32 utmz; - double utme, utmn; - char utmzc; - fs_xml *fs_gpx = NULL; - - - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - - if (tm == 0) - tm = time(NULL); - strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - - - gbfprintf(file_out, "\n
\n", wpt->shortname); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - - gbfprintf (file_out, "\n"); - - - gbfprintf(file_out, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); - cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1); - gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); - xfree (cout); - if (wpt->altitude != unknown_alt) - gbfprintf (file_out, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); - gbfprintf (file_out, "
\n"); - if (strcmp(wpt->description, wpt->shortname)) { - if (wpt->url) { - char *d = html_entitize(wpt->description); - gbfprintf(file_out, "%s", wpt->url, d); - xfree(d); - } - else { - gbfprintf(file_out, "%s", wpt->description); - } - if (wpt->gc_data->placer) { - gbfprintf(file_out, " by %s", wpt->gc_data->placer); - } - } - gbfprintf(file_out, "

"); - if (wpt->gc_data->terr) { - gbfprintf (file_out, "

%d%s / %d%s
\n", - (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?"½":"", - (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?"½":"" ); - gbfprintf(file_out, "%s / %s

", - gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container)); - } - gbfprintf(file_out, "
"); - if (wpt->gc_data->desc_short.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_short.utfstring); - gbfprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data->desc_long.utfstring) { - char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_long.utfstring); - gbfprintf (file_out, "

%s

\n", tmpstr ); - xfree( tmpstr ); - } - if (wpt->gc_data->hint) { - char *hint = NULL; - if ( html_encrypt ) - hint = rot13( wpt->gc_data->hint ); - else - hint = xstrdup( wpt->gc_data->hint ); - gbfprintf (file_out, "

Hint: %s

\n", hint); - xfree( hint ); - } - else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - gbfprintf (file_out, "

%s

\n", wpt->notes); - } - - fs_gpx = NULL; - if ( includelogs ) { - fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); - } - - if ( fs_gpx && fs_gpx->tag ) { - xml_tag *root = fs_gpx->tag; - xml_tag *curlog = NULL; - xml_tag *logpart = NULL; - curlog = xml_findfirst( root, "groundspeak:log" ); - while ( curlog ) { - time_t logtime = 0; - struct tm *logtm = NULL; - gbfprintf( file_out, "

\n" ); - - logpart = xml_findfirst( curlog, "groundspeak:type" ); - if ( logpart ) { - gbfprintf( file_out, "%s by ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:finder" ); - if ( logpart ) { - char *f = html_entitize( logpart->cdata ); - gbfprintf( file_out, "%s on ", f ); - xfree( f ); - } - - logpart = xml_findfirst( curlog, "groundspeak:date" ); - if ( logpart ) { - logtime = xml_parse_time( logpart->cdata, NULL); - logtm = localtime( &logtime ); - if ( logtm ) { - gbfprintf( file_out, - "%04d-%02d-%02d
\n", - logtm->tm_year+1900, - logtm->tm_mon+1, - logtm->tm_mday ); - } - } - - logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); - if ( logpart ) { - char *coordstr = NULL; - float lat = 0; - float lon = 0; - coordstr = xml_attribute( logpart, "lat" ); - if ( coordstr ) { - lat = atof( coordstr ); - } - coordstr = xml_attribute( logpart, "lon" ); - if ( coordstr ) { - lon = atof( coordstr ); - } - coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1); - gbfprintf( file_out, - "%s
\n", - coordstr ); - xfree(coordstr); - } - - logpart = xml_findfirst( curlog, "groundspeak:text" ); - if ( logpart ) { - char *encstr = NULL; - char *s = NULL; - char *t = NULL; - int encoded = 0; - encstr = xml_attribute( logpart, "encoded" ); - encoded = (encstr[0] != 'F'); - - if ( html_encrypt && encoded ) { - s = rot13( logpart->cdata ); - } - else { - s = xstrdup( logpart->cdata ); - } - - t = html_entitize( s ); - gbfprintf( file_out, "%s", t ); - xfree( t ); - xfree( s ); - } - - gbfprintf( file_out, "

\n" ); - curlog = xml_findnext( root, curlog, "groundspeak:log" ); - } - } - gbfprintf(file_out, "
\n"); + char tbuf[1024]; + char *cout; + time_t tm = wpt->creation_time; + gbint32 utmz; + double utme, utmn; + char utmzc; + fs_xml *fs_gpx = NULL; + + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) { + tm = time(NULL); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + + gbfprintf(file_out, "\n
\n", wpt->shortname); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf(file_out, "\n"); + + + gbfprintf(file_out, "

%s - ",(global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname); + cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1); + gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn); + xfree(cout); + if (wpt->altitude != unknown_alt) { + gbfprintf(file_out, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude)); + } + gbfprintf(file_out, "
\n"); + if (strcmp(wpt->description, wpt->shortname)) { + if (wpt->url) { + char *d = html_entitize(wpt->description); + gbfprintf(file_out, "%s", wpt->url, d); + xfree(d); + } else { + gbfprintf(file_out, "%s", wpt->description); + } + if (wpt->gc_data->placer) { + gbfprintf(file_out, " by %s", wpt->gc_data->placer); + } + } + gbfprintf(file_out, "

"); + if (wpt->gc_data->terr) { + gbfprintf(file_out, "

%d%s / %d%s
\n", + (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?"½":"", + (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?"½":""); + gbfprintf(file_out, "%s / %s

", + gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container)); + } + gbfprintf(file_out, "
"); + if (wpt->gc_data->desc_short.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_short.utfstring); + gbfprintf(file_out, "

%s

\n", tmpstr); + xfree(tmpstr); + } + if (wpt->gc_data->desc_long.utfstring) { + char *tmpstr = strip_nastyhtml(wpt->gc_data->desc_long.utfstring); + gbfprintf(file_out, "

%s

\n", tmpstr); + xfree(tmpstr); + } + if (wpt->gc_data->hint) { + char *hint = NULL; + if (html_encrypt) { + hint = rot13(wpt->gc_data->hint); + } else { + hint = xstrdup(wpt->gc_data->hint); + } + gbfprintf(file_out, "

Hint: %s

\n", hint); + xfree(hint); + } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + gbfprintf(file_out, "

%s

\n", wpt->notes); + } + + fs_gpx = NULL; + if (includelogs) { + fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX); + } + + if (fs_gpx && fs_gpx->tag) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm *logtm = NULL; + gbfprintf(file_out, "

\n"); + + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + gbfprintf(file_out, "%s by ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + char *f = html_entitize(logpart->cdata); + gbfprintf(file_out, "%s on ", f); + xfree(f); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + gbfprintf(file_out, + "%04d-%02d-%02d
\n", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + if (logpart) { + char *coordstr = NULL; + float lat = 0; + float lon = 0; + coordstr = xml_attribute(logpart, "lat"); + if (coordstr) { + lat = atof(coordstr); + } + coordstr = xml_attribute(logpart, "lon"); + if (coordstr) { + lon = atof(coordstr); + } + coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1); + gbfprintf(file_out, + "%s
\n", + coordstr); + xfree(coordstr); + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char *encstr = NULL; + char *s = NULL; + char *t = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (encstr[0] != 'F'); + + if (html_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + t = html_entitize(s); + gbfprintf(file_out, "%s", t); + xfree(t); + xfree(s); + } + + gbfprintf(file_out, "

\n"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + } + gbfprintf(file_out, "
\n"); } static void html_index(const waypoint *wpt) { - char *sn = html_entitize(wpt->shortname); - char *d = html_entitize(wpt->description); + char *sn = html_entitize(wpt->shortname); + char *d = html_entitize(wpt->description); - gbfprintf(file_out, "%s - %s
\n", sn, sn, d); + gbfprintf(file_out, "%s - %s
\n", sn, sn, d); - xfree(sn); - xfree(d); + xfree(sn); + xfree(d); } static void data_write(void) { - setshort_length(mkshort_handle, 6); - - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - gbfprintf(file_out, " \n"); - gbfprintf(file_out, " \n", gpsbabel_version); - gbfprintf(file_out, " GPSBabel HTML Output\n"); - if (stylesheet) - gbfprintf(file_out, " \n", stylesheet); - else { - gbfprintf(file_out, " \n"); - } - gbfprintf(file_out, "\n"); - gbfprintf(file_out, "\n"); - - gbfprintf(file_out, "

\n"); - waypt_disp_all(html_index); - gbfprintf(file_out, "

\n"); - - waypt_disp_all(html_disp); - - gbfprintf(file_out, ""); - gbfprintf(file_out, ""); + setshort_length(mkshort_handle, 6); + + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + gbfprintf(file_out, " \n"); + gbfprintf(file_out, " \n", gpsbabel_version); + gbfprintf(file_out, " GPSBabel HTML Output\n"); + if (stylesheet) { + gbfprintf(file_out, " \n", stylesheet); + } else { + gbfprintf(file_out, " \n"); + } + gbfprintf(file_out, "\n"); + gbfprintf(file_out, "\n"); + + gbfprintf(file_out, "

\n"); + waypt_disp_all(html_index); + gbfprintf(file_out, "

\n"); + + waypt_disp_all(html_disp); + + gbfprintf(file_out, ""); + gbfprintf(file_out, ""); } ff_vecs_t html_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none }, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - html_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none }, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + html_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/humminbird.c b/gpsbabel/humminbird.c index 90ec0071e..a44e127f4 100644 --- a/gpsbabel/humminbird.c +++ b/gpsbabel/humminbird.c @@ -59,113 +59,113 @@ Still, they're usful in the code as a plain signature. /* The hwr data format is records-based, and the records are 36 bytes long. */ typedef struct humminbird_waypt_s { - /* O.K.: the file can also contain routes with a different magic. */ - /* gbuint32 signature; */ /* Just for error checking(?) */ - gbuint16 num; /* Always ascending in the file. */ - gbuint16 zero; /* Always seems to be zero. */ - gbuint8 status; /* Always seems to be 1. Ends up as + /* O.K.: the file can also contain routes with a different magic. */ + /* gbuint32 signature; */ /* Just for error checking(?) */ + gbuint16 num; /* Always ascending in the file. */ + gbuint16 zero; /* Always seems to be zero. */ + gbuint8 status; /* Always seems to be 1. Ends up as in gpx files exported by HumminbirdPC. */ - gbuint8 icon; /* See below */ - gbuint16 depth; /* Water depth. These are fishfinders. In centimeters */ - gbuint32 time; /* This is a time_t. In UTC */ - gbint32 east; - gbint32 north; - char name[WPT_NAME_LEN]; + gbuint8 icon; /* See below */ + gbuint16 depth; /* Water depth. These are fishfinders. In centimeters */ + gbuint32 time; /* This is a time_t. In UTC */ + gbint32 east; + gbint32 north; + char name[WPT_NAME_LEN]; } humminbird_waypt_t; typedef struct humminbird_rte_s { - /* O.K.: the file can contain also routes with a different magic. */ - /* gbuint32 signature; */ /* Just for error checking(?) */ - gbuint16 num; - gbuint16 zero; - gbuint8 status; - gbuint8 U0; - gbuint8 U1; - gbint8 count; - gbuint32 time; - char name[RTE_NAME_LEN]; - gbuint16 points[MAX_RTE_POINTS]; + /* O.K.: the file can contain also routes with a different magic. */ + /* gbuint32 signature; */ /* Just for error checking(?) */ + gbuint16 num; + gbuint16 zero; + gbuint8 status; + gbuint8 U0; + gbuint8 U1; + gbint8 count; + gbuint32 time; + char name[RTE_NAME_LEN]; + gbuint16 points[MAX_RTE_POINTS]; } humminbird_rte_t; typedef struct humminbird_trk_header_s { /* 68 bytes, incl signature */ - /* gbuint32 signature; */ - gbuint16 trk_num; - gbuint16 zero; - gbuint16 num_points; - gbuint16 unknown; /* Always zero so far. */ - gbuint32 time; /* a time_t, in UTC */ - - gbint32 start_east; /* Start of track */ - gbint32 start_north; - gbint32 end_east; /* end of track */ - gbint32 end_north; - - gbint32 sw_east; /* Bounding box, enclosing the track */ - gbint32 sw_north; /* sw is the south-west point */ - gbint32 ne_east; /* ne is the north-east point */ - gbint32 ne_north; - - char name[20]; + /* gbuint32 signature; */ + gbuint16 trk_num; + gbuint16 zero; + gbuint16 num_points; + gbuint16 unknown; /* Always zero so far. */ + gbuint32 time; /* a time_t, in UTC */ + + gbint32 start_east; /* Start of track */ + gbint32 start_north; + gbint32 end_east; /* end of track */ + gbint32 end_north; + + gbint32 sw_east; /* Bounding box, enclosing the track */ + gbint32 sw_north; /* sw is the south-west point */ + gbint32 ne_east; /* ne is the north-east point */ + gbint32 ne_north; + + char name[20]; } humminbird_trk_header_t; typedef struct humminbird_trk_point_s { - gbint16 deltaeast; - gbint16 deltanorth; - gbuint16 depth; /* in centimeters */ + gbint16 deltaeast; + gbint16 deltanorth; + gbuint16 depth; /* in centimeters */ } humminbird_trk_point_t; typedef struct humminbird_trk_header_old_s { /* 16 bytes, incl signature */ - /* gbuint32 signature; */ - gbuint16 trk_num; - gbuint16 zero; - gbuint16 num_points; - gbuint16 unknown; /* Always zero so far. */ - gbuint32 time; /* a time_t, in UTC */ - - gbint32 start_east; /* Start of track */ - gbint32 start_north; - gbint32 end_east; /* end of track */ - gbint32 end_north; + /* gbuint32 signature; */ + gbuint16 trk_num; + gbuint16 zero; + gbuint16 num_points; + gbuint16 unknown; /* Always zero so far. */ + gbuint32 time; /* a time_t, in UTC */ + + gbint32 start_east; /* Start of track */ + gbint32 start_north; + gbint32 end_east; /* end of track */ + gbint32 end_north; } humminbird_trk_header_old_t; typedef struct humminbird_trk_point_old_s { - gbint16 deltaeast; - gbint16 deltanorth; + gbint16 deltaeast; + gbint16 deltanorth; } humminbird_trk_point_old_t; static const char* humminbird_icons[] = { - "Normal", /* 0 */ - "House", /* 1 */ - "Red cross", /* 2 */ - "Fish", /* 3 */ - "Duck", /* 4 */ - "Anchor", /* 5 */ - "Buoy", /* 6 */ - "Airport", /* 7 */ - "Camping", /* 8 */ - "Danger", /* 9 */ - "Fuel", /* 10 */ - "Rock", /* 11 */ - "Weed", /* 12 */ - "Wreck", /* 13 */ - "Phone", /* 14 */ - "Coffee", /* 15 */ - "Beer", /* 16 */ - "Mooring", /* 17 */ - "Pier", /* 18 */ - "Slip", /* 19 */ - "Ramp", /* 20 */ - "Circle", /* 21 */ - "Diamond", /* 22 */ - "Flag", /* 23 */ - "Pattern", /* 24 */ - "Shower", /* 25 */ - "Water tap", /* 26 */ - "Tree", /* 27 */ - "Recording", /* 28 */ - "Snapshot" /* 29 */ + "Normal", /* 0 */ + "House", /* 1 */ + "Red cross", /* 2 */ + "Fish", /* 3 */ + "Duck", /* 4 */ + "Anchor", /* 5 */ + "Buoy", /* 6 */ + "Airport", /* 7 */ + "Camping", /* 8 */ + "Danger", /* 9 */ + "Fuel", /* 10 */ + "Rock", /* 11 */ + "Weed", /* 12 */ + "Wreck", /* 13 */ + "Phone", /* 14 */ + "Coffee", /* 15 */ + "Beer", /* 16 */ + "Mooring", /* 17 */ + "Pier", /* 18 */ + "Slip", /* 19 */ + "Ramp", /* 20 */ + "Circle", /* 21 */ + "Diamond", /* 22 */ + "Flag", /* 23 */ + "Pattern", /* 24 */ + "Shower", /* 25 */ + "Water tap", /* 26 */ + "Tree", /* 27 */ + "Recording", /* 28 */ + "Snapshot" /* 29 */ }; static gbfile* fin; @@ -178,46 +178,50 @@ static int rte_num; static arglist_t humminbird_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /* Takes a latitude in degrees, * returns a latitude in degrees. */ static double -geodetic_to_geocentric_hwr(const double gd_lat) { - const double cos_ae = 0.9966349016452; - const double cos2_ae = cos_ae * cos_ae; - const double gdr = gd_lat *M_PI / 180.0; +geodetic_to_geocentric_hwr(const double gd_lat) +{ + const double cos_ae = 0.9966349016452; + const double cos2_ae = cos_ae * cos_ae; + const double gdr = gd_lat *M_PI / 180.0; - return atan(cos2_ae * tan(gdr)) * 180.0/M_PI; + return atan(cos2_ae * tan(gdr)) * 180.0/M_PI; } /* Takes a latitude in degrees, * returns a latitude in degrees. */ static double -geocentric_to_geodetic_hwr(const double gc_lat) { - const double cos_ae = 0.9966349016452; - const double cos2_ae = cos_ae * cos_ae; - const double gcr = gc_lat *M_PI / 180.0; +geocentric_to_geodetic_hwr(const double gc_lat) +{ + const double cos_ae = 0.9966349016452; + const double cos2_ae = cos_ae * cos_ae; + const double gcr = gc_lat *M_PI / 180.0; - return atan( tan(gcr)/cos2_ae ) * 180.0/M_PI; + return atan(tan(gcr)/cos2_ae) * 180.0/M_PI; } /* Takes a projected "north" value, returns latitude in degrees. */ static double -gudermannian_i1924(const double x) { - const double norm_x = x/i1924_equ_axis; +gudermannian_i1924(const double x) +{ + const double norm_x = x/i1924_equ_axis; - return atan(sinh(norm_x)) * 180.0/M_PI; + return atan(sinh(norm_x)) * 180.0/M_PI; } /* Takes latitude in degrees, returns projected "north" value. */ static double -inverse_gudermannian_i1924(const double x) { - const double x_r = x/180.0 * M_PI; - const double guder = log(tan(M_PI/4.0 + x_r/2.0)); +inverse_gudermannian_i1924(const double x) +{ + const double x_r = x/180.0 * M_PI; + const double guder = log(tan(M_PI/4.0 + x_r/2.0)); - return guder * i1924_equ_axis; + return guder * i1924_equ_axis; } /******************************************************************************* @@ -227,286 +231,301 @@ inverse_gudermannian_i1924(const double x) { static void humminbird_rd_init(const char *fname) { - fin = gbfopen_be(fname, "rb", MYNAME); - waypoints = avltree_init(0, MYNAME); + fin = gbfopen_be(fname, "rb", MYNAME); + waypoints = avltree_init(0, MYNAME); } -static void +static void humminbird_rd_deinit(void) { - avltree_done(waypoints); - gbfclose(fin); + avltree_done(waypoints); + gbfclose(fin); } static void -humminbird_read_wpt(gbfile* fin) { +humminbird_read_wpt(gbfile* fin) +{ + + humminbird_waypt_t w; + double guder; + int num_icons; + waypoint *wpt; + char buff[10]; - humminbird_waypt_t w; - double guder; - int num_icons; - waypoint *wpt; - char buff[10]; + if (! gbfread(&w, 1, sizeof(w), fin)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } - if (! gbfread(&w, 1, sizeof(w), fin)) - fatal(MYNAME ": Unexpected end of file!\n"); + /* Fix endianness - these are now BE */ + w.num = be_read16(&w.num); + w.zero = be_read16(&w.zero); + w.depth = be_read16(&w.depth); + w.time = be_read32(&w.time); + w.north = be_read32(&w.north); + w.east = be_read32(&w.east); - /* Fix endianness - these are now BE */ - w.num = be_read16(&w.num); - w.zero = be_read16(&w.zero); - w.depth = be_read16(&w.depth); - w.time = be_read32(&w.time); - w.north = be_read32(&w.north); - w.east = be_read32(&w.east); + /* All right! Copy the data to the gpsbabel struct... */ - /* All right! Copy the data to the gpsbabel struct... */ + wpt = waypt_new(); - wpt = waypt_new(); + wpt->shortname = xstrndup(w.name, sizeof(w.name)); + wpt->creation_time = w.time; - wpt->shortname = xstrndup(w.name, sizeof(w.name)); - wpt->creation_time = w.time; + guder = gudermannian_i1924(w.north); + wpt->latitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = (double)w.east / EAST_SCALE * 180.0; - guder = gudermannian_i1924(w.north); - wpt->latitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = (double)w.east / EAST_SCALE * 180.0; + wpt->altitude = 0.0; /* It's from a fishfinder... */ - wpt->altitude = 0.0; /* It's from a fishfinder... */ + if (w.depth != 0) { + WAYPT_SET(wpt,depth,(double)w.depth / 100.0); + } - if (w.depth != 0) - WAYPT_SET(wpt,depth,(double)w.depth / 100.0); + num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); + if (w.icon < num_icons) { + wpt->icon_descr = humminbird_icons[w.icon]; + } - num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); - if (w.icon < num_icons) - wpt->icon_descr = humminbird_icons[w.icon]; + waypt_add(wpt); - waypt_add(wpt); - - /* register the point over his internal Humminbird "Number" */ - snprintf(buff, sizeof(buff), "%d", w.num); - avltree_insert(waypoints, buff, wpt); + /* register the point over his internal Humminbird "Number" */ + snprintf(buff, sizeof(buff), "%d", w.num); + avltree_insert(waypoints, buff, wpt); } static void -humminbird_read_route(gbfile* fin) { - - humminbird_rte_t hrte; - - if (! gbfread(&hrte, 1, sizeof(hrte), fin)) - fatal(MYNAME ": Unexpected end of file!\n"); - - hrte.time = be_read32(&hrte.time); - hrte.num = be_read16(&hrte.num); - - if (hrte.count > 0) { - int i; - route_head *rte = NULL; - - for (i = 0; i < hrte.count; i++) { - waypoint *wpt; - char buff[10]; - hrte.points[i] = be_read16(&hrte.points[i]); - - /* locate the point over his internal Humminbird "Number" */ - snprintf(buff, sizeof(buff), "%d", hrte.points[i]); - if (avltree_find(waypoints, buff, (void *) &wpt)) { - if (rte == NULL) { - rte = route_head_alloc(); - route_add_head(rte); - rte->rte_name = xstrndup(hrte.name, sizeof(hrte.name)); - /* rte->rte_num = hrte.num + 1; only internal number */ - } - route_add_wpt(rte, waypt_dupe(wpt)); - } - } - } +humminbird_read_route(gbfile* fin) +{ + + humminbird_rte_t hrte; + + if (! gbfread(&hrte, 1, sizeof(hrte), fin)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + + hrte.time = be_read32(&hrte.time); + hrte.num = be_read16(&hrte.num); + + if (hrte.count > 0) { + int i; + route_head *rte = NULL; + + for (i = 0; i < hrte.count; i++) { + waypoint *wpt; + char buff[10]; + hrte.points[i] = be_read16(&hrte.points[i]); + + /* locate the point over his internal Humminbird "Number" */ + snprintf(buff, sizeof(buff), "%d", hrte.points[i]); + if (avltree_find(waypoints, buff, (void *) &wpt)) { + if (rte == NULL) { + rte = route_head_alloc(); + route_add_head(rte); + rte->rte_name = xstrndup(hrte.name, sizeof(hrte.name)); + /* rte->rte_num = hrte.num + 1; only internal number */ + } + route_add_wpt(rte, waypt_dupe(wpt)); + } + } + } } static void -humminbird_read_track(gbfile* fin) { - - humminbird_trk_header_t th; - humminbird_trk_point_t* points; - route_head* trk; - waypoint* first_wpt; - int i; - int max_points = 0; - gbint32 accum_east; - gbint32 accum_north; - double g_lat; - - if (! gbfread(&th, 1, sizeof(th), fin)) - fatal(MYNAME ": Unexpected end of file reading header!\n"); - - th.trk_num = be_read16(&th.trk_num); - th.num_points = be_read16(&th.num_points); - th.time = be_read32(&th.time); - - th.start_east = be_read32(&th.start_east); - th.start_north = be_read32(&th.start_north); - th.end_east = be_read32(&th.end_east); - th.end_north = be_read32(&th.end_north); - - th.sw_east = be_read32(&th.sw_east); - th.sw_north = be_read32(&th.sw_north); - th.ne_east = be_read32(&th.ne_east); - th.ne_north = be_read32(&th.ne_north); - - max_points = (131080 - sizeof(gbuint32) - sizeof(th)) / sizeof(humminbird_trk_point_t); - - if (th.num_points > max_points) - fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); - - /* num_points is actually one too big, because it includes the value in - the header. But we want the extra point at the end because the - freak-value filter below looks at points[i+1] */ - points = xcalloc(th.num_points, sizeof(humminbird_trk_point_t)); - if (! gbfread(points, sizeof(humminbird_trk_point_t), th.num_points-1, fin)) - fatal(MYNAME ": Unexpected end of file reading points!\n"); - - accum_east = th.start_east; - accum_north = th.start_north; - - trk = route_head_alloc(); - track_add_head(trk); - - trk->rte_name = xstrndup(th.name, sizeof(th.name)); - trk->rte_num = th.trk_num; - - /* We create one wpt for the info in the header */ - - first_wpt = waypt_new(); - g_lat = gudermannian_i1924(accum_north); - first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); - first_wpt->longitude = accum_east/EAST_SCALE * 180.0; - first_wpt->altitude = 0.0; - /* No depth info in the header. */ - track_add_wpt(trk, first_wpt); - - for(i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = accum_east/EAST_SCALE * 180.0; - wpt->altitude = 0.0; - - if (points[i].depth != 0) - WAYPT_SET(wpt,depth,(double)points[i].depth / 100.0); - - if (i == th.num_points-2 && th.time != 0) { - /* Last point. Add the date from the header. */ - /* Unless it's zero. Sometimes happens, possibly if - the gps didn't have a lock when the track was - saved. */ - wpt->creation_time = th.time; - } - track_add_wpt(trk, wpt); - } - xfree(points); +humminbird_read_track(gbfile* fin) +{ + + humminbird_trk_header_t th; + humminbird_trk_point_t* points; + route_head* trk; + waypoint* first_wpt; + int i; + int max_points = 0; + gbint32 accum_east; + gbint32 accum_north; + double g_lat; + + if (! gbfread(&th, 1, sizeof(th), fin)) { + fatal(MYNAME ": Unexpected end of file reading header!\n"); + } + + th.trk_num = be_read16(&th.trk_num); + th.num_points = be_read16(&th.num_points); + th.time = be_read32(&th.time); + + th.start_east = be_read32(&th.start_east); + th.start_north = be_read32(&th.start_north); + th.end_east = be_read32(&th.end_east); + th.end_north = be_read32(&th.end_north); + + th.sw_east = be_read32(&th.sw_east); + th.sw_north = be_read32(&th.sw_north); + th.ne_east = be_read32(&th.ne_east); + th.ne_north = be_read32(&th.ne_north); + + max_points = (131080 - sizeof(gbuint32) - sizeof(th)) / sizeof(humminbird_trk_point_t); + + if (th.num_points > max_points) { + fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); + } + + /* num_points is actually one too big, because it includes the value in + the header. But we want the extra point at the end because the + freak-value filter below looks at points[i+1] */ + points = xcalloc(th.num_points, sizeof(humminbird_trk_point_t)); + if (! gbfread(points, sizeof(humminbird_trk_point_t), th.num_points-1, fin)) { + fatal(MYNAME ": Unexpected end of file reading points!\n"); + } + + accum_east = th.start_east; + accum_north = th.start_north; + + trk = route_head_alloc(); + track_add_head(trk); + + trk->rte_name = xstrndup(th.name, sizeof(th.name)); + trk->rte_num = th.trk_num; + + /* We create one wpt for the info in the header */ + + first_wpt = waypt_new(); + g_lat = gudermannian_i1924(accum_north); + first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); + first_wpt->longitude = accum_east/EAST_SCALE * 180.0; + first_wpt->altitude = 0.0; + /* No depth info in the header. */ + track_add_wpt(trk, first_wpt); + + for (i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = accum_east/EAST_SCALE * 180.0; + wpt->altitude = 0.0; + + if (points[i].depth != 0) { + WAYPT_SET(wpt,depth,(double)points[i].depth / 100.0); + } + + if (i == th.num_points-2 && th.time != 0) { + /* Last point. Add the date from the header. */ + /* Unless it's zero. Sometimes happens, possibly if + the gps didn't have a lock when the track was + saved. */ + wpt->creation_time = th.time; + } + track_add_wpt(trk, wpt); + } + xfree(points); } static void -humminbird_read_track_old(gbfile* fin) { - - humminbird_trk_header_old_t th; - humminbird_trk_point_old_t* points; - route_head* trk; - waypoint* first_wpt; - int i; - int max_points = 0; - gbint32 accum_east; - gbint32 accum_north; - double g_lat; - const int file_len = 8048; - char namebuf[TRK_NAME_LEN]; - - - if (! gbfread(&th, 1, sizeof(th), fin)) - fatal(MYNAME ": Unexpected end of file reading header!\n"); - - th.trk_num = be_read16(&th.trk_num); - th.num_points = be_read16(&th.num_points); - th.time = be_read32(&th.time); - - th.start_east = be_read32(&th.start_east); - th.start_north = be_read32(&th.start_north); - th.end_east = be_read32(&th.end_east); - th.end_north = be_read32(&th.end_north); - - // These files are always 8048 bytes long. Note that that's the value - // of the second 16-bit word in the signature. - max_points = (file_len - (sizeof(th) + sizeof (gbuint32) + TRK_NAME_LEN)) / sizeof(humminbird_trk_point_old_t); - - if (th.num_points > max_points) - fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); - - /* num_points is actually one too big, because it includes the value in - the header. But we want the extra point at the end because the - freak-value filter below looks at points[i+1] */ - points = xcalloc(th.num_points, sizeof(humminbird_trk_point_old_t)); - if (! gbfread(points, sizeof(humminbird_trk_point_old_t), th.num_points-1, fin)) - fatal(MYNAME ": Unexpected end of file reading points!\n"); - - accum_east = th.start_east; - accum_north = th.start_north; - - trk = route_head_alloc(); - track_add_head(trk); - - /* The name is not in the header, but at the end of the file. - (The last 20 bytes.) */ - - gbfseek(fin, file_len-TRK_NAME_LEN, SEEK_SET); - gbfread(&namebuf, 1, TRK_NAME_LEN, fin); - trk->rte_name = xstrndup(namebuf, sizeof(namebuf)); - - trk->rte_num = th.trk_num; - - /* We create one wpt for the info in the header */ - - first_wpt = waypt_new(); - g_lat = gudermannian_i1924(accum_north); - first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); - first_wpt->longitude = accum_east/EAST_SCALE * 180.0; - first_wpt->altitude = 0.0; - track_add_wpt(trk, first_wpt); - - for(i=0 ; i max_points) { + fatal(MYNAME ": Too many track points! (%d)\n", th.num_points); + } + + /* num_points is actually one too big, because it includes the value in + the header. But we want the extra point at the end because the + freak-value filter below looks at points[i+1] */ + points = xcalloc(th.num_points, sizeof(humminbird_trk_point_old_t)); + if (! gbfread(points, sizeof(humminbird_trk_point_old_t), th.num_points-1, fin)) { + fatal(MYNAME ": Unexpected end of file reading points!\n"); + } + + accum_east = th.start_east; + accum_north = th.start_north; + + trk = route_head_alloc(); + track_add_head(trk); + + /* The name is not in the header, but at the end of the file. + (The last 20 bytes.) */ + + gbfseek(fin, file_len-TRK_NAME_LEN, SEEK_SET); + gbfread(&namebuf, 1, TRK_NAME_LEN, fin); + trk->rte_name = xstrndup(namebuf, sizeof(namebuf)); + + trk->rte_num = th.trk_num; + + /* We create one wpt for the info in the header */ + + first_wpt = waypt_new(); + g_lat = gudermannian_i1924(accum_north); + first_wpt->latitude = geocentric_to_geodetic_hwr(g_lat); + first_wpt->longitude = accum_east/EAST_SCALE * 180.0; + first_wpt->altitude = 0.0; + track_add_wpt(trk, first_wpt); + + for (i=0 ; ilatitude = geocentric_to_geodetic_hwr(guder); - wpt->longitude = accum_east/EAST_SCALE * 180.0; - wpt->altitude = 0.0; - - if (i == th.num_points-2 && th.time != 0) { - /* Last point. Add the date from the header. */ - /* Unless it's zero. Sometimes happens, possibly if - the gps didn't have a lock when the track was - saved. */ - wpt->creation_time = th.time; - } - track_add_wpt(trk, wpt); - } - xfree(points); + accum_east += points[i].deltaeast; + accum_north += points[i].deltanorth; + + guder = gudermannian_i1924(accum_north); + wpt->latitude = geocentric_to_geodetic_hwr(guder); + wpt->longitude = accum_east/EAST_SCALE * 180.0; + wpt->altitude = 0.0; + + if (i == th.num_points-2 && th.time != 0) { + /* Last point. Add the date from the header. */ + /* Unless it's zero. Sometimes happens, possibly if + the gps didn't have a lock when the track was + saved. */ + wpt->creation_time = th.time; + } + track_add_wpt(trk, wpt); + } + xfree(points); } static void humminbird_read(void) { - while(! gbfeof(fin)) { - gbuint32 signature; - - signature = gbfgetuint32(fin); - - switch(signature) { - case WPT_MAGIC: - humminbird_read_wpt(fin); - break; - case RTE_MAGIC: - humminbird_read_route(fin); - break; - case TRK_MAGIC: - humminbird_read_track(fin); - return; /* Don't continue. The rest of the file is all zeores */ - case TRK_MAGIC2: - humminbird_read_track_old(fin); - return; /* Don't continue. The rest of the file is all zeores */ - default: - fatal(MYNAME ": Invalid record header \"0x%08X\" (no or unknown humminbird file)!\n", signature); - } - } + while (! gbfeof(fin)) { + gbuint32 signature; + + signature = gbfgetuint32(fin); + + switch (signature) { + case WPT_MAGIC: + humminbird_read_wpt(fin); + break; + case RTE_MAGIC: + humminbird_read_route(fin); + break; + case TRK_MAGIC: + humminbird_read_track(fin); + return; /* Don't continue. The rest of the file is all zeores */ + case TRK_MAGIC2: + humminbird_read_track_old(fin); + return; /* Don't continue. The rest of the file is all zeores */ + default: + fatal(MYNAME ": Invalid record header \"0x%08X\" (no or unknown humminbird file)!\n", signature); + } + } } @@ -575,110 +594,111 @@ humminbird_read(void) static void humminbird_wr_init(const char *fname) { - fout = gbfopen_be(fname, "wb", MYNAME); - - wptname_sh = mkshort_new_handle(); - - setshort_length(wptname_sh, WPT_NAME_LEN - 1); - setshort_badchars(wptname_sh, BAD_CHARS); - setshort_mustupper(wptname_sh, 0); - setshort_mustuniq(wptname_sh, 0); - setshort_whitespace_ok(wptname_sh, 1); - setshort_repeating_whitespace_ok(wptname_sh, 1); - setshort_defname(wptname_sh, "WPT"); - - rtename_sh = mkshort_new_handle(); - setshort_length(rtename_sh, RTE_NAME_LEN - 1); - setshort_badchars(rtename_sh, BAD_CHARS); - setshort_mustupper(rtename_sh, 0); - setshort_mustuniq(rtename_sh, 0); - setshort_whitespace_ok(rtename_sh, 1); - setshort_repeating_whitespace_ok(rtename_sh, 1); - setshort_defname(rtename_sh, "Route"); - - trkname_sh = mkshort_new_handle(); - setshort_length(trkname_sh, RTE_NAME_LEN - 1); - setshort_badchars(trkname_sh, BAD_CHARS); - setshort_mustupper(trkname_sh, 0); - setshort_mustuniq(trkname_sh, 0); - setshort_whitespace_ok(trkname_sh, 1); - setshort_repeating_whitespace_ok(trkname_sh, 1); - setshort_defname(trkname_sh, "Track"); - - waypoints = avltree_init(0, MYNAME); - - waypoint_num = 0; - rte_num = 0; + fout = gbfopen_be(fname, "wb", MYNAME); + + wptname_sh = mkshort_new_handle(); + + setshort_length(wptname_sh, WPT_NAME_LEN - 1); + setshort_badchars(wptname_sh, BAD_CHARS); + setshort_mustupper(wptname_sh, 0); + setshort_mustuniq(wptname_sh, 0); + setshort_whitespace_ok(wptname_sh, 1); + setshort_repeating_whitespace_ok(wptname_sh, 1); + setshort_defname(wptname_sh, "WPT"); + + rtename_sh = mkshort_new_handle(); + setshort_length(rtename_sh, RTE_NAME_LEN - 1); + setshort_badchars(rtename_sh, BAD_CHARS); + setshort_mustupper(rtename_sh, 0); + setshort_mustuniq(rtename_sh, 0); + setshort_whitespace_ok(rtename_sh, 1); + setshort_repeating_whitespace_ok(rtename_sh, 1); + setshort_defname(rtename_sh, "Route"); + + trkname_sh = mkshort_new_handle(); + setshort_length(trkname_sh, RTE_NAME_LEN - 1); + setshort_badchars(trkname_sh, BAD_CHARS); + setshort_mustupper(trkname_sh, 0); + setshort_mustuniq(trkname_sh, 0); + setshort_whitespace_ok(trkname_sh, 1); + setshort_repeating_whitespace_ok(trkname_sh, 1); + setshort_defname(trkname_sh, "Track"); + + waypoints = avltree_init(0, MYNAME); + + waypoint_num = 0; + rte_num = 0; } static void humminbird_wr_deinit(void) { - avltree_done(waypoints); - mkshort_del_handle(&wptname_sh); - mkshort_del_handle(&rtename_sh); - mkshort_del_handle(&trkname_sh); - gbfclose(fout); + avltree_done(waypoints); + mkshort_del_handle(&wptname_sh); + mkshort_del_handle(&rtename_sh); + mkshort_del_handle(&trkname_sh); + gbfclose(fout); } static void -humminbird_write_waypoint(const waypoint *wpt) { - humminbird_waypt_t hum; - double lat, north, east; - int i; - int num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); - char *name; - - be_write16(&hum.num, waypoint_num++); - hum.zero = 0; - hum.status = 1; - hum.icon = 255; - - // Icon.... - if (wpt->icon_descr) { - for (i = 0; i < num_icons; i++) { - if (!case_ignore_strcmp(wpt->icon_descr, humminbird_icons[i])) { - hum.icon = i; - break; - } - } - if (hum.icon == 255) { /* no success, no try to find the item in a more comlex name */ - hum.icon = 0; /* i.e. "Diamond" as part of "Diamond, Green" or "Green Diamond" */ - for (i = 0; i < num_icons; i++) { - char *match; - int j; - xasprintf(&match, "*%s*", humminbird_icons[i]); - j = case_ignore_str_match(wpt->icon_descr, match); - xfree(match); - if (j != 0) { - hum.icon = i; - break; - } - } - } - } - - hum.depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); - be_write16(&hum.depth, hum.depth); - - be_write32(&hum.time, wpt->creation_time); - - east = wpt->longitude / 180.0 * EAST_SCALE; - be_write32(&hum.east, si_round((east))); - - lat = geodetic_to_geocentric_hwr(wpt->latitude); - north = inverse_gudermannian_i1924(lat); - be_write32(&hum.north, si_round(north)); - - name = (global_opts.synthesize_shortnames) - ? mkshort_from_wpt(wptname_sh, wpt) - : mkshort(wptname_sh, wpt->shortname); - memset(&hum.name, 0, sizeof(hum.name)); - memcpy(&hum.name, name, strlen(name)); - xfree(name); - - gbfputuint32(WPT_MAGIC, fout); - gbfwrite(&hum, sizeof(hum), 1, fout); +humminbird_write_waypoint(const waypoint *wpt) +{ + humminbird_waypt_t hum; + double lat, north, east; + int i; + int num_icons = sizeof(humminbird_icons) / sizeof(humminbird_icons[0]); + char *name; + + be_write16(&hum.num, waypoint_num++); + hum.zero = 0; + hum.status = 1; + hum.icon = 255; + + // Icon.... + if (wpt->icon_descr) { + for (i = 0; i < num_icons; i++) { + if (!case_ignore_strcmp(wpt->icon_descr, humminbird_icons[i])) { + hum.icon = i; + break; + } + } + if (hum.icon == 255) { /* no success, no try to find the item in a more comlex name */ + hum.icon = 0; /* i.e. "Diamond" as part of "Diamond, Green" or "Green Diamond" */ + for (i = 0; i < num_icons; i++) { + char *match; + int j; + xasprintf(&match, "*%s*", humminbird_icons[i]); + j = case_ignore_str_match(wpt->icon_descr, match); + xfree(match); + if (j != 0) { + hum.icon = i; + break; + } + } + } + } + + hum.depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); + be_write16(&hum.depth, hum.depth); + + be_write32(&hum.time, wpt->creation_time); + + east = wpt->longitude / 180.0 * EAST_SCALE; + be_write32(&hum.east, si_round((east))); + + lat = geodetic_to_geocentric_hwr(wpt->latitude); + north = inverse_gudermannian_i1924(lat); + be_write32(&hum.north, si_round(north)); + + name = (global_opts.synthesize_shortnames) + ? mkshort_from_wpt(wptname_sh, wpt) + : mkshort(wptname_sh, wpt->shortname); + memset(&hum.name, 0, sizeof(hum.name)); + memcpy(&hum.name, name, strlen(name)); + xfree(name); + + gbfputuint32(WPT_MAGIC, fout); + gbfwrite(&hum, sizeof(hum), 1, fout); } static humminbird_trk_header_t* trk_head; @@ -689,230 +709,251 @@ static gbuint32 last_time; static void -humminbird_track_head(const route_head *trk) { - int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); - - trk_head = NULL; - last_time = 0; - if (trk->rte_waypt_ct > 0) { - char *name; - trk_head = xcalloc(1, sizeof(humminbird_trk_header_t)); - trk_points = xcalloc (max_points, sizeof(humminbird_trk_point_t)); - - name = mkshort(trkname_sh, trk->rte_name); - strncpy(trk_head->name, name, sizeof(trk_head->name)); - xfree(name); - be_write16(&trk_head->trk_num, trk->rte_num); - } +humminbird_track_head(const route_head *trk) +{ + int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); + + trk_head = NULL; + last_time = 0; + if (trk->rte_waypt_ct > 0) { + char *name; + trk_head = xcalloc(1, sizeof(humminbird_trk_header_t)); + trk_points = xcalloc(max_points, sizeof(humminbird_trk_point_t)); + + name = mkshort(trkname_sh, trk->rte_name); + strncpy(trk_head->name, name, sizeof(trk_head->name)); + xfree(name); + be_write16(&trk_head->trk_num, trk->rte_num); + } } static void -humminbird_track_tail(const route_head *rte) { - int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); +humminbird_track_tail(const route_head *rte) +{ + int max_points = (131080 - sizeof(gbuint32)- sizeof(humminbird_trk_header_t)) / sizeof(humminbird_trk_point_t); + + if (trk_head == NULL) { + return; + } - if (trk_head == NULL) - return; + be_write32(&trk_head->end_east, last_east); + be_write32(&trk_head->end_north, last_north); + be_write32(&trk_head->time, last_time); - be_write32(&trk_head->end_east, last_east); - be_write32(&trk_head->end_north, last_north); - be_write32(&trk_head->time, last_time); + /* Fix some endianness */ - /* Fix some endianness */ + be_write32(&trk_head->sw_east, trk_head->sw_east); + be_write32(&trk_head->ne_east, trk_head->ne_east); + be_write32(&trk_head->sw_north, trk_head->sw_north); + be_write32(&trk_head->ne_north, trk_head->ne_north); - be_write32(&trk_head->sw_east, trk_head->sw_east); - be_write32(&trk_head->ne_east, trk_head->ne_east); - be_write32(&trk_head->sw_north, trk_head->sw_north); - be_write32(&trk_head->ne_north, trk_head->ne_north); - - be_write16(&trk_head->num_points, trk_head->num_points); + be_write16(&trk_head->num_points, trk_head->num_points); - /* Actually write it out */ + /* Actually write it out */ - - gbfputuint32(TRK_MAGIC, fout); - gbfwrite(trk_head, 1, sizeof(humminbird_trk_header_t), fout); - gbfwrite(trk_points, max_points, sizeof(humminbird_trk_point_t), fout); - gbfputuint16(0, fout); /* Odd but true. The format doesn't fit an int nr of entries. */ - xfree(trk_head); - xfree(trk_points); + gbfputuint32(TRK_MAGIC, fout); + gbfwrite(trk_head, 1, sizeof(humminbird_trk_header_t), fout); + gbfwrite(trk_points, max_points, sizeof(humminbird_trk_point_t), fout); + gbfputuint16(0, fout); /* Odd but true. The format doesn't fit an int nr of entries. */ - trk_head = NULL; - trk_points = NULL; + xfree(trk_head); + xfree(trk_points); + + trk_head = NULL; + trk_points = NULL; } static void -humminbird_track_cb(const waypoint *wpt) { - gbint32 north, east; - double lat; - int i; - - if (trk_head == NULL) - return; - - i = trk_head->num_points; - - east = si_round(wpt->longitude / 180.0 * EAST_SCALE); - lat = geodetic_to_geocentric_hwr(wpt->latitude); - north = si_round(inverse_gudermannian_i1924(lat)); - - if (wpt->creation_time != 0) - last_time = wpt->creation_time; - - if (i == 0) { - /* It's the first point. That info goes in the header. */ - - be_write32(&trk_head->start_east, east); - be_write32(&trk_head->start_north, north); - - /* Bounding box. Easy for one point. */ - /* These are not BE yet, fixed in the end. */ - trk_head->sw_east = east; - trk_head->ne_east = east; - trk_head->sw_north = north; - trk_head->ne_north = north; - - /* No depth info in the header. */ - } else { - /* These points are 16-bit differential. */ - int j = i-1; - trk_points[j].deltaeast = east - last_east; - trk_points[j].deltanorth = north - last_north; - trk_points[j].depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); - - /* BE-ify */ - be_write16(&trk_points[j].deltaeast, trk_points[j].deltaeast); - be_write16(&trk_points[j].deltanorth, trk_points[j].deltanorth); - be_write16(&trk_points[j].depth, trk_points[j].depth); - - /* Update bounding box in header if neccessary */ - if (east > trk_head->ne_east) trk_head->ne_east = east; - if (east < trk_head->sw_east) trk_head->sw_east = east; - if (north > trk_head->ne_north) trk_head->ne_north = north; - if (north < trk_head->sw_north) trk_head->sw_north = north; - } - - last_east = east; - last_north = north; - - trk_head->num_points++; +humminbird_track_cb(const waypoint *wpt) +{ + gbint32 north, east; + double lat; + int i; + + if (trk_head == NULL) { + return; + } + + i = trk_head->num_points; + + east = si_round(wpt->longitude / 180.0 * EAST_SCALE); + lat = geodetic_to_geocentric_hwr(wpt->latitude); + north = si_round(inverse_gudermannian_i1924(lat)); + + if (wpt->creation_time != 0) { + last_time = wpt->creation_time; + } + + if (i == 0) { + /* It's the first point. That info goes in the header. */ + + be_write32(&trk_head->start_east, east); + be_write32(&trk_head->start_north, north); + + /* Bounding box. Easy for one point. */ + /* These are not BE yet, fixed in the end. */ + trk_head->sw_east = east; + trk_head->ne_east = east; + trk_head->sw_north = north; + trk_head->ne_north = north; + + /* No depth info in the header. */ + } else { + /* These points are 16-bit differential. */ + int j = i-1; + trk_points[j].deltaeast = east - last_east; + trk_points[j].deltanorth = north - last_north; + trk_points[j].depth = si_round(WAYPT_GET(wpt, depth, 0)*100.0); + + /* BE-ify */ + be_write16(&trk_points[j].deltaeast, trk_points[j].deltaeast); + be_write16(&trk_points[j].deltanorth, trk_points[j].deltanorth); + be_write16(&trk_points[j].depth, trk_points[j].depth); + + /* Update bounding box in header if neccessary */ + if (east > trk_head->ne_east) { + trk_head->ne_east = east; + } + if (east < trk_head->sw_east) { + trk_head->sw_east = east; + } + if (north > trk_head->ne_north) { + trk_head->ne_north = north; + } + if (north < trk_head->sw_north) { + trk_head->sw_north = north; + } + } + + last_east = east; + last_north = north; + + trk_head->num_points++; } static void -humminbird_track_write(void) { +humminbird_track_write(void) +{ - track_disp_all(humminbird_track_head, humminbird_track_tail, humminbird_track_cb); + track_disp_all(humminbird_track_head, humminbird_track_tail, humminbird_track_cb); } static void humminbird_rte_head(const route_head *rte) { - humrte = NULL; - if (rte->rte_waypt_ct > 0) - humrte = xcalloc(1, sizeof(*humrte)); + humrte = NULL; + if (rte->rte_waypt_ct > 0) { + humrte = xcalloc(1, sizeof(*humrte)); + } } static void humminbird_rte_tail(const route_head *rte) { - if (humrte == NULL) return; - - if (humrte->count > 0) { - int i; - char *name; - - humrte->num = rte_num++; - humrte->time = gpsbabel_time; - for (i = 0; i < humrte->count; i++) - be_write16(&humrte->points[i], humrte->points[i]); - - be_write16(&humrte->num, humrte->num); - be_write32(&humrte->time, humrte->time); - - name = mkshort(rtename_sh, rte->rte_name); - strncpy(humrte->name, name, sizeof(humrte->name)); - xfree(name); - - gbfputuint32(RTE_MAGIC, fout); - gbfwrite(humrte, sizeof(*humrte), 1, fout); - } - - xfree(humrte); - humrte = NULL; + if (humrte == NULL) { + return; + } + + if (humrte->count > 0) { + int i; + char *name; + + humrte->num = rte_num++; + humrte->time = gpsbabel_time; + for (i = 0; i < humrte->count; i++) { + be_write16(&humrte->points[i], humrte->points[i]); + } + + be_write16(&humrte->num, humrte->num); + be_write32(&humrte->time, humrte->time); + + name = mkshort(rtename_sh, rte->rte_name); + strncpy(humrte->name, name, sizeof(humrte->name)); + xfree(name); + + gbfputuint32(RTE_MAGIC, fout); + gbfwrite(humrte, sizeof(*humrte), 1, fout); + } + + xfree(humrte); + humrte = NULL; } static void humminbird_write_rtept(const waypoint *wpt) { - int i; - - if (humrte == NULL) return; - i = gb_ptr2int(wpt->extra_data); - if (i <= 0) return; - - if (humrte->count < MAX_RTE_POINTS) { - humrte->points[humrte->count] = i - 1; - humrte->count++; - } - else { - warning(MYNAME ": Sorry, routes are limited to %d points!\n", MAX_RTE_POINTS); - fatal(MYNAME ": You can use our simplify filter to reduce the number of route points.\n"); - } + int i; + + if (humrte == NULL) { + return; + } + i = gb_ptr2int(wpt->extra_data); + if (i <= 0) { + return; + } + + if (humrte->count < MAX_RTE_POINTS) { + humrte->points[humrte->count] = i - 1; + humrte->count++; + } else { + warning(MYNAME ": Sorry, routes are limited to %d points!\n", MAX_RTE_POINTS); + fatal(MYNAME ": You can use our simplify filter to reduce the number of route points.\n"); + } } static void humminbird_write_waypoint_wrapper(const waypoint *wpt) { - char *key; - waypoint *tmpwpt; + char *key; + waypoint *tmpwpt; - xasprintf(&key, "%s\01%.9f\01%.9f", wpt->shortname, wpt->latitude, wpt->longitude); + xasprintf(&key, "%s\01%.9f\01%.9f", wpt->shortname, wpt->latitude, wpt->longitude); - if (! avltree_find(waypoints, key, (void *)&tmpwpt)) { - tmpwpt = (waypoint *)wpt; + if (! avltree_find(waypoints, key, (void *)&tmpwpt)) { + tmpwpt = (waypoint *)wpt; - avltree_insert(waypoints, key, wpt); + avltree_insert(waypoints, key, wpt); - tmpwpt->extra_data = gb_int2ptr(waypoint_num + 1); /* NOT NULL */ - humminbird_write_waypoint(wpt); - } - else { - void *p = tmpwpt->extra_data; - tmpwpt = (waypoint *)wpt; - tmpwpt->extra_data = p; - } + tmpwpt->extra_data = gb_int2ptr(waypoint_num + 1); /* NOT NULL */ + humminbird_write_waypoint(wpt); + } else { + void *p = tmpwpt->extra_data; + tmpwpt = (waypoint *)wpt; + tmpwpt->extra_data = p; + } - xfree(key); + xfree(key); } static void humminbird_write(void) { - waypt_disp_all(humminbird_write_waypoint_wrapper); - route_disp_all(NULL, NULL, humminbird_write_waypoint_wrapper); - route_disp_all(humminbird_rte_head, humminbird_rte_tail, humminbird_write_rtept); + waypt_disp_all(humminbird_write_waypoint_wrapper); + route_disp_all(NULL, NULL, humminbird_write_waypoint_wrapper); + route_disp_all(humminbird_rte_head, humminbird_rte_tail, humminbird_write_rtept); } /**************************************************************************/ ff_vecs_t humminbird_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_read | ff_cap_write /* routes */ - }, - humminbird_rd_init, - humminbird_wr_init, - humminbird_rd_deinit, - humminbird_wr_deinit, - humminbird_read, - humminbird_write, - NULL, // humminbird_exit, - humminbird_args, - CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ - /* currently fixed !!! */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_read | ff_cap_write /* routes */ + }, + humminbird_rd_init, + humminbird_wr_init, + humminbird_rd_deinit, + humminbird_wr_deinit, + humminbird_read, + humminbird_write, + NULL, // humminbird_exit, + humminbird_args, + CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ + /* currently fixed !!! */ }; /**************************************************************************/ @@ -920,22 +961,22 @@ ff_vecs_t humminbird_vecs = { /**************************************************************************/ ff_vecs_t humminbird_ht_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_read /* routes */ - }, - humminbird_rd_init, - humminbird_wr_init, - humminbird_rd_deinit, - humminbird_wr_deinit, - humminbird_read, - humminbird_track_write, - NULL, // humminbird_exit, - humminbird_args, - CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ - /* currently fixed !!! */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_read /* routes */ + }, + humminbird_rd_init, + humminbird_wr_init, + humminbird_rd_deinit, + humminbird_wr_deinit, + humminbird_read, + humminbird_track_write, + NULL, // humminbird_exit, + humminbird_args, + CET_CHARSET_ASCII, 1 /* ascii is the expected character set */ + /* currently fixed !!! */ }; /**************************************************************************/ diff --git a/gpsbabel/igc.c b/gpsbabel/igc.c index 3fa95d518..af5294b37 100644 --- a/gpsbabel/igc.c +++ b/gpsbabel/igc.c @@ -1,26 +1,26 @@ /* * FAI/IGC data format translation. - * + * * Refer to Appendix 1 of * http://www.fai.org:81/gliding/gnss/tech_spec_gnss.asp for the * specification of the IGC data format. This translation code was * written when the latest ammendment list for the specification was AL6. - * + * * Copyright (C) 2004 Chris Jones - * - * This program is free software; you can redistribute it and/or modify it + * + * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. - * + * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111 USA + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111 USA */ #include "defs.h" @@ -46,23 +46,23 @@ static int lineno; * These appear as the first char in each record. */ typedef enum { - rec_manuf_id = 'A', // FR manufacturer and identification - rec_fix = 'B', // Fix - rec_task = 'C', // Task/declaration - rec_diff_gps = 'D', // Differential GPS - rec_event = 'E', // Event - rec_constel = 'F', // Constellation - rec_security = 'G', // Security - rec_header = 'H', // File header - rec_fix_defn = 'I', // List of extension data included at end of each fix (B) record - rec_extn_defn = 'J', // List of data included in each extension (K) record - rec_extn_data = 'K', // Extension data - rec_log_book = 'L', // Logbook/comments - - // M..Z are spare - - rec_none = 0, // No record - rec_bad = 1, // Bad record + rec_manuf_id = 'A', // FR manufacturer and identification + rec_fix = 'B', // Fix + rec_task = 'C', // Task/declaration + rec_diff_gps = 'D', // Differential GPS + rec_event = 'E', // Event + rec_constel = 'F', // Constellation + rec_security = 'G', // Security + rec_header = 'H', // File header + rec_fix_defn = 'I', // List of extension data included at end of each fix (B) record + rec_extn_defn = 'J', // List of data included in each extension (K) record + rec_extn_data = 'K', // Extension data + rec_log_book = 'L', // Logbook/comments + + // M..Z are spare + + rec_none = 0, // No record + rec_bad = 1, // Bad record } igc_rec_type_t; /* @@ -76,11 +76,11 @@ typedef enum { */ static unsigned char coords_match(double lat1, double lon1, double lat2, double lon2) { - return (fabs(lat1 - lat2) < 0.0001 && fabs(lon1 - lon2) < 0.0001) ? 1 : 0; + return (fabs(lat1 - lat2) < 0.0001 && fabs(lon1 - lon2) < 0.0001) ? 1 : 0; } /************************************************************************************************* - * Input file processing + * Input file processing */ /* @@ -90,40 +90,46 @@ static unsigned char coords_match(double lat1, double lon1, double lat2, double */ static igc_rec_type_t get_record(char **rec) { - size_t len; - char *c; + size_t len; + char *c; retry: - *rec = c = gbfgetstr(file_in); - if ((lineno++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - if (c == NULL) return rec_none; - - len = strlen(c); - - /* Trackwiev writes (bogus) blank links between each record */ - if (len == 0) goto retry; - - if (len < 3 || c[0] < 'A' || c[0] > 'Z') { - warning(MYNAME " bad input record: '%s'\n", c); - return rec_bad; - } - return (igc_rec_type_t) c[0]; + *rec = c = gbfgetstr(file_in); + if ((lineno++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + if (c == NULL) { + return rec_none; + } + + len = strlen(c); + + /* Trackwiev writes (bogus) blank links between each record */ + if (len == 0) { + goto retry; + } + + if (len < 3 || c[0] < 'A' || c[0] > 'Z') { + warning(MYNAME " bad input record: '%s'\n", c); + return rec_bad; + } + return (igc_rec_type_t) c[0]; } static void rd_init(const char *fname) { - char *ibuf; - - file_in = gbfopen(fname, "r", MYNAME); - lineno = 0; - // File must begin with a manufacturer/ID record - if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { - fatal(MYNAME ": %s is not an IGC file\n", fname); - } + char *ibuf; + + file_in = gbfopen(fname, "r", MYNAME); + lineno = 0; + // File must begin with a manufacturer/ID record + if (get_record(&ibuf) != rec_manuf_id || sscanf(ibuf, "A%3[A-Z]", manufacturer) != 1) { + fatal(MYNAME ": %s is not an IGC file\n", fname); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } /** @@ -133,314 +139,314 @@ static void rd_deinit(void) */ static void igc_task_rec(const char *rec) { - static char flight_date[7]; - static unsigned int num_tp, tp_ct; - static route_head *rte_head; - static time_t creation; - - char task_num[5]; - char task_desc[MAXRECLEN]; - waypoint *wpt; - unsigned int lat_deg, lat_min, lat_frac; - unsigned int lon_deg, lon_min, lon_frac; - char lat_hemi[2], lon_hemi[2]; - char short_name[8]; - char tmp_str[MAXRECLEN]; - struct tm tm; - - static enum { id, takeoff, start, turnpoint, finish, landing } state = id; - - // First task record identifies the task to follow - if (id == state) { - task_desc[0] = '\0'; - if (sscanf(rec, "C%2u%2u%2u%2u%2u%2u%6[0-9]%4c%2u%[^\r]\r\n", - &tm.tm_mday, &tm.tm_mon, &tm.tm_year, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec, - flight_date, task_num, &num_tp, task_desc) < 9) { - fatal(MYNAME ": task id (C) record parse error\n'%s'", rec); - } - task_num[4] = '\0'; - tm.tm_mon -= 1; - if (tm.tm_year < 70) { - tm.tm_year += 100; - } - tm.tm_isdst = 0; - creation = mkgmtime(&tm); - - // Create a route to store the task data in. - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(task_num); - sprintf(tmp_str, DATEMAGIC "%s: %s", flight_date, task_desc); - rte_head->rte_desc = xstrdup(tmp_str); - route_add_head(rte_head); - state++; - return; - } - // Get the waypoint - tmp_str[0] = '\0'; - if (sscanf(rec, "C%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%[^\r]\r\n", - &lat_deg, &lat_min, &lat_frac, lat_hemi, - &lon_deg, &lon_min, &lon_frac, lon_hemi, tmp_str) < 8) { - fatal(MYNAME ": task waypoint (C) record parse error\n%s", rec); - } - - wpt = waypt_new(); - wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * - (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); - - wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * - (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); - - wpt->creation_time = creation; - wpt->description = xstrdup(tmp_str); - - // Name the waypoint according to the order of the task record - switch (state) { - case takeoff: - snprintf(short_name, 8, "TAKEOFF"); - state++; - break; - - case start: - snprintf(short_name, 8, "START"); - tp_ct = 0; - state++; - break; - - case turnpoint: - if (++tp_ct == num_tp) { - state++; - } - snprintf(short_name, 8, "TURN%02u", tp_ct); - break; - - case finish: - snprintf(short_name, 8, "FINISH"); - state++; - break; - - case landing: - snprintf(short_name, 8, "LANDING"); - state = id; - break; - - default: - fatal(MYNAME ": task id (C) record internal error\n%s", rec); - break; - } - - // Zero lat and lon indicates an unknown waypoint - if (coords_match(wpt->latitude, wpt->longitude, 0.0, 0.0)) { - waypt_free(wpt); - return; - } - wpt->shortname = xstrdup(short_name); - route_add_wpt(rte_head, wpt); + static char flight_date[7]; + static unsigned int num_tp, tp_ct; + static route_head *rte_head; + static time_t creation; + + char task_num[5]; + char task_desc[MAXRECLEN]; + waypoint *wpt; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char short_name[8]; + char tmp_str[MAXRECLEN]; + struct tm tm; + + static enum { id, takeoff, start, turnpoint, finish, landing } state = id; + + // First task record identifies the task to follow + if (id == state) { + task_desc[0] = '\0'; + if (sscanf(rec, "C%2u%2u%2u%2u%2u%2u%6[0-9]%4c%2u%[^\r]\r\n", + &tm.tm_mday, &tm.tm_mon, &tm.tm_year, + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, + flight_date, task_num, &num_tp, task_desc) < 9) { + fatal(MYNAME ": task id (C) record parse error\n'%s'", rec); + } + task_num[4] = '\0'; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + creation = mkgmtime(&tm); + + // Create a route to store the task data in. + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(task_num); + sprintf(tmp_str, DATEMAGIC "%s: %s", flight_date, task_desc); + rte_head->rte_desc = xstrdup(tmp_str); + route_add_head(rte_head); + state++; + return; + } + // Get the waypoint + tmp_str[0] = '\0'; + if (sscanf(rec, "C%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%[^\r]\r\n", + &lat_deg, &lat_min, &lat_frac, lat_hemi, + &lon_deg, &lon_min, &lon_frac, lon_hemi, tmp_str) < 8) { + fatal(MYNAME ": task waypoint (C) record parse error\n%s", rec); + } + + wpt = waypt_new(); + wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + wpt->creation_time = creation; + wpt->description = xstrdup(tmp_str); + + // Name the waypoint according to the order of the task record + switch (state) { + case takeoff: + snprintf(short_name, 8, "TAKEOFF"); + state++; + break; + + case start: + snprintf(short_name, 8, "START"); + tp_ct = 0; + state++; + break; + + case turnpoint: + if (++tp_ct == num_tp) { + state++; + } + snprintf(short_name, 8, "TURN%02u", tp_ct); + break; + + case finish: + snprintf(short_name, 8, "FINISH"); + state++; + break; + + case landing: + snprintf(short_name, 8, "LANDING"); + state = id; + break; + + default: + fatal(MYNAME ": task id (C) record internal error\n%s", rec); + break; + } + + // Zero lat and lon indicates an unknown waypoint + if (coords_match(wpt->latitude, wpt->longitude, 0.0, 0.0)) { + waypt_free(wpt); + return; + } + wpt->shortname = xstrdup(short_name); + route_add_wpt(rte_head, wpt); } static void data_read(void) { - char *ibuf; - igc_rec_type_t rec_type; - unsigned int hours, mins, secs; - unsigned int lat_deg, lat_min, lat_frac; - unsigned int lon_deg, lon_min, lon_frac; - char lat_hemi[2], lon_hemi[2]; - char validity; - route_head *pres_head = NULL; - route_head *gnss_head = NULL; - int pres_alt, gnss_alt; - char pres_valid = 0; - char gnss_valid = 0; - waypoint *pres_wpt = NULL; - waypoint *gnss_wpt = NULL; - time_t date = 0; - time_t prev_tod = 0; - time_t tod; - struct tm tm; - char tmp_str[20]; - char *hdr_data; - size_t remain; - char trk_desc[MAXDESCLEN + 1]; - - strcpy(trk_desc, HDRMAGIC HDRDELIM); - - while (1) { - rec_type = get_record(&ibuf); - switch (rec_type) { - case rec_manuf_id: - // Manufacturer/ID record already found in rd_init(). - warning(MYNAME ": duplicate manufacturer/ID record\n"); - break; - - case rec_header: - // Get the header sub type - if (sscanf(ibuf, "H%*1[FOP]%3s", tmp_str) != 1) { - fatal(MYNAME ": header (H) record parse error\n%s\n%s\n", ibuf, tmp_str); - } - // Optional long name of record sub type is followed by a - // colon. Actual header data follows that. - if (NULL == (hdr_data = strchr(ibuf, ':'))) { - hdr_data = ibuf + 5; - } else { - hdr_data++; - } - - // Date sub type - if (strcmp(tmp_str, "DTE") == 0) { - if (sscanf(hdr_data, "%2u%2u%2u", &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { - fatal(MYNAME ": date (H) record parse error\n'%s'\n", ibuf); - } - tm.tm_sec = tm.tm_min = tm.tm_hour = 0; - tm.tm_mon -= 1; - if (tm.tm_year < 70) { - tm.tm_year += 100; - } - tm.tm_isdst = 0; - date = mkgmtime(&tm); - } else { - // Store other header data in the track descriptions - if (strlen(trk_desc) < MAXDESCLEN) { - strcat(ibuf, HDRDELIM); - remain = MAXDESCLEN - strlen(trk_desc); - strncat(trk_desc, ibuf, remain); - } - } - break; - - case rec_fix: - // Date must appear in file before the first fix record - if (date < 1000000L) { - fatal(MYNAME ": bad date %d\n", (int)date); - } - // Create a track for pressure altitude waypoints - if (!pres_head) { - pres_head = route_head_alloc(); - pres_head->rte_name = xstrdup(PRESTRKNAME); - pres_head->rte_desc = xstrdup(trk_desc); - track_add_head(pres_head); - } - // Create a second track for GNSS altitude waypoints - if (!gnss_head) { - gnss_head = route_head_alloc(); - gnss_head->rte_name = xstrdup(GNSSTRKNAME); - gnss_head->rte_desc = xstrdup(trk_desc); - track_add_head(gnss_head); - } - // Create a waypoint from the fix record data - if (sscanf(ibuf, - "B%2u%2u%2u%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%c%5d%5d", - &hours, &mins, &secs, &lat_deg, &lat_min, &lat_frac, - lat_hemi, &lon_deg, &lon_min, &lon_frac, lon_hemi, - &validity, &pres_alt, &gnss_alt) != 14) { - fatal(MYNAME ": fix (B) record parse error\n%s\n", ibuf); - } - pres_wpt = waypt_new(); - - pres_wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * - (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); - - pres_wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * - (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); - - // Increment date if we pass midnight UTC - tod = (hours * 60 + mins) * 60 + secs; - if (tod < prev_tod) { - date += 24 * 60 * 60; - } - prev_tod = tod; - pres_wpt->creation_time = date + tod; - - // Add the waypoint to the pressure altitude track - if (pres_alt) { - pres_valid = 1; - pres_wpt->altitude = pres_alt; - } else { - pres_wpt->altitude = unknown_alt; - } - track_add_wpt(pres_head, pres_wpt); - - // Add the same waypoint with GNSS altitude to the second - // track - gnss_wpt = waypt_dupe(pres_wpt); - - if (gnss_alt) { - gnss_valid = 1; - gnss_wpt->altitude = gnss_alt; - } else { - gnss_wpt->altitude = unknown_alt; - } - track_add_wpt(gnss_head, gnss_wpt); - break; - - case rec_task: - // Create a route for each pre-flight declaration - igc_task_rec(ibuf); - break; - - case rec_log_book: - // Get the log book sub type - if (sscanf(ibuf, "L%3s", tmp_str) != 1) { - fatal(MYNAME ": log book (L) record parse error\n'%s'\n", ibuf); - } - - if (strcmp(tmp_str, "PFC") == 0) { - // Create a route for each post-flight declaration - igc_task_rec(ibuf + 4); - break; - } else if (global_opts.debug_level) { - if (strcmp(tmp_str, "OOI") == 0) { - fputs(MYNAME ": Observer Input> ", stdout); - } else if (strcmp(tmp_str, "PLT") == 0) { - fputs(MYNAME ": Pilot Input> ", stdout); - } else if (strcmp(tmp_str, manufacturer) == 0) { - fputs(MYNAME ": Manufacturer Input> ", stdout); - } else { - fputs(MYNAME ": Anonymous Input> ", stdout); - fputs(ibuf + 1, stdout); - break; - } - fputs(ibuf + 4, stdout); - putchar('\n'); - } - break; - - // These record types are discarded - case rec_diff_gps: - case rec_event: - case rec_constel: - case rec_security: - case rec_fix_defn: - case rec_extn_defn: - case rec_extn_data: - break; - - // No more records - case rec_none: - - // Include pressure altitude track only if it has useful - // altitude data or if it is the only track available. - if (pres_head && !pres_valid && gnss_head) { - track_del_head(pres_head); - pres_head = NULL; - } - // Include GNSS altitude track only if it has useful altitude - // data or if it is the only track available. - if (gnss_head && !gnss_valid && pres_head) { - track_del_head(gnss_head); - } - return; // All done so bail - - default: - case rec_bad: - fatal(MYNAME ": failure reading file\n"); - break; - } + char *ibuf; + igc_rec_type_t rec_type; + unsigned int hours, mins, secs; + unsigned int lat_deg, lat_min, lat_frac; + unsigned int lon_deg, lon_min, lon_frac; + char lat_hemi[2], lon_hemi[2]; + char validity; + route_head *pres_head = NULL; + route_head *gnss_head = NULL; + int pres_alt, gnss_alt; + char pres_valid = 0; + char gnss_valid = 0; + waypoint *pres_wpt = NULL; + waypoint *gnss_wpt = NULL; + time_t date = 0; + time_t prev_tod = 0; + time_t tod; + struct tm tm; + char tmp_str[20]; + char *hdr_data; + size_t remain; + char trk_desc[MAXDESCLEN + 1]; + + strcpy(trk_desc, HDRMAGIC HDRDELIM); + + while (1) { + rec_type = get_record(&ibuf); + switch (rec_type) { + case rec_manuf_id: + // Manufacturer/ID record already found in rd_init(). + warning(MYNAME ": duplicate manufacturer/ID record\n"); + break; + + case rec_header: + // Get the header sub type + if (sscanf(ibuf, "H%*1[FOP]%3s", tmp_str) != 1) { + fatal(MYNAME ": header (H) record parse error\n%s\n%s\n", ibuf, tmp_str); + } + // Optional long name of record sub type is followed by a + // colon. Actual header data follows that. + if (NULL == (hdr_data = strchr(ibuf, ':'))) { + hdr_data = ibuf + 5; + } else { + hdr_data++; + } + + // Date sub type + if (strcmp(tmp_str, "DTE") == 0) { + if (sscanf(hdr_data, "%2u%2u%2u", &tm.tm_mday, &tm.tm_mon, &tm.tm_year) != 3) { + fatal(MYNAME ": date (H) record parse error\n'%s'\n", ibuf); + } + tm.tm_sec = tm.tm_min = tm.tm_hour = 0; + tm.tm_mon -= 1; + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + tm.tm_isdst = 0; + date = mkgmtime(&tm); + } else { + // Store other header data in the track descriptions + if (strlen(trk_desc) < MAXDESCLEN) { + strcat(ibuf, HDRDELIM); + remain = MAXDESCLEN - strlen(trk_desc); + strncat(trk_desc, ibuf, remain); + } + } + break; + + case rec_fix: + // Date must appear in file before the first fix record + if (date < 1000000L) { + fatal(MYNAME ": bad date %d\n", (int)date); + } + // Create a track for pressure altitude waypoints + if (!pres_head) { + pres_head = route_head_alloc(); + pres_head->rte_name = xstrdup(PRESTRKNAME); + pres_head->rte_desc = xstrdup(trk_desc); + track_add_head(pres_head); + } + // Create a second track for GNSS altitude waypoints + if (!gnss_head) { + gnss_head = route_head_alloc(); + gnss_head->rte_name = xstrdup(GNSSTRKNAME); + gnss_head->rte_desc = xstrdup(trk_desc); + track_add_head(gnss_head); + } + // Create a waypoint from the fix record data + if (sscanf(ibuf, + "B%2u%2u%2u%2u%2u%3u%1[NS]%3u%2u%3u%1[WE]%c%5d%5d", + &hours, &mins, &secs, &lat_deg, &lat_min, &lat_frac, + lat_hemi, &lon_deg, &lon_min, &lon_frac, lon_hemi, + &validity, &pres_alt, &gnss_alt) != 14) { + fatal(MYNAME ": fix (B) record parse error\n%s\n", ibuf); + } + pres_wpt = waypt_new(); + + pres_wpt->latitude = ('N' == lat_hemi[0] ? 1 : -1) * + (lat_deg + (lat_min * 1000 + lat_frac) / 1000.0 / 60); + + pres_wpt->longitude = ('E' == lon_hemi[0] ? 1 : -1) * + (lon_deg + (lon_min * 1000 + lon_frac) / 1000.0 / 60); + + // Increment date if we pass midnight UTC + tod = (hours * 60 + mins) * 60 + secs; + if (tod < prev_tod) { + date += 24 * 60 * 60; + } + prev_tod = tod; + pres_wpt->creation_time = date + tod; + + // Add the waypoint to the pressure altitude track + if (pres_alt) { + pres_valid = 1; + pres_wpt->altitude = pres_alt; + } else { + pres_wpt->altitude = unknown_alt; + } + track_add_wpt(pres_head, pres_wpt); + + // Add the same waypoint with GNSS altitude to the second + // track + gnss_wpt = waypt_dupe(pres_wpt); + + if (gnss_alt) { + gnss_valid = 1; + gnss_wpt->altitude = gnss_alt; + } else { + gnss_wpt->altitude = unknown_alt; + } + track_add_wpt(gnss_head, gnss_wpt); + break; + + case rec_task: + // Create a route for each pre-flight declaration + igc_task_rec(ibuf); + break; + + case rec_log_book: + // Get the log book sub type + if (sscanf(ibuf, "L%3s", tmp_str) != 1) { + fatal(MYNAME ": log book (L) record parse error\n'%s'\n", ibuf); + } + + if (strcmp(tmp_str, "PFC") == 0) { + // Create a route for each post-flight declaration + igc_task_rec(ibuf + 4); + break; + } else if (global_opts.debug_level) { + if (strcmp(tmp_str, "OOI") == 0) { + fputs(MYNAME ": Observer Input> ", stdout); + } else if (strcmp(tmp_str, "PLT") == 0) { + fputs(MYNAME ": Pilot Input> ", stdout); + } else if (strcmp(tmp_str, manufacturer) == 0) { + fputs(MYNAME ": Manufacturer Input> ", stdout); + } else { + fputs(MYNAME ": Anonymous Input> ", stdout); + fputs(ibuf + 1, stdout); + break; + } + fputs(ibuf + 4, stdout); + putchar('\n'); + } + break; + + // These record types are discarded + case rec_diff_gps: + case rec_event: + case rec_constel: + case rec_security: + case rec_fix_defn: + case rec_extn_defn: + case rec_extn_data: + break; + + // No more records + case rec_none: + + // Include pressure altitude track only if it has useful + // altitude data or if it is the only track available. + if (pres_head && !pres_valid && gnss_head) { + track_del_head(pres_head); + pres_head = NULL; + } + // Include GNSS altitude track only if it has useful altitude + // data or if it is the only track available. + if (gnss_head && !gnss_valid && pres_head) { + track_del_head(gnss_head); + } + return; // All done so bail + + default: + case rec_bad: + fatal(MYNAME ": failure reading file\n"); + break; } + } } /************************************************************************************************* - * Output file processing + * Output file processing */ /************************************************* @@ -449,33 +455,33 @@ static void data_read(void) static void detect_pres_track(const route_head * rh) { - if (rh->rte_name && strncmp(rh->rte_name, PRESTRKNAME, 6) == 0) { - head = rh; - } + if (rh->rte_name && strncmp(rh->rte_name, PRESTRKNAME, 6) == 0) { + head = rh; + } } static void detect_gnss_track(const route_head * rh) { - if (rh->rte_name && strncmp(rh->rte_name, GNSSTRKNAME, 6) == 0) { - head = rh; - } + if (rh->rte_name && strncmp(rh->rte_name, GNSSTRKNAME, 6) == 0) { + head = rh; + } } static void detect_other_track(const route_head * rh) { - static int max_waypt_ct; - - if (!head) { - max_waypt_ct = 0; - } - // Find other track with the most waypoints - if (rh->rte_waypt_ct > max_waypt_ct && - (!rh->rte_name || - (strncmp(rh->rte_name, PRESTRKNAME, 6) != 0 && - strncmp(rh->rte_name, GNSSTRKNAME, 6) != 0))) { - head = rh; - max_waypt_ct = rh->rte_waypt_ct; - } + static int max_waypt_ct; + + if (!head) { + max_waypt_ct = 0; + } + // Find other track with the most waypoints + if (rh->rte_waypt_ct > max_waypt_ct && + (!rh->rte_name || + (strncmp(rh->rte_name, PRESTRKNAME, 6) != 0 && + strncmp(rh->rte_name, GNSSTRKNAME, 6) != 0))) { + head = rh; + max_waypt_ct = rh->rte_waypt_ct; + } } /* @@ -487,24 +493,24 @@ static void detect_other_track(const route_head * rh) */ static void get_tracks(const route_head ** pres_track, const route_head ** gnss_track) { - head = NULL; - track_disp_all(detect_pres_track, NULL, NULL); - *pres_track = head; + head = NULL; + track_disp_all(detect_pres_track, NULL, NULL); + *pres_track = head; - head = NULL; - track_disp_all(detect_gnss_track, NULL, NULL); - *gnss_track = head; + head = NULL; + track_disp_all(detect_gnss_track, NULL, NULL); + *gnss_track = head; - head = NULL; - track_disp_all(detect_other_track, NULL, NULL); + head = NULL; + track_disp_all(detect_other_track, NULL, NULL); - if (!*pres_track && *gnss_track && head) { - *pres_track = head; - } + if (!*pres_track && *gnss_track && head) { + *pres_track = head; + } - if (!*gnss_track && head) { - *gnss_track = head; - } + if (!*gnss_track && head) { + *gnss_track = head; + } } /************************************************* @@ -513,39 +519,39 @@ static void get_tracks(const route_head ** pres_track, const route_head ** gnss_ static char *latlon2str(const waypoint * wpt) { - static char str[18] = ""; - char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; - char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; - unsigned char lat_deg = fabs(wpt->latitude); - unsigned char lon_deg = fabs(wpt->longitude); - unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; - unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; - - if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", - lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { - fatal(MYNAME ": Bad waypoint format '%s'\n", str); - } - return str; + static char str[18] = ""; + char lat_hemi = wpt->latitude < 0 ? 'S' : 'N'; + char lon_hemi = wpt->longitude < 0 ? 'W' : 'E'; + unsigned char lat_deg = fabs(wpt->latitude); + unsigned char lon_deg = fabs(wpt->longitude); + unsigned int lat_min = (fabs(wpt->latitude) - lat_deg) * 60000 + 0.500000000001; + unsigned int lon_min = (fabs(wpt->longitude) - lon_deg) * 60000 + 0.500000000001; + + if (snprintf(str, 18, "%02u%05u%c%03u%05u%c", + lat_deg, lat_min, lat_hemi, lon_deg, lon_min, lon_hemi) != 17) { + fatal(MYNAME ": Bad waypoint format '%s'\n", str); + } + return str; } static char *date2str(struct tm *dt) { - static char str[7] = ""; + static char str[7] = ""; - if (snprintf(str, 7, "%02u%02u%02u", dt->tm_mday, dt->tm_mon + 1, dt->tm_year % 100) != 6) { - fatal(MYNAME ": Bad date format '%s'\n", str); - } - return str; + if (snprintf(str, 7, "%02u%02u%02u", dt->tm_mday, dt->tm_mon + 1, dt->tm_year % 100) != 6) { + fatal(MYNAME ": Bad date format '%s'\n", str); + } + return str; } static char *tod2str(struct tm *tod) { - static char str[7] = ""; + static char str[7] = ""; - if (snprintf(str, 7, "%02u%02u%02u", tod->tm_hour, tod->tm_min, tod->tm_sec) != 6) { - fatal(MYNAME ": Bad time of day format '%s'\n", str); - } - return str; + if (snprintf(str, 7, "%02u%02u%02u", tod->tm_hour, tod->tm_min, tod->tm_sec) != 6) { + fatal(MYNAME ": Bad time of day format '%s'\n", str); + } + return str; } /* @@ -553,43 +559,43 @@ static char *tod2str(struct tm *tod) */ static void wr_header(void) { - const route_head *pres_track; - const route_head *track; - struct tm *tm; - time_t date; - static const char dflt_str[] = "Unknown"; - const char *str; - waypoint *wpt; - - get_tracks(&pres_track, &track); - if (!track && pres_track) { - track = pres_track; - } - // Date in header record is that of the first fix record - date = !track ? current_time() : - ((waypoint *) QUEUE_FIRST(&track->waypoint_list))->creation_time; - - if (NULL == (tm = gmtime(&date))) { - fatal(MYNAME ": Bad track timestamp\n"); - } - gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); - - // Other header data may have been stored in track description - if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { - for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); - str; str = strtok(NULL, HDRDELIM)) { - gbfprintf(file_out, "%s\r\n", str); - } - } else { - // IGC header info not found so synthesise it. - // If a waypoint is supplied with a short name of "PILOT", use - // its description as the pilot's name in the header. - str = dflt_str; - if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { - str = wpt->description; - } - gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); - } + const route_head *pres_track; + const route_head *track; + struct tm *tm; + time_t date; + static const char dflt_str[] = "Unknown"; + const char *str; + waypoint *wpt; + + get_tracks(&pres_track, &track); + if (!track && pres_track) { + track = pres_track; + } + // Date in header record is that of the first fix record + date = !track ? current_time() : + ((waypoint *) QUEUE_FIRST(&track->waypoint_list))->creation_time; + + if (NULL == (tm = gmtime(&date))) { + fatal(MYNAME ": Bad track timestamp\n"); + } + gbfprintf(file_out, "HFDTE%s\r\n", date2str(tm)); + + // Other header data may have been stored in track description + if (track && track->rte_desc && strncmp(track->rte_desc, HDRMAGIC, strlen(HDRMAGIC)) == 0) { + for (str = strtok(track->rte_desc + strlen(HDRMAGIC) + strlen(HDRDELIM), HDRDELIM); + str; str = strtok(NULL, HDRDELIM)) { + gbfprintf(file_out, "%s\r\n", str); + } + } else { + // IGC header info not found so synthesise it. + // If a waypoint is supplied with a short name of "PILOT", use + // its description as the pilot's name in the header. + str = dflt_str; + if (NULL != (wpt = find_waypt_by_name("PILOT")) && wpt->description) { + str = wpt->description; + } + gbfprintf(file_out, "HFPLTPILOT:%s\r\n", str); + } } /************************************************* @@ -598,77 +604,76 @@ static void wr_header(void) static void wr_task_wpt_name(const waypoint * wpt, const char *alt_name) { - gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), - wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); + gbfprintf(file_out, "C%s%s\r\n", latlon2str(wpt), + wpt->description ? wpt->description : wpt->shortname ? wpt->shortname : alt_name); } static void wr_task_hdr(const route_head * rte) { - unsigned char have_takeoff = 0; - const waypoint *wpt; - char flight_date[7] = "000000"; - char task_desc[MAXRECLEN] = ""; - int num_tps = rte->rte_waypt_ct - 2; - struct tm *tm; - time_t rte_time; - static unsigned int task_num = 1; - - if (num_tps < 0) { - fatal(MYNAME ": Empty task route\n"); - } - // See if the takeoff and landing waypoints are there or if we need to - // generate them. - wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); - if (wpt->shortname && strncmp(wpt->shortname, "LANDING", 6) == 0) { - num_tps--; - } - wpt = (waypoint *) QUEUE_FIRST(&rte->waypoint_list); - if (wpt->shortname && strncmp(wpt->shortname, "TAKEOFF", 6) == 0) { - have_takeoff = 1; - num_tps--; - } - if (num_tps < 0) { - fatal(MYNAME ": Too few waypoints in task route\n"); - } - else if (num_tps > 99) { - fatal(MYNAME ": Too much waypoints (more than 99) in task route.\n"); - } - // Gather data to write to the task identification (first) record - rte_time = wpt->creation_time ? wpt->creation_time : current_time(); - if (NULL == (tm = gmtime(&rte_time))) { - fatal(MYNAME ": Bad task route timestamp\n"); - } - - if (rte->rte_desc) { - sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); - } - - gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), - tod2str(tm), flight_date, task_num++, num_tps, task_desc); - - if (!have_takeoff) { - // Generate the takeoff waypoint - wr_task_wpt_name(wpt, "TAKEOFF"); - } + unsigned char have_takeoff = 0; + const waypoint *wpt; + char flight_date[7] = "000000"; + char task_desc[MAXRECLEN] = ""; + int num_tps = rte->rte_waypt_ct - 2; + struct tm *tm; + time_t rte_time; + static unsigned int task_num = 1; + + if (num_tps < 0) { + fatal(MYNAME ": Empty task route\n"); + } + // See if the takeoff and landing waypoints are there or if we need to + // generate them. + wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "LANDING", 6) == 0) { + num_tps--; + } + wpt = (waypoint *) QUEUE_FIRST(&rte->waypoint_list); + if (wpt->shortname && strncmp(wpt->shortname, "TAKEOFF", 6) == 0) { + have_takeoff = 1; + num_tps--; + } + if (num_tps < 0) { + fatal(MYNAME ": Too few waypoints in task route\n"); + } else if (num_tps > 99) { + fatal(MYNAME ": Too much waypoints (more than 99) in task route.\n"); + } + // Gather data to write to the task identification (first) record + rte_time = wpt->creation_time ? wpt->creation_time : current_time(); + if (NULL == (tm = gmtime(&rte_time))) { + fatal(MYNAME ": Bad task route timestamp\n"); + } + + if (rte->rte_desc) { + sscanf(rte->rte_desc, DATEMAGIC "%6[0-9]: %s", flight_date, task_desc); + } + + gbfprintf(file_out, "C%s%s%s%04u%02u%s\r\n", date2str(tm), + tod2str(tm), flight_date, task_num++, num_tps, task_desc); + + if (!have_takeoff) { + // Generate the takeoff waypoint + wr_task_wpt_name(wpt, "TAKEOFF"); + } } static void wr_task_wpt(const waypoint * wpt) { - wr_task_wpt_name(wpt, ""); + wr_task_wpt_name(wpt, ""); } static void wr_task_tlr(const route_head * rte) { - // If the landing waypoint is not supplied we need to generate it. - const waypoint *wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); - if (!wpt->shortname || strncmp(wpt->shortname, "LANDIN", 6) != 0) { - wr_task_wpt_name(wpt, "LANDING"); - } + // If the landing waypoint is not supplied we need to generate it. + const waypoint *wpt = (waypoint *) QUEUE_LAST(&rte->waypoint_list); + if (!wpt->shortname || strncmp(wpt->shortname, "LANDIN", 6) != 0) { + wr_task_wpt_name(wpt, "LANDING"); + } } static void wr_tasks(void) { - route_disp_all(wr_task_hdr, wr_task_tlr, wr_task_wpt); + route_disp_all(wr_task_hdr, wr_task_tlr, wr_task_wpt); } /* @@ -676,20 +681,20 @@ static void wr_tasks(void) */ static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) { - struct tm *tm; - - if (NULL == (tm = gmtime(&wpt->creation_time))) { - fatal(MYNAME ": bad track timestamp\n"); - } - - if (unknown_alt == pres_alt) { - pres_alt = 0; - } - if (unknown_alt == gnss_alt) { - gnss_alt = 0; - } - gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, - tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); + struct tm *tm; + + if (NULL == (tm = gmtime(&wpt->creation_time))) { + fatal(MYNAME ": bad track timestamp\n"); + } + + if (unknown_alt == pres_alt) { + pres_alt = 0; + } + if (unknown_alt == gnss_alt) { + gnss_alt = 0; + } + gbfprintf(file_out, "B%02u%02u%02u%sA%05d%05d\r\n", tm->tm_hour, + tm->tm_min, tm->tm_sec, latlon2str(wpt), pres_alt, gnss_alt); } /** @@ -702,62 +707,62 @@ static void wr_fix_record(const waypoint * wpt, int pres_alt, int gnss_alt) */ static int correlate_tracks(const route_head * pres_track, const route_head * gnss_track) { - const queue *elem; - double last_alt, alt_diff; - double speed; - time_t pres_time, gnss_time; - int time_diff; - const waypoint *wpt; - - // Deduce the landing time from the pressure altitude track based on - // when we last descended to within 10m of the final track altitude. - elem = QUEUE_LAST(&pres_track->waypoint_list); - last_alt = ((waypoint *) elem)->altitude; - do { - elem = elem->prev; - if (&pres_track->waypoint_list == elem) { - // No track left - return 0; - } - alt_diff = last_alt - ((waypoint *) elem)->altitude; - if (alt_diff > 10.0) { - // Last part of track was ascending - return 0; - } - } while (alt_diff > -10.0); - pres_time = ((waypoint *) elem->next)->creation_time; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": pressure landing time %s", ctime(&pres_time)); - } - // Deduce the landing time from the GNSS altitude track based on - // when the groundspeed last dropped below a certain level. - elem = QUEUE_LAST(&gnss_track->waypoint_list); - last_alt = ((waypoint *) elem)->altitude; - do { - wpt = (waypoint *) elem; - elem = elem->prev; - if (&gnss_track->waypoint_list == elem) { - // No track left - return 0; - } - // Get a crude indication of groundspeed from the change in lat/lon - time_diff = wpt->creation_time - ((waypoint *) elem)->creation_time; - speed = !time_diff ? 0 : - (fabs(wpt->latitude - ((waypoint *) elem)->latitude) + - fabs(wpt->longitude - ((waypoint *) elem)->longitude)) / time_diff; - if (global_opts.debug_level >= 2) { - printf(MYNAME ": speed=%f\n", speed); - } - } while (speed < 0.00003); - gnss_time = ((waypoint *) elem->next)->creation_time; - if (global_opts.debug_level >= 1) { - printf(MYNAME ": gnss landing time %s", ctime(&gnss_time)); - } - // Time adjustment is difference between the two estimated landing times - if (15 * 60 < abs(time_diff = pres_time - gnss_time)) { - warning(MYNAME ": excessive time adjustment %ds\n", time_diff); - } - return time_diff; + const queue *elem; + double last_alt, alt_diff; + double speed; + time_t pres_time, gnss_time; + int time_diff; + const waypoint *wpt; + + // Deduce the landing time from the pressure altitude track based on + // when we last descended to within 10m of the final track altitude. + elem = QUEUE_LAST(&pres_track->waypoint_list); + last_alt = ((waypoint *) elem)->altitude; + do { + elem = elem->prev; + if (&pres_track->waypoint_list == elem) { + // No track left + return 0; + } + alt_diff = last_alt - ((waypoint *) elem)->altitude; + if (alt_diff > 10.0) { + // Last part of track was ascending + return 0; + } + } while (alt_diff > -10.0); + pres_time = ((waypoint *) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": pressure landing time %s", ctime(&pres_time)); + } + // Deduce the landing time from the GNSS altitude track based on + // when the groundspeed last dropped below a certain level. + elem = QUEUE_LAST(&gnss_track->waypoint_list); + last_alt = ((waypoint *) elem)->altitude; + do { + wpt = (waypoint *) elem; + elem = elem->prev; + if (&gnss_track->waypoint_list == elem) { + // No track left + return 0; + } + // Get a crude indication of groundspeed from the change in lat/lon + time_diff = wpt->creation_time - ((waypoint *) elem)->creation_time; + speed = !time_diff ? 0 : + (fabs(wpt->latitude - ((waypoint *) elem)->latitude) + + fabs(wpt->longitude - ((waypoint *) elem)->longitude)) / time_diff; + if (global_opts.debug_level >= 2) { + printf(MYNAME ": speed=%f\n", speed); + } + } while (speed < 0.00003); + gnss_time = ((waypoint *) elem->next)->creation_time; + if (global_opts.debug_level >= 1) { + printf(MYNAME ": gnss landing time %s", ctime(&gnss_time)); + } + // Time adjustment is difference between the two estimated landing times + if (15 * 60 < abs(time_diff = pres_time - gnss_time)) { + warning(MYNAME ": excessive time adjustment %ds\n", time_diff); + } + return time_diff; } /** @@ -768,46 +773,46 @@ static int correlate_tracks(const route_head * pres_track, const route_head * gn */ static double interpolate_alt(const route_head * track, time_t time) { - static const queue *prev_elem = NULL; - static const queue *curr_elem = NULL; - const waypoint *prev_wpt; - const waypoint *curr_wpt; - int time_diff; - double alt_diff; - - // Start search at the beginning of the track - if (!prev_elem) { - curr_elem = prev_elem = QUEUE_FIRST(&track->waypoint_list); - } - // Find the track points either side of the requested time - while (((waypoint *) curr_elem)->creation_time < time) { - if (QUEUE_LAST(&track->waypoint_list) == curr_elem) { - // Requested time later than all track points, we can't interpolate - return unknown_alt; - } - prev_elem = curr_elem; - curr_elem = QUEUE_NEXT(prev_elem); - } - - prev_wpt = (waypoint *) prev_elem; - curr_wpt = (waypoint *) curr_elem; - - if (QUEUE_FIRST(&track->waypoint_list) == curr_elem) { - if (curr_wpt->creation_time == time) { - // First point's creation time is an exact match so use it's altitude - return curr_wpt->altitude; - } else { - // Requested time is prior to any track points, we can't interpolate - return unknown_alt; - } - } - // Interpolate - if (0 == (time_diff = curr_wpt->creation_time - prev_wpt->creation_time)) { - // Avoid divide by zero - return curr_wpt->altitude; - } - alt_diff = curr_wpt->altitude - prev_wpt->altitude; - return prev_wpt->altitude + (alt_diff / time_diff) * (time - prev_wpt->creation_time); + static const queue *prev_elem = NULL; + static const queue *curr_elem = NULL; + const waypoint *prev_wpt; + const waypoint *curr_wpt; + int time_diff; + double alt_diff; + + // Start search at the beginning of the track + if (!prev_elem) { + curr_elem = prev_elem = QUEUE_FIRST(&track->waypoint_list); + } + // Find the track points either side of the requested time + while (((waypoint *) curr_elem)->creation_time < time) { + if (QUEUE_LAST(&track->waypoint_list) == curr_elem) { + // Requested time later than all track points, we can't interpolate + return unknown_alt; + } + prev_elem = curr_elem; + curr_elem = QUEUE_NEXT(prev_elem); + } + + prev_wpt = (waypoint *) prev_elem; + curr_wpt = (waypoint *) curr_elem; + + if (QUEUE_FIRST(&track->waypoint_list) == curr_elem) { + if (curr_wpt->creation_time == time) { + // First point's creation time is an exact match so use it's altitude + return curr_wpt->altitude; + } else { + // Requested time is prior to any track points, we can't interpolate + return unknown_alt; + } + } + // Interpolate + if (0 == (time_diff = curr_wpt->creation_time - prev_wpt->creation_time)) { + // Avoid divide by zero + return curr_wpt->altitude; + } + alt_diff = curr_wpt->altitude - prev_wpt->altitude; + return prev_wpt->altitude + (alt_diff / time_diff) * (time - prev_wpt->creation_time); } /* @@ -816,95 +821,97 @@ static double interpolate_alt(const route_head * track, time_t time) */ static void wr_track(void) { - const route_head *pres_track; - const route_head *gnss_track; - const waypoint *wpt; - const queue *elem; - const queue *tmp; - int time_adj; - double pres_alt; - - // Find pressure altitude and GNSS altitude tracks - get_tracks(&pres_track, &gnss_track); - - // If both found, attempt to merge them - if (pres_track && gnss_track) { - if (timeadj) { - if (strcmp(timeadj, "auto") == 0) { - time_adj = correlate_tracks(pres_track, gnss_track); - } else if (sscanf(timeadj, "%d", &time_adj) != 1) { - fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj); - } - } else { - time_adj = 0; - } - if (global_opts.debug_level >= 1) { - printf(MYNAME ": adjusting time by %ds\n", time_adj); - } - // Iterate through waypoints in both tracks simultaneously - QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { - wpt = (waypoint *) elem; - pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj); - wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude); - } + const route_head *pres_track; + const route_head *gnss_track; + const waypoint *wpt; + const queue *elem; + const queue *tmp; + int time_adj; + double pres_alt; + + // Find pressure altitude and GNSS altitude tracks + get_tracks(&pres_track, &gnss_track); + + // If both found, attempt to merge them + if (pres_track && gnss_track) { + if (timeadj) { + if (strcmp(timeadj, "auto") == 0) { + time_adj = correlate_tracks(pres_track, gnss_track); + } else if (sscanf(timeadj, "%d", &time_adj) != 1) { + fatal(MYNAME ": bad timeadj argument '%s'\n", timeadj); + } + } else { + time_adj = 0; + } + if (global_opts.debug_level >= 1) { + printf(MYNAME ": adjusting time by %ds\n", time_adj); + } + // Iterate through waypoints in both tracks simultaneously + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wpt = (waypoint *) elem; + pres_alt = interpolate_alt(pres_track, wpt->creation_time + time_adj); + wr_fix_record(wpt, (int) pres_alt, (int) wpt->altitude); + } + } else { + if (pres_track) { + // Only the pressure altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint *) elem, (int)((waypoint *) elem)->altitude, (int) unknown_alt); + } + } else if (gnss_track) { + // Only the GNSS altitude track was found so generate fix + // records from it alone. + QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { + wr_fix_record((waypoint *) elem, (int) unknown_alt, (int)((waypoint *) elem)->altitude); + } } else { - if (pres_track) { - // Only the pressure altitude track was found so generate fix - // records from it alone. - QUEUE_FOR_EACH(&pres_track->waypoint_list, elem, tmp) { - wr_fix_record((waypoint *) elem, (int) ((waypoint *) elem)->altitude, (int) unknown_alt); - } - } else if (gnss_track) { - // Only the GNSS altitude track was found so generate fix - // records from it alone. - QUEUE_FOR_EACH(&gnss_track->waypoint_list, elem, tmp) { - wr_fix_record((waypoint *) elem, (int) unknown_alt, (int) ((waypoint *) elem)->altitude); - } - } else { - // No tracks found so nothing to do - return; - } + // No tracks found so nothing to do + return; } + } } static void wr_init(const char *fname) { - file_out = gbfopen(fname, "wb", MYNAME); + file_out = gbfopen(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void data_write(void) { - gbfputs("AXXXZZZGPSBabel\r\n", file_out); - wr_header(); - wr_tasks(); - wr_track(); - gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); - gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); + gbfputs("AXXXZZZGPSBabel\r\n", file_out); + wr_header(); + wr_tasks(); + wr_track(); + gbfprintf(file_out, "LXXXGenerated by GPSBabel Version %s\r\n", gpsbabel_version); + gbfputs("GGPSBabelSecurityRecordGuaranteedToFailVALIChecks\r\n", file_out); } static arglist_t igc_args[] = { - {"timeadj", &timeadj, - "(integer sec or 'auto') Barograph to GPS time diff", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "timeadj", &timeadj, + "(integer sec or 'auto') Barograph to GPS time diff", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t igc_vecs = { - ff_type_file, - { ff_cap_none , ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - igc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none , ff_cap_read | ff_cap_write, ff_cap_read | ff_cap_write }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + igc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/ignrando.c b/gpsbabel/ignrando.c index 58ab29bcc..ec1aff1bd 100644 --- a/gpsbabel/ignrando.c +++ b/gpsbabel/ignrando.c @@ -1,7 +1,7 @@ -/* +/* Support for IGN Rando track files. - + Copyright (C) 2005,2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -45,10 +45,9 @@ static int xmlpoints; /* options */ static char *index_opt = NULL; -static arglist_t ignr_args[] = -{ - {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t ignr_args[] = { + {"index", &index_opt, "Index of track to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; #if ! HAVE_LIBEXPAT @@ -56,7 +55,7 @@ static arglist_t ignr_args[] = static void ignr_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" input support because expat was not installed.\n"); } static void @@ -77,24 +76,24 @@ static xg_callback ignr_nb_etapes, ignr_descr; static xg_callback ignr_etape_begin, ignr_etape_end; static xg_callback ignr_etape_pos, ignr_etape_alt; -static -xg_tag_mapping ignr_xml_map[] = -{ - { ignr_start, cb_start, "/RANDONNEE" }, - { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, - { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, - { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, - { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, - { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, - { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, - { NULL, 0, NULL } +static +xg_tag_mapping ignr_xml_map[] = { + { ignr_start, cb_start, "/RANDONNEE" }, + { ignr_nb_etapes, cb_cdata, "/RANDONNEE/INFORMATIONS/NB_ETAPES" }, + { ignr_descr, cb_cdata, "/RANDONNEE/INFORMATIONS/DESCRIPTION" }, + { ignr_etape_begin, cb_start, "/RANDONNEE/ETAPE" }, + { ignr_etape_end, cb_end, "/RANDONNEE/ETAPE" }, + { ignr_etape_pos, cb_cdata, "/RANDONNEE/ETAPE/POSITION" }, + { ignr_etape_alt, cb_cdata, "/RANDONNEE/ETAPE/ALTITUDE" }, + { NULL, 0, NULL } }; static void ignr_xml_error(int condition) { - if (condition != 0) - fatal(MYNAME ": Error in XML structure!\n"); + if (condition != 0) { + fatal(MYNAME ": Error in XML structure!\n"); + } } /* xmlgeneric callbacks */ @@ -103,86 +102,91 @@ static xg_callback ignr_start; static xg_callback ignr_nb_etapes, ignr_descr; static xg_callback ignr_etape_begin, ignr_etape_end; -static void +static void ignr_start(const char *args, const char **attrv) { - ignr_xml_error((track != NULL)); - - track = route_head_alloc(); - track_add_head(track); + ignr_xml_error((track != NULL)); + + track = route_head_alloc(); + track_add_head(track); } -static void +static void ignr_nb_etapes(const char *args, const char **attrv) { - xmlpoints = atoi(args); + xmlpoints = atoi(args); } -static void +static void ignr_descr(const char *args, const char **attrv) { - ignr_xml_error((track == NULL)); + ignr_xml_error((track == NULL)); - if ((args != NULL) && (strlen(args) > 0)) - track->rte_desc = xstrdup(args); + if ((args != NULL) && (strlen(args) > 0)) { + track->rte_desc = xstrdup(args); + } } -static void +static void ignr_etape_begin(const char *args, const char **attrv) { - ignr_xml_error((wpt != NULL)); - - wpt = waypt_new(); + ignr_xml_error((wpt != NULL)); + + wpt = waypt_new(); } -static void +static void ignr_etape_end(const char *args, const char **attrv) { - ignr_xml_error((track == NULL) || (wpt == NULL)); - - track_add_wpt(track, wpt); - wpt = NULL; + ignr_xml_error((track == NULL) || (wpt == NULL)); + + track_add_wpt(track, wpt); + wpt = NULL; } static void ignr_etape_pos(const char *args, const char **attrv) { - ignr_xml_error((wpt == NULL) || (args == NULL)); + ignr_xml_error((wpt == NULL) || (args == NULL)); - if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) - fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); + if (2 != sscanf(args, "%lf,%lf", &wpt->latitude, &wpt->longitude)) { + fatal(MYNAME ": Invalid coordinates \"%s\"!\n", args); + } } static void ignr_etape_alt(const char *args, const char **attrv) { - ignr_xml_error((wpt == NULL)); - if (args == NULL) return; - - if (1 != sscanf(args, "%lf", &wpt->altitude)) - fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); + ignr_xml_error((wpt == NULL)); + if (args == NULL) { + return; + } + + if (1 != sscanf(args, "%lf", &wpt->altitude)) { + fatal(MYNAME ": Invalid altitude \"%s\"!\n", args); + } } /* callbacks registered in ignr_vecs */ -static void +static void ignr_rd_init(const char *fname) { - xml_init(fname, ignr_xml_map, NULL); - wpt = NULL; - track = NULL; + xml_init(fname, ignr_xml_map, NULL); + wpt = NULL; + track = NULL; } -static void +static void ignr_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } -static void +static void ignr_read(void) { - xml_read(); + xml_read(); } #endif @@ -191,30 +195,33 @@ ignr_read(void) /* callbacks registered in ignr_vecs */ -static void +static void ignr_rw_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } -static void +static void ignr_rw_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void ignr_write_track_hdr(const route_head *track) { - track_num++; - - if (track_num != track_index) return; - - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); - if (track->rte_desc != NULL) - gbfprintf(fout, "\t\t%s\n", track->rte_desc); - gbfprintf(fout, "\t\n"); + track_num++; + + if (track_num != track_index) { + return; + } + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%d\n", track->rte_waypt_ct); + if (track->rte_desc != NULL) { + gbfprintf(fout, "\t\t%s\n", track->rte_desc); + } + gbfprintf(fout, "\t\n"); } static void @@ -225,62 +232,64 @@ ignr_write_track_trl(const route_head *track) static void ignr_write_waypt(const waypoint *wpt) { - if (track_num != track_index) return; - - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); - if (wpt->altitude != unknown_alt) - gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); - gbfprintf(fout, "\t\n"); + if (track_num != track_index) { + return; + } + + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t%3.6f,%3.6f\n", wpt->latitude, wpt->longitude); + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, "\t\t%3.6f\n", wpt->altitude); + } + gbfprintf(fout, "\t\n"); } -static void +static void ignr_write(void) { - time_t now; - struct tm tm; - char buff[32]; - - if (index_opt != NULL) - { - track_index = atoi(index_opt); - if ((track_index < 1) || (track_index > (int) track_count())) - fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", - track_index, track_count()); - } - else - track_index = 1; - track_num = 0; - - now = current_time(); - tm = *localtime(&now); - - gbfprintf(fout, "\n"); - gbfprintf(fout, "\n"); - gbfprintf(fout, "\t\n"); - gbfprintf(fout, "\t\t1.1\n"); - gbfprintf(fout, "\t\tIHA03AA\n"); - - strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); - gbfprintf(fout, "\t\t%s\n", buff); - strftime(buff, sizeof(buff), "%H:%M:%S", &tm); - gbfprintf(fout, "\t\t%s\n", buff); - - gbfprintf(fout, "\t\n"); - track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); - gbfprintf(fout, "\n"); + time_t now; + struct tm tm; + char buff[32]; + + if (index_opt != NULL) { + track_index = atoi(index_opt); + if ((track_index < 1) || (track_index > (int) track_count())) + fatal(MYNAME ": Invalid track index %d (we have currently %d track(s))!\n", + track_index, track_count()); + } else { + track_index = 1; + } + track_num = 0; + + now = current_time(); + tm = *localtime(&now); + + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\t\n"); + gbfprintf(fout, "\t\t1.1\n"); + gbfprintf(fout, "\t\tIHA03AA\n"); + + strftime(buff, sizeof(buff), "%d/%m/%Y", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + strftime(buff, sizeof(buff), "%H:%M:%S", &tm); + gbfprintf(fout, "\t\t%s\n", buff); + + gbfprintf(fout, "\t\n"); + track_disp_all(ignr_write_track_hdr, ignr_write_track_trl, ignr_write_waypt); + gbfprintf(fout, "\n"); } ff_vecs_t ignr_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - ignr_rd_init, - ignr_rw_init, - ignr_rd_deinit, - ignr_rw_deinit, - ignr_read, - ignr_write, - NULL, - ignr_args, - CET_CHARSET_MS_ANSI, 1 + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + ignr_rd_init, + ignr_rw_init, + ignr_rd_deinit, + ignr_rw_deinit, + ignr_read, + ignr_write, + NULL, + ignr_args, + CET_CHARSET_MS_ANSI, 1 }; diff --git a/gpsbabel/igo8.c b/gpsbabel/igo8.c index 6bbcd4483..ab517fc94 100644 --- a/gpsbabel/igo8.c +++ b/gpsbabel/igo8.c @@ -29,14 +29,14 @@ | ID Block (20B) | | |------------------------------| | | | | - | | + | | | | H | | e | | a | Description Block (256B) | d | | e | | r - | | + | | | | | | | | | | | @@ -54,7 +54,7 @@ ID Block: defined by igo8_id_block Description Block: Two null-terminated unicode 2 strings. - The first is the title of the track, + The first is the title of the track, the second is the description. Information Block: defined by igo8_information_block Waypoint: defined by igo8_point @@ -71,27 +71,24 @@ #define IGO8_HEADER_SIZE (sizeof(igo8_id_block) + 256) #define MYNAME "IGO8" -typedef struct _igo8_id_block -{ - gbuint32 unknown_1; - gbuint32 unknown_2; - gbuint32 unknown_3; - gbuint32 track_number; - gbuint32 unknown_4; +typedef struct _igo8_id_block { + gbuint32 unknown_1; + gbuint32 unknown_2; + gbuint32 unknown_3; + gbuint32 track_number; + gbuint32 unknown_4; } igo8_id_block, *p_igo8_id_block; -typedef struct _igo8_information_block -{ - gbuint32 start_time; // In Unix time - gbuint32 zero; // Doesn't appear to serve a purpose - gbuint32 total_file_size; // In bytes +typedef struct _igo8_information_block { + gbuint32 start_time; // In Unix time + gbuint32 zero; // Doesn't appear to serve a purpose + gbuint32 total_file_size; // In bytes } igo8_information_block, *p_igo8_information_block; -typedef struct _igo8_point -{ - gbuint32 unix_time; - gbuint32 lon; - gbuint32 lat; +typedef struct _igo8_point { + gbuint32 unix_time; + gbuint32 lon; + gbuint32 lat; } igo8_point, *p_igo8_point; // Files @@ -110,182 +107,170 @@ static int in_point_count; // Exported options list static arglist_t igo8_options[] = { - { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { "tracknum", &igo8_option_tracknum, "Track identification number", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { "title", &igo8_option_title, "Track title", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "description", &igo8_option_description, "Track description", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; // Sanity check static void igo8_check_type_sizes() { - if (sizeof(igo8_point) != 12) - { - fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n", - (long) sizeof(igo8_point)); - } - - if (sizeof(igo8_information_block) != 12) - { - fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n", - (long) sizeof(igo8_information_block)); - } - - if (sizeof(igo8_id_block) != 20) - { - fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n", - (long) sizeof(igo8_id_block)); - } + if (sizeof(igo8_point) != 12) { + fatal(MYNAME ": igo8_point is %ld bytes instead of the required 12.\n", + (long) sizeof(igo8_point)); + } + + if (sizeof(igo8_information_block) != 12) { + fatal(MYNAME ": igo8_information_block is %ld bytes instead of the required 12.\n", + (long) sizeof(igo8_information_block)); + } + + if (sizeof(igo8_id_block) != 20) { + fatal(MYNAME ": igo8_id_block is %ld bytes instead of the required 20.\n", + (long) sizeof(igo8_id_block)); + } } // Reader initialization callback static void igo8_read_init(const char *fname) { - igo8_file_in = gbfopen_le(fname, "rb", MYNAME); - - // Make sure that we are in the environment we expect and require - igo8_check_type_sizes(); - - // Seek past the header and most of the Information Block. Read - // the last word for trackpoint count since latest igo8 seems to - // zero-pad the files. - gbfseek(igo8_file_in, IGO8_HEADER_SIZE + sizeof(igo8_information_block) - 4, SEEK_SET); - in_point_count = (gbfgetint32(igo8_file_in) - IGO8_HEADER_SIZE - - sizeof(igo8_information_block)) / sizeof(igo8_point); + igo8_file_in = gbfopen_le(fname, "rb", MYNAME); + + // Make sure that we are in the environment we expect and require + igo8_check_type_sizes(); + + // Seek past the header and most of the Information Block. Read + // the last word for trackpoint count since latest igo8 seems to + // zero-pad the files. + gbfseek(igo8_file_in, IGO8_HEADER_SIZE + sizeof(igo8_information_block) - 4, SEEK_SET); + in_point_count = (gbfgetint32(igo8_file_in) - IGO8_HEADER_SIZE - + sizeof(igo8_information_block)) / sizeof(igo8_point); } // Reader callback static void igo8_read(void) { - waypoint *wpt_tmp; - route_head *track_head; - igo8_point point; + waypoint *wpt_tmp; + route_head *track_head; + igo8_point point; - track_head = route_head_alloc(); - track_add_head(track_head); + track_head = route_head_alloc(); + track_add_head(track_head); - while (in_point_count && - gbfread(&point, sizeof(point), 1, igo8_file_in) > 0) { - in_point_count--; - wpt_tmp = waypt_new(); + while (in_point_count && + gbfread(&point, sizeof(point), 1, igo8_file_in) > 0) { + in_point_count--; + wpt_tmp = waypt_new(); - wpt_tmp->latitude = le_read32(&point.lat) / (double)0x800000; - wpt_tmp->longitude = le_read32(&point.lon) / (double)0x800000; - wpt_tmp->creation_time = le_read32(&point.unix_time); + wpt_tmp->latitude = le_read32(&point.lat) / (double)0x800000; + wpt_tmp->longitude = le_read32(&point.lon) / (double)0x800000; + wpt_tmp->creation_time = le_read32(&point.unix_time); - track_add_wpt(track_head, wpt_tmp); - } + track_add_wpt(track_head, wpt_tmp); + } } // Reader close callback static void igo8_read_deinit(void) { - gbfclose(igo8_file_in); + gbfclose(igo8_file_in); } // Writer initialize callback static void igo8_write_init(const char *fname) { - igo8_file_out = gbfopen_le(fname, "wb", MYNAME); + igo8_file_out = gbfopen_le(fname, "wb", MYNAME); - igo8_check_type_sizes(); + igo8_check_type_sizes(); - invented_time = 1; - point_count = 0; + invented_time = 1; + point_count = 0; } // Writer close callback static void igo8_write_deinit(void) { - gbuint32 normalized_file_size; + gbuint32 normalized_file_size; - // Seek to the start of the third long in the Information Block, this is - // where we will write out the total size of the file. - gbfseek(igo8_file_out, IGO8_HEADER_SIZE + sizeof(gbuint32)*2, SEEK_SET); + // Seek to the start of the third long in the Information Block, this is + // where we will write out the total size of the file. + gbfseek(igo8_file_out, IGO8_HEADER_SIZE + sizeof(gbuint32)*2, SEEK_SET); - // The total size of the file is the number of points written + Information block + Header - le_write32(&normalized_file_size, sizeof(igo8_point)*(point_count) + sizeof(igo8_information_block) + IGO8_HEADER_SIZE); + // The total size of the file is the number of points written + Information block + Header + le_write32(&normalized_file_size, sizeof(igo8_point)*(point_count) + sizeof(igo8_information_block) + IGO8_HEADER_SIZE); - // Write the size - gbfwrite(&normalized_file_size, sizeof(normalized_file_size), 1, igo8_file_out); + // Write the size + gbfwrite(&normalized_file_size, sizeof(normalized_file_size), 1, igo8_file_out); - gbfclose(igo8_file_out); + gbfclose(igo8_file_out); } // Write point callback static void write_igo8_track_point(const waypoint *wpt) { - igo8_point point; - - memset(&point, 0, sizeof(point)); - - // iGo8 appears to expect a time, if one isn't provided - // then we shall make our own, where each point is one - // second apart. - if (wpt->creation_time == 0) - { - le_write32(&point.unix_time, invented_time++); - } - else - { - le_write32(&point.unix_time, wpt->creation_time); - } - - // Write the first part of the Information Block, the start time - if (point_count == 0) - { - gbfwrite(&point, sizeof(point), 1, igo8_file_out); - } - - le_write32(&point.lon, FLOAT_TO_INT(wpt->longitude * 0x800000)); - le_write32(&point.lat, FLOAT_TO_INT(wpt->latitude * 0x800000)); - - gbfwrite(&point, sizeof(point), 1, igo8_file_out); - - // Count the number of point printed, we will use this at the end to - // finish filling out the Information Block. - point_count++; + igo8_point point; + + memset(&point, 0, sizeof(point)); + + // iGo8 appears to expect a time, if one isn't provided + // then we shall make our own, where each point is one + // second apart. + if (wpt->creation_time == 0) { + le_write32(&point.unix_time, invented_time++); + } else { + le_write32(&point.unix_time, wpt->creation_time); + } + + // Write the first part of the Information Block, the start time + if (point_count == 0) { + gbfwrite(&point, sizeof(point), 1, igo8_file_out); + } + + le_write32(&point.lon, FLOAT_TO_INT(wpt->longitude * 0x800000)); + le_write32(&point.lat, FLOAT_TO_INT(wpt->latitude * 0x800000)); + + gbfwrite(&point, sizeof(point), 1, igo8_file_out); + + // Count the number of point printed, we will use this at the end to + // finish filling out the Information Block. + point_count++; } // Write src unicode str to the dst cstring using unicode characters // All lengths are in bytes unsigned int print_unicode(char *dst, const unsigned int dst_max_length, short *src, unsigned int src_len) { - // Check to see what length we were passed, if the length doesn't include the null - // then we make it include the null - if (src[(src_len/2) - 1] != 0) - { - // If the last character isn't null check the next one - if (src[(src_len/2)] != 0) - { - // If the next character also inst' null, make it null - src[(src_len/2)] = 0; - } - else - { - // The next character is null, adjust the total length of the str to account for this - src_len += 2; - } - } - - // Make sure we fit in our dst size - if (src_len > dst_max_length) - { - src_len = dst_max_length; - src[(src_len/2) - 1] = 0; // Make sure we keep that terminating null around - } - - // Copy the str - memcpy(dst, src, src_len); - - return src_len; + // Check to see what length we were passed, if the length doesn't include the null + // then we make it include the null + if (src[(src_len/2) - 1] != 0) { + // If the last character isn't null check the next one + if (src[(src_len/2)] != 0) { + // If the next character also inst' null, make it null + src[(src_len/2)] = 0; + } else { + // The next character is null, adjust the total length of the str to account for this + src_len += 2; + } + } + + // Make sure we fit in our dst size + if (src_len > dst_max_length) { + src_len = dst_max_length; + src[(src_len/2) - 1] = 0; // Make sure we keep that terminating null around + } + + // Copy the str + memcpy(dst, src, src_len); + + return src_len; } // This is a sort of hacked together ascii-> unicode 2 converter. I have no idea // if iGo8 even supports real unicode 2, but is does look like it as every ascii // character is a short with the ascii character as the least significant 7 bits // -// Please replace this with a much more filled out and correct version if you see +// Please replace this with a much more filled out and correct version if you see // fit. /* 2008/06/24, O.K.: Use CET library for ascii-> unicode 2 converter */ @@ -295,97 +280,92 @@ unsigned int print_unicode(char *dst, const unsigned int dst_max_length, short * unsigned int ascii_to_unicode_2(char *dst, const unsigned int dst_max_length, const char *src) { - short *unicode; - int len; + short *unicode; + int len; + + unicode = cet_str_any_to_uni(src, &cet_cs_vec_ansi_x3_4_1968, &len); - unicode = cet_str_any_to_uni(src, &cet_cs_vec_ansi_x3_4_1968, &len); + len *= 2; /* real size in bytes */ + len = print_unicode(dst, dst_max_length, unicode, len); - len *= 2; /* real size in bytes */ - len = print_unicode(dst, dst_max_length, unicode, len); + xfree(unicode); - xfree(unicode); - - return len; + return len; } void write_header() { - char header[IGO8_HEADER_SIZE] = {'\0'}; - igo8_id_block tmp_id_block; - p_igo8_id_block id_block = (p_igo8_id_block)header; - gbuint32 current_position = 0; - const char* title = "Title"; - const char* description = "Description"; - - // These values seem to be constant for me, but I have no idea what they are. - tmp_id_block.unknown_1 = 0x0000029B; - tmp_id_block.unknown_2 = 0x000003E7; - tmp_id_block.unknown_3 = 0x00000003; - - // This appears to be a unique number that IDs the track. - // It is mono-incrementing and offset by 2 above the track number. - // e.g. "Track 1" --> track_number = 3 - // XXX - Dustin: My guess is that this number is used as the key for the track color, if - // XXX - Dustin: multiple tracks have the same color they will be colored the same, just - // XXX - Dustin: a guess though. - if (igo8_option_tracknum) - { - tmp_id_block.track_number = atoi(igo8_option_tracknum); - } - else - { - tmp_id_block.track_number = 0x00000010; - } - tmp_id_block.unknown_4 = 0x00000001; - - // Byte swap out to the header buffer. - le_write32(&id_block->unknown_1, tmp_id_block.unknown_1); - le_write32(&id_block->unknown_2, tmp_id_block.unknown_2); - le_write32(&id_block->unknown_3, tmp_id_block.unknown_3); - le_write32(&id_block->track_number, tmp_id_block.track_number); - le_write32(&id_block->unknown_4, tmp_id_block.unknown_4); - - // Move past the ID block, we have just filled it. - current_position += sizeof(*id_block); - - // Set the title of the track - // Note: we shorten the length of the potential title by 2 because we need to leave at - // least enough room to have a null for the description string that follows it. - if (igo8_option_title) - { - title = igo8_option_title; - } - current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position - 2, title); - - // Set the description of the track - if (igo8_option_description) - { - description = igo8_option_description; - } - current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position, description); - - gbfwrite(&header, IGO8_HEADER_SIZE, 1, igo8_file_out); + char header[IGO8_HEADER_SIZE] = {'\0'}; + igo8_id_block tmp_id_block; + p_igo8_id_block id_block = (p_igo8_id_block)header; + gbuint32 current_position = 0; + const char* title = "Title"; + const char* description = "Description"; + + // These values seem to be constant for me, but I have no idea what they are. + tmp_id_block.unknown_1 = 0x0000029B; + tmp_id_block.unknown_2 = 0x000003E7; + tmp_id_block.unknown_3 = 0x00000003; + + // This appears to be a unique number that IDs the track. + // It is mono-incrementing and offset by 2 above the track number. + // e.g. "Track 1" --> track_number = 3 + // XXX - Dustin: My guess is that this number is used as the key for the track color, if + // XXX - Dustin: multiple tracks have the same color they will be colored the same, just + // XXX - Dustin: a guess though. + if (igo8_option_tracknum) { + tmp_id_block.track_number = atoi(igo8_option_tracknum); + } else { + tmp_id_block.track_number = 0x00000010; + } + tmp_id_block.unknown_4 = 0x00000001; + + // Byte swap out to the header buffer. + le_write32(&id_block->unknown_1, tmp_id_block.unknown_1); + le_write32(&id_block->unknown_2, tmp_id_block.unknown_2); + le_write32(&id_block->unknown_3, tmp_id_block.unknown_3); + le_write32(&id_block->track_number, tmp_id_block.track_number); + le_write32(&id_block->unknown_4, tmp_id_block.unknown_4); + + // Move past the ID block, we have just filled it. + current_position += sizeof(*id_block); + + // Set the title of the track + // Note: we shorten the length of the potential title by 2 because we need to leave at + // least enough room to have a null for the description string that follows it. + if (igo8_option_title) { + title = igo8_option_title; + } + current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position - 2, title); + + // Set the description of the track + if (igo8_option_description) { + description = igo8_option_description; + } + current_position += ascii_to_unicode_2((char*)(header+current_position), IGO8_HEADER_SIZE - current_position, description); + + gbfwrite(&header, IGO8_HEADER_SIZE, 1, igo8_file_out); } // Writer callback static void igo8_write(void) { - write_header(); - track_disp_all(NULL, NULL, write_igo8_track_point); + write_header(); + track_disp_all(NULL, NULL, write_igo8_track_point); } // Callback definitions ff_vecs_t igo8_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, - igo8_read_init, - igo8_write_init, - igo8_read_deinit, - igo8_write_deinit, - igo8_read, - igo8_write, - NULL, - igo8_options, - CET_CHARSET_UTF8, - 1 + ff_type_file, + { ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none }, + igo8_read_init, + igo8_write_init, + igo8_read_deinit, + igo8_write_deinit, + igo8_read, + igo8_write, + NULL, + igo8_options, + CET_CHARSET_UTF8, + 1 }; diff --git a/gpsbabel/ik3d.c b/gpsbabel/ik3d.c index 9a5c50c45..64b64dcb2 100644 --- a/gpsbabel/ik3d.c +++ b/gpsbabel/ik3d.c @@ -1,4 +1,4 @@ -/* +/* Support for "MagicMaps" project files (.ikt) @@ -23,9 +23,8 @@ #include "defs.h" #include "xmlgeneric.h" -static arglist_t ikt_args[] = -{ - ARG_TERMINATOR +static arglist_t ikt_args[] = { + ARG_TERMINATOR }; #define MYNAME "ikt" @@ -36,7 +35,7 @@ static char *name, *text; void ikt_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); } void @@ -61,142 +60,151 @@ static xg_callback iktobj_waypt, iktobj_type, iktobj_name, iktobj_trkpt, iktobj_ /* Here we are working with wildcards in the tag list. Please ensure that the longest entries comes first */ -static +static xg_tag_mapping ikt_map[] = { - { iktobj_trkpt, cb_start, IKTOBJ "_*/PathPoints/Point_*/GeoPosition" }, - { iktobj_type, cb_cdata, IKTOBJ "_*/GeoObjectType" }, - { iktobj_waypt, cb_start, IKTOBJ "_*/GeoPosition" }, - { iktobj_name, cb_cdata, IKTOBJ "_*/Name" }, - { iktobj_text, cb_cdata, IKTOBJ "_*/POIDrawable2D/Text" }, - { NULL, 0, NULL } + { iktobj_trkpt, cb_start, IKTOBJ "_*/PathPoints/Point_*/GeoPosition" }, + { iktobj_type, cb_cdata, IKTOBJ "_*/GeoObjectType" }, + { iktobj_waypt, cb_start, IKTOBJ "_*/GeoPosition" }, + { iktobj_name, cb_cdata, IKTOBJ "_*/Name" }, + { iktobj_text, cb_cdata, IKTOBJ "_*/POIDrawable2D/Text" }, + { NULL, 0, NULL } }; static void ikt_object_end(void) { - if (track) { - track->rte_name = name; - track_add_head(track); - name = NULL; - } - else if (waypt) { - waypt->shortname = name; - waypt->description = text; - waypt_add(waypt); - name = NULL; - text = NULL; - } - if (name) { - xfree(name); - name = NULL; - } - if (text) { - xfree(text); - text = NULL; - } - track = NULL; - waypt = NULL; + if (track) { + track->rte_name = name; + track_add_head(track); + name = NULL; + } else if (waypt) { + waypt->shortname = name; + waypt->description = text; + waypt_add(waypt); + name = NULL; + text = NULL; + } + if (name) { + xfree(name); + name = NULL; + } + if (text) { + xfree(text); + text = NULL; + } + track = NULL; + waypt = NULL; } -static void +static void iktobj_waypt(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); - avp+=2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "X") == 0) { + waypt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "Y") == 0) { + waypt->latitude = atof(avp[1]); + } + avp+=2; + } } static void iktobj_trkpt(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - waypt = waypt_new(); - while (*avp) { - if (strcmp(avp[0], "X") == 0) waypt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "Y") == 0) waypt->latitude = atof(avp[1]); - avp+=2; - } - track_add_wpt(track, waypt); - waypt = NULL; + const char **avp = &attrv[0]; + + waypt = waypt_new(); + while (*avp) { + if (strcmp(avp[0], "X") == 0) { + waypt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "Y") == 0) { + waypt->latitude = atof(avp[1]); + } + avp+=2; + } + track_add_wpt(track, waypt); + waypt = NULL; } -static void +static void iktobj_name(const char *args, const char **unused) { - name = xstrdup(args); + name = xstrdup(args); } -static void +static void iktobj_text(const char *args, const char **unused) { - text = xstrdup(args); + text = xstrdup(args); } -static void +static void iktobj_type(const char *args, const char **unused) { - ikt_object_end(); - - switch(atoi(args)) { - case 0: - waypt = waypt_new(); - break; - case 1: - track = route_head_alloc(); - break; - default: - fatal(MYNAME ": Unknown object type %s!\n", args); - } + ikt_object_end(); + + switch (atoi(args)) { + case 0: + waypt = waypt_new(); + break; + case 1: + track = route_head_alloc(); + break; + default: + fatal(MYNAME ": Unknown object type %s!\n", args); + } } -static void +static void ikt_rd_init(const char *fname) { - xml_init(fname, ikt_map, NULL); - - track = NULL; - waypt = NULL; - name = NULL; - text = NULL; + xml_init(fname, ikt_map, NULL); + + track = NULL; + waypt = NULL; + name = NULL; + text = NULL; } -static void +static void ikt_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void ikt_rd_deinit(void) { - ikt_object_end(); - if (name) xfree(name); - if (text) xfree(text); - - xml_deinit(); + ikt_object_end(); + if (name) { + xfree(name); + } + if (text) { + xfree(text); + } + + xml_deinit(); } ff_vecs_t ik3d_vecs = { - ff_type_file, - { - ff_cap_read, /* waypoints */ - ff_cap_read, /* tracks */ - ff_cap_none /* routes */ - }, - ikt_rd_init, - NULL, - ikt_rd_deinit, - NULL, - ikt_read, - NULL, - NULL, - ikt_args, - CET_CHARSET_UTF8, 1 + ff_type_file, + { + ff_cap_read, /* waypoints */ + ff_cap_read, /* tracks */ + ff_cap_none /* routes */ + }, + ikt_rd_init, + NULL, + ikt_rd_deinit, + NULL, + ikt_read, + NULL, + NULL, + ikt_args, + CET_CHARSET_UTF8, 1 }; diff --git a/gpsbabel/inifile.c b/gpsbabel/inifile.c index bc8ed9148..59e802e03 100644 --- a/gpsbabel/inifile.c +++ b/gpsbabel/inifile.c @@ -1,6 +1,6 @@ /* Library for inifile like data files. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -28,19 +28,17 @@ #define MYNAME "inifile" -typedef struct inifile_entry_s -{ - queue Q; - char *key; - char *val; +typedef struct inifile_entry_s { + queue Q; + char *key; + char *val; } inifile_entry_t; -typedef struct inifile_section_s -{ - queue Q; - char *name; - int ientries; - queue entries; +typedef struct inifile_section_s { + queue Q; + char *name; + int ientries; + queue entries; } inifile_section_t; /* internal procedures */ @@ -56,179 +54,190 @@ char *gbinipathname; static char * find_gpsbabel_inifile(const char *path) /* can be empty or NULL */ { - FILE *test; - char *buff; - int len; - - if (path == NULL) return NULL; - - len = strlen(path); - buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); - strcpy(buff, path); - if (len > 0) { - char test = buff[len - 1]; + FILE *test; + char *buff; + int len; + + if (path == NULL) { + return NULL; + } + + len = strlen(path); + buff = xmalloc(len + 1 + strlen(GPSBABEL_INIFILE) + 1); + strcpy(buff, path); + if (len > 0) { + char test = buff[len - 1]; #ifdef __WIN32__ - if ((test != '\\') && (test != ':')) - strcat(buff, "\\"); + if ((test != '\\') && (test != ':')) { + strcat(buff, "\\"); + } #else - if (test != '/') - strcat(buff, "/"); + if (test != '/') { + strcat(buff, "/"); + } #endif - } - strcat(buff, GPSBABEL_INIFILE); - test = fopen(buff, "rb"); - if (test) { - fclose(test); - return buff; - } - xfree(buff); - return NULL; + } + strcat(buff, GPSBABEL_INIFILE); + test = fopen(buff, "rb"); + if (test) { + fclose(test); + return buff; + } + xfree(buff); + return NULL; } static gbfile * open_gpsbabel_inifile(void) { - char *name; - char *envstr; - gbfile *res = NULL; - - envstr = getenv("GPSBABELINI"); - if (envstr != NULL) { - FILE *test; - - test = fopen(envstr, "r"); - if (test != NULL) { - fclose(test); - return gbfopen(envstr, "r", "GPSBabel"); - } - warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); - return NULL; - } - name = find_gpsbabel_inifile(""); /* PWD */ - if (name == NULL) { + char *name; + char *envstr; + gbfile *res = NULL; + + envstr = getenv("GPSBABELINI"); + if (envstr != NULL) { + FILE *test; + + test = fopen(envstr, "r"); + if (test != NULL) { + fclose(test); + return gbfopen(envstr, "r", "GPSBabel"); + } + warning("WARNING: GPSBabel-inifile, defined in environment, NOT found!\n"); + return NULL; + } + name = find_gpsbabel_inifile(""); /* PWD */ + if (name == NULL) { #ifdef __WIN32__ - name = find_gpsbabel_inifile(getenv("APPDATA")); - if (name == NULL) name = find_gpsbabel_inifile(getenv("WINDIR")); - if (name == NULL) name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); + name = find_gpsbabel_inifile(getenv("APPDATA")); + if (name == NULL) { + name = find_gpsbabel_inifile(getenv("WINDIR")); + } + if (name == NULL) { + name = find_gpsbabel_inifile(getenv("SYSTEMROOT")); + } #else - if ((envstr = getenv("HOME")) != NULL) { - char *path; - - path = xmalloc(strlen(envstr) + 11); - strcpy(path, envstr); - strcat(path, "/.gpsbabel"); - name = find_gpsbabel_inifile(path); - xfree(path); - } - if (name == NULL) name = find_gpsbabel_inifile("/usr/local/etc"); - if (name == NULL) name = find_gpsbabel_inifile("/etc"); + if ((envstr = getenv("HOME")) != NULL) { + char *path; + + path = xmalloc(strlen(envstr) + 11); + strcpy(path, envstr); + strcat(path, "/.gpsbabel"); + name = find_gpsbabel_inifile(path); + xfree(path); + } + if (name == NULL) { + name = find_gpsbabel_inifile("/usr/local/etc"); + } + if (name == NULL) { + name = find_gpsbabel_inifile("/etc"); + } #endif - } - if (name != NULL) { - res = gbfopen(name, "r", "GPSBabel"); - if (gbinipathname) { - xfree(gbinipathname); - } - gbinipathname = name; - } - return res; + } + if (name != NULL) { + res = gbfopen(name, "r", "GPSBabel"); + if (gbinipathname) { + xfree(gbinipathname); + } + gbinipathname = name; + } + return res; } static void inifile_load_file(gbfile *fin, inifile_t *inifile, const char *myname) { - char *buf; - inifile_section_t *sec = NULL; - int line = 0; - - while ((buf = gbfgetstr(fin))) - { - char *cin = lrtrim(buf); - - if ((line++ == 0) && fin->unicode) inifile->unicode = 1; - - if (*cin == '\0') continue; /* skip empty lines */ - if ((*cin == '#') || (*cin == ';')) continue; /* skip comments */ - - if (*cin == '[') - { - - char *cend = strchr(++cin, ']'); - - if (cend != NULL) - { - *cend = '\0'; - cin = lrtrim(cin); - } - if ((*cin == '\0') || (cend == NULL)) - fatal("%s: invalid section header '%s' in '%s'.\n", myname, cin, gbinipathname); - - sec = (inifile_section_t *) xcalloc(1, sizeof(*sec)); - - sec->name = xstrdup(cin); - QUEUE_INIT(&sec->entries); - ENQUEUE_TAIL(&inifile->secs, &sec->Q); - inifile->isecs++; - } - else - { - char *cx; - inifile_entry_t *entry; - - if (sec == NULL) - fatal("%s: missing section header in '%s'.\n", myname,gbinipathname); - - entry = (inifile_entry_t *) xcalloc(1, sizeof(*entry)); - ENQUEUE_TAIL(&sec->entries, &entry->Q); - sec->ientries++; - - cx = strchr(cin, '='); - if (cx != NULL) - { - *cx = '\0'; - cin = lrtrim(cin); - } - - entry->key = xstrdup(cin); - - if (cx != NULL) - { - cx = lrtrim(++cx); - entry->val = xstrdup(cx); - } - else - entry->val = xstrdup(""); - } - } + char *buf; + inifile_section_t *sec = NULL; + int line = 0; + + while ((buf = gbfgetstr(fin))) { + char *cin = lrtrim(buf); + + if ((line++ == 0) && fin->unicode) { + inifile->unicode = 1; + } + + if (*cin == '\0') { + continue; /* skip empty lines */ + } + if ((*cin == '#') || (*cin == ';')) { + continue; /* skip comments */ + } + + if (*cin == '[') { + + char *cend = strchr(++cin, ']'); + + if (cend != NULL) { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) { + fatal("%s: invalid section header '%s' in '%s'.\n", myname, cin, gbinipathname); + } + + sec = (inifile_section_t *) xcalloc(1, sizeof(*sec)); + + sec->name = xstrdup(cin); + QUEUE_INIT(&sec->entries); + ENQUEUE_TAIL(&inifile->secs, &sec->Q); + inifile->isecs++; + } else { + char *cx; + inifile_entry_t *entry; + + if (sec == NULL) { + fatal("%s: missing section header in '%s'.\n", myname,gbinipathname); + } + + entry = (inifile_entry_t *) xcalloc(1, sizeof(*entry)); + ENQUEUE_TAIL(&sec->entries, &entry->Q); + sec->ientries++; + + cx = strchr(cin, '='); + if (cx != NULL) { + *cx = '\0'; + cin = lrtrim(cin); + } + + entry->key = xstrdup(cin); + + if (cx != NULL) { + cx = lrtrim(++cx); + entry->val = xstrdup(cx); + } else { + entry->val = xstrdup(""); + } + } + } } static char * inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *key) { - queue *elem, *tmp; - - if (inifile == NULL) return NULL; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) - { - inifile_section_t *sec = (inifile_section_t *) elem; - - if (case_ignore_strcmp(sec->name, sec_name) == 0) - { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&sec->entries, elem, tmp) - { - inifile_entry_t *entry = (inifile_entry_t *) elem; - - if (case_ignore_strcmp(entry->key, key) == 0) - { - return entry->val; - } - } - } - } - return NULL; + queue *elem, *tmp; + + if (inifile == NULL) { + return NULL; + } + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (case_ignore_strcmp(sec->name, sec_name) == 0) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (case_ignore_strcmp(entry->key, key) == 0) { + return entry->val; + } + } + } + } + return NULL; } /* public procedures */ @@ -237,112 +246,122 @@ inifile_find_value(const inifile_t *inifile, const char *sec_name, const char *k inifile_init: reads inifile filename into memory myname represents the calling module - + filename == NULL: try to open global gpsbabel.ini */ inifile_t * inifile_init(const char *filename, const char *myname) { - inifile_t *result; - gbfile *fin = NULL; - - if (filename == NULL) { - fin = open_gpsbabel_inifile(); - if (fin == NULL) return NULL; - } - else fin = gbfopen(filename, "rb", myname); - - result = (inifile_t *) xcalloc(1, sizeof(*result)); - QUEUE_INIT(&result->secs); - inifile_load_file(fin, result, myname); - - gbfclose(fin); - return result; + inifile_t *result; + gbfile *fin = NULL; + + if (filename == NULL) { + fin = open_gpsbabel_inifile(); + if (fin == NULL) { + return NULL; + } + } else { + fin = gbfopen(filename, "rb", myname); + } + + result = (inifile_t *) xcalloc(1, sizeof(*result)); + QUEUE_INIT(&result->secs); + inifile_load_file(fin, result, myname); + + gbfclose(fin); + return result; } void inifile_done(inifile_t *inifile) { - if (inifile == NULL) return; - - if (inifile->isecs > 0) - { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { - inifile_section_t *sec = (inifile_section_t *) elem; - - if (sec->ientries > 0) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&sec->entries, elem, tmp) { - inifile_entry_t *entry = (inifile_entry_t *) elem; - - if (entry->key) xfree(entry->key); - if (entry->val) xfree(entry->val); - dequeue(elem); - xfree(entry); - } - } - dequeue(elem); - if (sec->name) xfree(sec->name); - xfree(sec); - } - xfree(inifile); - } - if (gbinipathname) { - xfree(gbinipathname); - gbinipathname = NULL; - } + if (inifile == NULL) { + return; + } + + if (inifile->isecs > 0) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t *sec = (inifile_section_t *) elem; + + if (sec->ientries > 0) { + queue *elem, *tmp; + + QUEUE_FOR_EACH(&sec->entries, elem, tmp) { + inifile_entry_t *entry = (inifile_entry_t *) elem; + + if (entry->key) { + xfree(entry->key); + } + if (entry->val) { + xfree(entry->val); + } + dequeue(elem); + xfree(entry); + } + } + dequeue(elem); + if (sec->name) { + xfree(sec->name); + } + xfree(sec); + } + xfree(inifile); + } + if (gbinipathname) { + xfree(gbinipathname); + gbinipathname = NULL; + } } -int +int inifile_has_section(const inifile_t *inifile, const char *section) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&inifile->secs, elem, tmp) - { - inifile_section_t *sec = (inifile_section_t *) elem; - if (case_ignore_strcmp(sec->name, section) == 0) - return 1; - } - return 0; + queue *elem, *tmp; + + QUEUE_FOR_EACH(&inifile->secs, elem, tmp) { + inifile_section_t *sec = (inifile_section_t *) elem; + if (case_ignore_strcmp(sec->name, section) == 0) { + return 1; + } + } + return 0; } -/* +/* inifile_readstr: returns NULL if not found, otherwise a pointer to the value of key ... - all key values are valid entities until "inifile_done" + all key values are valid entities until "inifile_done" */ char * inifile_readstr(const inifile_t *inifile, const char *section, const char *key) { - return inifile_find_value(inifile, section, key); + return inifile_find_value(inifile, section, key); } -/* +/* inifile_readint: on success the value is stored into "*value" and "inifile_readint" returns 1, otherwise inifile_readint returns 0 */ - -int + +int inifile_readint(const inifile_t *inifile, const char *section, const char *key, int *value) { - char *str; - - str = inifile_find_value(inifile, section, key); - - if (str == NULL) { - return 0; - } - - if (value != NULL) { - *value = atoi(str); - } - return 1; + char *str; + + str = inifile_find_value(inifile, section, key); + + if (str == NULL) { + return 0; + } + + if (value != NULL) { + *value = atoi(str); + } + return 1; } /* @@ -350,15 +369,14 @@ inifile_readint(const inifile_t *inifile, const char *section, const char *key, if found inifile_readint_def returns value of key, otherwise a default value "def" */ -int +int inifile_readint_def(const inifile_t *inifile, const char *section, const char *key, const int def) { - int result; - - if (inifile_readint(inifile, section, key, &result) == 0) { - return def; - } - else { - return result; - } + int result; + + if (inifile_readint(inifile, section, key, &result) == 0) { + return def; + } else { + return result; + } } diff --git a/gpsbabel/inifile.h b/gpsbabel/inifile.h index e7fc8289f..1b7ccddee 100644 --- a/gpsbabel/inifile.h +++ b/gpsbabel/inifile.h @@ -23,11 +23,10 @@ #include "defs.h" -typedef struct inifile_s -{ - int isecs; /* number of sections */ - queue secs; /* sections */ - gbuint8 unicode:1; +typedef struct inifile_s { + int isecs; /* number of sections */ + queue secs; /* sections */ + gbuint8 unicode:1; } inifile_t; /* @@ -40,14 +39,14 @@ void inifile_done(inifile_t *inifile); int inifile_has_section(const inifile_t *inifile, const char *section); -/* +/* inifile_readstr: returns NULL if not found, otherwise a pointer to the value of key ... - all key values are valid entities until "inifile_done" + all key values are valid entities until "inifile_done" */ char *inifile_readstr(const inifile_t *inifile, const char *section, const char *key); -/* +/* inifile_readint: on success the value is stored into "*value" and "inifile_readint" returns 1, otherwise inifile_readint returns 0 diff --git a/gpsbabel/internal_styles.c b/gpsbabel/internal_styles.c index acd527324..5eab6e386 100644 --- a/gpsbabel/internal_styles.c +++ b/gpsbabel/internal_styles.c @@ -3,1322 +3,1322 @@ #include "defs.h" #if CSVFMTS_ENABLED -static char arc[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: GPSBabel arc filter format\n" -"# Author: Ron Parker\n" -"# Date: 17 July 2003\n" -"#\n" - -"DESCRIPTION GPSBabel arc filter file\n" -"EXTENSION txt\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" - -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -; -static char cambridge[] = -"DESCRIPTION Cambridge/Winpilot glider software\n" -"SHORTLEN 8\n" -"EXTENSION dat\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"IFIELD INDEX,\"1\",\"%d\"\n" -"IFIELD LAT_HUMAN_READABLE,\"\",\"%d:%06.3f%c\"\n" -"IFIELD LON_HUMAN_READABLE,\"\",\"%03d:%06.3f%c\"\n" -"IFIELD ALT_METERS,\"\",\"%3.0fM\"\n" -"IFIELD CONSTANT,\"\",\"T\"\n" -"IFIELD SHORTNAME,\"\",\"%s\"\n" -"IFIELD DESCRIPTION,\"\",\"%s\"\n" -; -static char csv[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: DeLorme SA 9.0 CSV\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"DESCRIPTION Comma separated values\n" -"SHORTLEN 8\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMASPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" - -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD DESCRIPTION, \"\", \"%s\"\n" -; -static char cup[] = -"#\n" -"# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas\n" -"# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf\n" -"#\n" - -"DESCRIPTION See You flight analysis data\n" -"SHORTLEN 8\n" -"EXTENSION cup\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" -"PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc\n" -"EPILOGUE -----Related Tasks-----\n" - - -"IFIELD SHORTNAME,\"\", \"\"%s\"\"\n" -"IFIELD SHORTNAME,\"\", \"%s\"\n" -"IFIELD CONSTANT,\"\", \"\"\n" -"IFIELD LAT_DDMMDIR, \"%f\", \"%08.3f\", \"absolute\"\n" -"IFIELD LON_DDMMDIR, \"%f\", \"%09.3f\", \"absolute\"\n" -"IFIELD ALT_METERS,\"\", \"%dm\"\n" -"IFIELD CONSTANT,\"\", \"1\"\n" -"IFIELD CONSTANT,\"\", \"\"\n" -"IFIELD CONSTANT,\"\", \"\"\n" -"IFIELD CONSTANT,\"\", \"\"\n" -"IFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" - -"OFIELD SHORTNAME,\"\", \"\"%s\"\"\n" -"OFIELD SHORTNAME,\"\", \"%s\"\n" -"OFIELD CONSTANT,\"\", \"\"\n" -"OFIELD LAT_DDMMDIR, \"\", \"%08.3f%c\"\n" -"OFIELD LON_DDMMDIR, \"\", \"%09.3f%c\"\n" -"OFIELD ALT_METERS,\"\", \"%3.1fm\"\n" -"OFIELD CONSTANT,\"\", \"1\"\n" -"OFIELD CONSTANT,\"\", \"\"\n" -"OFIELD CONSTANT,\"\", \"\"\n" -"OFIELD CONSTANT,\"\", \"\"\n" -"OFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" - - -; -static char custom[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Custom \"Everything\" Style\n" -"# Author: Alex Mottram\n" -"# Date: 11/24/2002\n" -"#\n" -"#\n" - -"DESCRIPTION Custom \"Everything\" Style\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" -"FORMAT_TYPE INTERNAL\n" - -"#\n" -"# HEADER STUFF:\n" -"#\n" -"PROLOGUE Prologue Line 1 __FILE__\n" -"PROLOGUE Prologue Line 2\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS:\n" -"#\n" -"IFIELD CONSTANT, \"CONSTANT\", \"%s\"\n" -"IFIELD INDEX, \"\", \"%d\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" -"IFIELD LAT_DIR, \"\", \"%c\"\n" -"IFIELD LON_DECIMAL, \"\", \"%f\"\n" -"IFIELD LON_DIR, \"\", \"%c\"\n" -"IFIELD ICON_DESCR, \"\", \"%s\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD NOTES, \"\", \"%s\"\n" -"IFIELD URL, \"\", \"%s\" \n" -"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" -"IFIELD ALT_METERS, \"\", \"%fM\"\n" -"IFIELD ALT_FEET, \"\", \"%fF\"\n" -"IFIELD LAT_DECIMALDIR, \"\", \"%f/%c\"\n" -"IFIELD LON_DECIMALDIR, \"\", \"%f/%c\"\n" -"IFIELD LAT_DIRDECIMAL, \"\", \"%c/%f\"\n" -"IFIELD LON_DIRDECIMAL, \"\", \"%c/%f\"\n" -"IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" -"IFIELD LON_INT32DEG, \"\", \"%ld\"\n" -"IFIELD TIMET_TIME, \"\", \"%ld\"\n" -"IFIELD EXCEL_TIME, \"\", \"%f\"\n" - -"# EPILOGUE: \n" -"EPILOGUE Epilogue Line 1\n" -"EPILOGUE Epilogue Line 2\n" -; -static char dna[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: DNA Marker Format\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"# As defined in dna.c\n" -"#\n" -"#\n" - -"DESCRIPTION Navitrak DNA marker format\n" -"EXTENSION dna\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD INDEX, \"\", \"%d\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" - -; -static char flysight[] = -"# Format: FlySight\n" -"# Author: LukeH\n" -"# Date: 10/10/10\n" - -"DESCRIPTION FlySight GPS File\n" -"EXTENSION csv\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" - -"PROLOGUE time lat lon hMSL velN velE velD hAcc vAcc sAcc gpsFix numSV\n" -"PROLOGUE\n" - -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"IFIELD ISO_TIME, \"\", \"%s\" # Date & time\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" -"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" -"IFIELD ALT_METERS, \"\", \"%.0f\" # Altitude above MSL (m)\n" -"IFIELD IGNORE, \"\", \"%s\" # Velocity north (m/s)\n" -"IFIELD IGNORE, \"\", \"%s\" # Velocity east (m/s)\n" -"IFIELD IGNORE, \"\", \"%s\" # Velocity down (m/s)\n" -"IFIELD IGNORE, \"\", \"%s\" # Horizontal accuracy (m)\n" -"IFIELD IGNORE, \"\", \"%s\" # Vertical accuracy (m)\n" -"IFIELD IGNORE, \"\", \"%s\" # Speed accuracy (m/s)\n" -"IFIELD GPS_FIX, \"\", \"%s\" # GPS fix type\n" -"IFIELD GPS_SAT, \"\", \"%d\" # Number of satellites used in fix\n" -; -static char fugawi[] = -"# fugawi XCSV style file\n" -"#\n" -"# Format: Fugawi\n" -"# Author: Robert Lipe, Patrick Ohly\n" -"# Date: 07/24/2005\n" -"#\n" -"# \n" - -"DESCRIPTION Fugawi\n" -"EXTENSION txt\n" -"SHORTLEN 10\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"PROLOGUE \\# Latitude, Longitude and UTM coordinates are in WGS84 datum\n" -"PROLOGUE \\#\n" -"PROLOGUE \\# Every set of data contains the following:\n" -"PROLOGUE \\#\n" -"PROLOGUE \\# Waypoint name\n" -"PROLOGUE \\# Waypoint comment\n" -"PROLOGUE \\# Waypoint description\n" -"PROLOGUE \\# Latitude in Degree and decimals (soutern hemisphere has neg. degrees)\n" -"PROLOGUE \\# Longitude in degree and decimals (neg. numbers: west of Greenwich)\n" -"PROLOGUE \\# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD NOTES, \"\", \"%s\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%-.7f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%-.7f\"\n" -"IFIELD ALT_METERS, \"\", \"%-7.1f\"\n" -"IFIELD GMT_TIME, \"\", \"%Y%m%d\"\n" -"IFIELD HMSG_TIME, \"\", \"%02d%02d%02d\"\n" -; -static char garmin301[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Garmin 301 Position + Heartrate data\n" -"# Author: Jeff Kalikstein\n" -"# Date: 08/29/2005\n" -"#\n" - -"DESCRIPTION Garmin 301 Custom position and heartrate\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" -"#FORMAT_TYPE INTERNAL\n" - -"#\n" -"# HEADER STUFF:\n" -"#\n" -"PROLOGUE Garmin 301 data __FILE__ \n" -"PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate\n" -"#\n" -"# INDIVIDUAL DATA FIELDS:\n" -"#\n" -"IFIELD TIMET_TIME,\"\",\"%ld\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%f\"\n" -"IFIELD ALT_FEET, \"\", \"%fF\"\n" -"IFIELD HEART_RATE,\"\",\" %d\" # beats per minute\n" - - -"# EPILOGUE: \n" -"#EPILOGUE Epilogue Line 1\n" -"#EPILOGUE Epilogue Line 2\n" -; -static char garmin_poi[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Garmin POI\n" -"# Author: Robert Lipe\n" -"# Date: 10/07/2005\n" -"# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204\n" -"#\n" -"DESCRIPTION Garmin POI database\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" -"SHORTLEN 24\n" -"# PROLOGUE Longitude,Latitude,Name, comment\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" - -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD SHORTNAME, \"\", \"%-.24s\"\n" -"OFIELD GEOCACHE_TYPE, \"\", \" %-.4s\", \"no_delim_before,optional\"\n" -"OFIELD GEOCACHE_CONTAINER, \"\", \"/%-.4s \", \"no_delim_before,optional\"\n" -"OFIELD GEOCACHE_DIFF, \"\", \"(%3.1f\", \"no_delim_before,optional\"\n" -"OFIELD GEOCACHE_TERR, \"\", \"/%3.1f)\", \"no_delim_before,optional\"\n" -"OFIELD DESCRIPTION, \"\", \"%-.50s\"\n" -; -static char geonet[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html)\n" -"# Author: Olaf Klein\n" -"# Date: 08/20/2002\n" -"#\n" - -"DESCRIPTION GEOnet Names Server (GNS)\n" -"EXTENSION txt\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" - -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS TAB\n" -"ENCODING UTF-8\n" - -"PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD IGNORE, \"\", \"%s\" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html )\n" -"IFIELD IGNORE, \"\", \"%s\" # UFI\n" -"IFIELD IGNORE, \"\", \"%s\" # UNI\n" -"IFIELD LAT_DECIMAL, \"\", \"%03.7f\" # LAT\n" -"IFIELD LON_DECIMAL, \"\", \"%03.7f\" # LONG\n" -"IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" -"IFIELD IGNORE, \"\", \"%s\" # DMS_LONG\n" -"IFIELD IGNORE, \"\", \"%s\" # UTM\n" -"IFIELD IGNORE, \"\", \"%s\" # JOG\n" -"IFIELD IGNORE, \"\", \"%s\" # FC\n" -"IFIELD IGNORE, \"\", \"%s\" # DSG\n" -"IFIELD IGNORE, \"\", \"%s\" # PC\n" -"IFIELD IGNORE, \"\", \"%s\" # CC1\n" -"IFIELD IGNORE, \"\", \"%s\" # ADM1\n" -"IFIELD IGNORE, \"\", \"%s\" # ADM2\n" -"IFIELD IGNORE, \"\", \"%s\" # DIM\n" -"IFIELD IGNORE, \"\", \"%s\" # CC2\n" -"IFIELD IGNORE, \"\", \"%s\" # NT\n" -"IFIELD IGNORE, \"\", \"%s\" # LC\n" -"IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" -"IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" -"IFIELD SHORTNAME, \"\", \"%s\" # SHORT_NAME\n" -"IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME\n" -"IFIELD IGNORE, \"\", \"%s\" # FULL_NAME_ND\n" -"IFIELD IGNORE, \"\", \"%s\" # MOD_DATE\n" -; -static char gpsdrive[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: GPSDrive\n" -"# Author: Alex Mottram\n" -"# Date: 12/11/2002\n" -"#\n" -"# \n" -"#\n" - -"DESCRIPTION GpsDrive Format\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER WHITESPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,'\"\n" - -"SHORTLEN 20\n" -"SHORTWHITE 0\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" - -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD ICON_DESCR, \"\", \"%s\"\n" - -"OFIELD ANYNAME, \"\", \"%s\"\n" -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD ICON_DESCR, \"\", \"%s\"\n" -; -static char gpsdrivetrack[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: GPSDriveTrack\n" -"# Author: Tobias Minich\n" -"# Date: 12/07/2005\n" -"#\n" -"# \n" -"#\n" - -"DESCRIPTION GpsDrive Format for Tracks\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER WHITESPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,'\"\n" - -"SHORTLEN 20\n" -"SHORTWHITE 0\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" - -"IFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" -"IFIELD ALT_METERS, \"\", \"%10.0f\"\n" -"# Reports are that this format stores in local time, not GMT as \n" -"# originally thought.\n" -"# IFIELD GMT_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" -"IFIELD LOCAL_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" -; -static char gpsman[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: GPSMAN Format\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"# As defined in gpsman.c\n" -"#\n" -"#\n" - -"DESCRIPTION GPSman\n" -"SHORTLEN 8\n" -"SHORTWHITE 0\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS TAB\n" - -"PROLOGUE !Format: DDD 1 WGS 84\n" -"PROLOGUE !W:\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD SHORTNAME, \"\", \"%-8.8s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" -"IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" -"IFIELD IGNORE, \"\", \"%s\"\n" - -"# gpsman.c likes mkshort len = 8, whitespace = 0.\n" -; -static char iblue747[] = -"# GPSBabel XCSV Style File http://www.gpsbabel.org/htmldoc-development/Styles.html\n" -"# Author: Christian Barmala http://www.barmala.de/\n" -"# License GNU Public License http://opensource.org/licenses/gpl-license.php\n" - -"DESCRIPTION Data Logger iBlue747 csv\n" -"EXTENSION csv\n" -"# full length csv with all options\n" - -"# FILE LAYOUT DEFINITIIONS:\n" - -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"# BADCHARS COMMA\n" -"# SHORTLEN 16\n" -"# SHORTWHITE 0\n" -"# ENCODING UTF-8\n" -"DATATYPE TRACK\n" -"PROLOGUE INDEX,RCR,DATE,TIME,VALID,LATITUDE,N/S,LONGITUDE,E/W,HEIGHT,SPEED,PDOP,HDOP,VDOP,NSAT,DISTANCE,\n" - - -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" - -"IFIELD INDEX,\"1\",\"%d\" # INDEX\n" -"IFIELD CONSTANT,\"T\",\"%s\" # RCR\n" -"IFIELD GMT_TIME,\"\",\"%Y/%m/%d\" # DATE\n" -"IFIELD HMSG_TIME,\"\",\"%02d:%02d:%02d\" # TIME\n" -"IFIELD GPS_FIX,\"\",\"%s\" # VALID # No fix, SPS, DGPS, PPS\n" -"IFIELD LAT_DECIMAL,\"\",\"%f\" # LATITUDE\n" -"IFIELD LAT_DIR,\"\",\"%c\" # N/S\n" -"IFIELD LON_DECIMAL,\"\",\"%f\" # LONGITUDE\n" -"IFIELD LON_DIR,\"\",\"%c\" # E/W\n" -"IFIELD ALT_METERS,\"\",\"%.0f\" # HEIGHT\n" -"IFIELD PATH_SPEED_KPH,\"\",\"%.1f\" # SPEED\n" -"IFIELD IGNORE,\"\",\"%f\" # HEADING\n" -"IFIELD IGNORE,\"\",\"%d\" # DSTA\n" -"IFIELD IGNORE,\"\",\"%f\" # DAGE\n" -"IFIELD GPS_PDOP,\"\",\"%f\" # PDOP\n" -"IFIELD GPS_HDOP,\"\",\"%f\" # HDOP\n" -"IFIELD GPS_VDOP,\"\",\"%f\" # VDOP\n" -"IFIELD GPS_SAT,\"\",\"%d(\" # NSAT USED/VIEW\n" -"IFIELD IGNORE,\"\",\"%s\" # SAT INFO\n" -"IFIELD PATH_DISTANCE_KM,\"\",\"%f\" # DISTANCE\n" -; -static char igo2008_poi[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: iGO2008 points of interest\n" -"# Author: Olaf Klein\n" -"# Date: 09/05/2008\n" -"#\n" -"DESCRIPTION iGO2008 points of interest (.upoi)\n" -"EXTENSION upoi\n" -"DATATYPE WAYPOINT\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER PIPE\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS \"|\n" -"ENCODING MS-ANSI\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD INDEX,\"1\",\"%d\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD IGNORE, \"\", \"%s\" # nothing\n" -"IFIELD LAT_DECIMAL, \"\", \"%.6f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%.6f\"\n" -"IFIELD IGNORE, \"\", \"%s\" # Name of map\n" -"IFIELD IGNORE, \"\", \"%s\" # nothing\n" -"IFIELD POSTAL_CODE, \"\", \"%s\"\n" -"IFIELD CITY, \"\", \"%s\"\n" -"IFIELD STREET_ADDR, \"\", \"%s\" # Street without number\n" -"IFIELD IGNORE, \"\", \"%s\" # Street number\n" -"IFIELD NOTES, \"\", \"%s\"\n" -"IFIELD PHONE_NR, \"\", \"%s\"\n" -; -static char kompass_tk[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" -"# Author: Olaf Klein\n" -"# Date: 01/10/2007\n" -"#\n" -"# \n" -"DESCRIPTION Kompass (DAV) Track (.tk)\n" -"DATATYPE TRACK\n" -"EXTENSION wp\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" -; -static char kompass_wp[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" -"# Author: Olaf Klein\n" -"# Date: 01/10/2007\n" -"#\n" -"# \n" -"DESCRIPTION Kompass (DAV) Waypoints (.wp)\n" -"DATATYPE WAYPOINT\n" -"EXTENSION wp\n" -"ENCODING UTF-8\n" -"FIELD_DELIMITER SEMICOLON\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS ,\"\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" -"IFIELD ALT_METERS, \"\", \"%.0f\"\n" -"IFIELD LOCAL_TIME,\"\",\"%d.%m.%Y %H:%M:%S\"\n" -"IFIELD CONSTANT, \"Icons\\Wegpunkt grün.bmp\", \"%s\"\n" -"IFIELD IGNORE, \"\", \"%s\"\n" -"IFIELD CONSTANT, \"1\", \"%s\" # unknown\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -; -static char ktf2[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Kartex KTF 2.0 Degrees with decimals\n" -"# Author: Harald Nordius\n" -"# Date: 4/13 2006\n" -"#\n" -"# \n" -"DESCRIPTION Kartex 5 Track File\n" -"EXTENSION ktf\n" -"DATATYPE TRACK\n" -"SHORTLEN 10\n" -"SHORTWHITE 1\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER CRNEWLINE\n" -"#\n" -"#\n" -"# FILE HEADER\n" -"#\n" -"PROLOGUE //Kartex Track File created by GPSBabel\n" -"PROLOGUE &KTF 2.0,sweref 99 lat long,0\n" -"#\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD CONSTANT, %, \"%s\"\n" -"IFIELD INDEX, \"\", \"%d\"\n" -"IFIELD LATLON_HUMAN_READABLE, \"\", \"%c%f°\"\n" -"IFIELD ALT_METERS, \"\", \"%.2f\"\n" -"IFIELD GMT_TIME, \"\", \"%Y-%m-%d %H:%M:%S\"\n" -"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" -"IFIELD IGNORE, \"\", \"%s\" #Empty field\n" -"IFIELD CONSTANT, \"$\", \"%s\"\n" -; -static char kwf2[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Kartex KWF 2.0 Degrees with decimals\n" -"# Author: Harald Nordius\n" -"# Date: 12/08 2004\n" -"#\n" -"# \n" -"DESCRIPTION Kartex 5 Waypoint File\n" -"EXTENSION kwf\n" -"SHORTLEN 10\n" -"SHORTWHITE 1\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER CRNEWLINE\n" -"ENCODING CP1252\n" -"#\n" -"#\n" -"# FILE HEADER\n" -"#\n" -"PROLOGUE //Kartex Waypoint File created by GPSBabel\n" -"PROLOGUE &KWF 2.0,sweref 99 lat long,0\n" -"#\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD CONSTANT, \\#, \"%s\"\n" -"IFIELD INDEX,\"\",\"%d\"\n" -"IFIELD SHORTNAME,\"\",\"%s\"\n" -"IFIELD LATLON_HUMAN_READABLE,\"\",\"%c%f°\"\n" -"IFIELD ALT_METERS,\"\",\"%.2f\"\n" -"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" -"IFIELD IGNORE, \"\",\"%s\" #Empty field\n" -"IFIELD CONSTANT, \"0\",\"%s\" #Waypoint symbol code\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD CONSTANT, \"$\", \"%s\"\n" -; -static char land_air_sea[] = -"# Format: GPS Tracking Key Pro text file\n" -"# Author: Tyler Ritchie\n" -"# Date: 2011.02.04\n" - -"DESCRIPTION GPS Tracking Key Pro text\n" -"EXTENSION txt\n" -"ENCODING LATIN1\n" - -"DATUM WGS 84\n" -"DATATYPE TRACK\n" -"#File layout definitions\n" - -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" - -"# Individual data fields in order of appearance\n" - -"IFIELD LOCAL_TIME,\"\",\"%m-%d-%Y\"\n" -"IFIELD HMSG_TIME,\"\",\"%d:%d:%d\"\n" -"IFIELD LAT_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" -"IFIELD LON_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" -"IFIELD PATH_SPEED_MPH,\"\",\"%.1fmph\"\n" -"IFIELD IGNORE,\"\",\"%s\" #This is the bearing data\n" -"IFIELD ALT_FEET,\"\",\"%dft\"\n" -; -static char mapconverter[] = -"# Format: Mapopolis.com Mapconverter\n" -"# Author: Gary Paulson\n" -"# Date: 01/13/2003\n" -"# Requires unsupported mapconverter.exe from mapopolis.com.\n" -"#\n" -"# Modifications by Alex Mottram documented 6/30/2003\n" -"# Change %-40.40s on description output to %-.40s to stop padding.\n" -"# Add QUOTE as badchars, remove COMMA.\n" -"# Removed Mapconverter.exe's README information from style file.\n" -"# Changed OFIELD to IFIELD in case you ever want to read one of these things.\n" -"#\n" -"#\n" -"DESCRIPTION Mapopolis.com Mapconverter CSV\n" -"EXTENSION txt\n" - -"# FILE LAYOUT DEFINITIIONS:\n" - -"FIELD_DELIMITER COMMASPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS \",\n" - -"# Map Info Record (header):\n" -"PROLOGUE M, \"Geocaches\", \"GPSBabel\", Geocaches, __FILE__\n" -"#\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"# L Records:\n" -"IFIELD CONSTANT, \"L\", \"%s\" # [L]ANDMARK\n" -"IFIELD CONSTANT, \"Geocaches\", \"%s\" # Category for Landmark Searches\n" -"IFIELD DESCRIPTION, \"\", \"%-.40s\" # Name\n" -"IFIELD CONSTANT, \"1\", \"%s\" # View at Zoom Level 1 (1-4)\n" -"IFIELD LON_DECIMAL, \"\", \"%08.5f\" # Longitude\n" -"IFIELD LAT_DECIMAL, \"\", \"%08.5f\" # Latitude\n" -; -static char mxf[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Ozi Explorer\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"# As used in mxf.c\n" -"#\n" -"#\n" - -"DESCRIPTION MapTech Exchange Format\n" -"EXTENSION mxf\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMASPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"IFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" -"IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" -"IFIELD IGNORE, \"\", \"%s\"\n" -"IFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" -"IFIELD CONSTANT, \"47\", \"%s\" # ICON\n" - -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" -"OFIELD SHORTNAME, \"\", \"\"%s\"\"\n" -"OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" -"OFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" -"OFIELD CONSTANT, \"47\", \"%s\" # ICON\n" -; -static char navigonwpt[] = -"# gpsbabel XCSV style file\n" -"# Author: Tom Glaab\n" -"#\n" -"DESCRIPTION Navigon Waypoints\n" -"SHORTLEN 8\n" -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER |\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS |\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" - -"OFIELD SHORTNAME, \"\",\"[%-.14s \"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"\",\"]\"\n" -"OFIELD CONSTANT, \"%s\",\"[0][17]\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"\"\n" -"OFIELD CONSTANT, \"%s\",\"49\"\n" -; -static char nima[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: NIMA/GNIS Geographic Names File\n" -"# Author: Alex Mottram\n" -"# Date: 11/24/2002\n" -"#\n" - -"DESCRIPTION NIMA/GNIS Geographic Names File\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS TAB\n" -"PROLOGUE RC UFI UNI DD_LAT DD_LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD IGNORE, \"\", \"%s\" # RC\n" -"IFIELD IGNORE, \"\", \"%s\" # UFI\n" -"IFIELD IGNORE, \"\", \"%s\" # UNI\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\" # DD_LAT\n" -"IFIELD LON_DECIMAL, \"\", \"%f\" # DD_LON\n" -"IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" -"IFIELD IGNORE, \"\", \"%s\" # DMS_LON\n" -"IFIELD IGNORE, \"\", \"%s\" # UTM\n" -"IFIELD IGNORE, \"\", \"%s\" # JOG\n" -"IFIELD IGNORE, \"\", \"%s\" # FC\n" -"IFIELD IGNORE, \"\", \"%s\" # DSG\n" -"IFIELD IGNORE, \"\", \"%s\" # PC\n" -"IFIELD IGNORE, \"\", \"%s\" # CC1\n" -"IFIELD IGNORE, \"\", \"%s\" # ADM1\n" -"IFIELD IGNORE, \"\", \"%s\" # ADM2\n" -"IFIELD IGNORE, \"\", \"%s\" # DIM\n" -"IFIELD IGNORE, \"\", \"%s\" # CC2\n" -"IFIELD IGNORE, \"\", \"%s\" # NT\n" -"IFIELD IGNORE, \"\", \"%s\" # LC\n" -"IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" -"IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" -"IFIELD SHORTNAME, \"\", \"%s\" # SORT_NAME \n" -"IFIELD IGNORE, \"\", \"%s\" # FULL_NAME (unicoded!)\n" -"IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME_ND\n" -"IFIELD IGNORE, \"\", \"%s\" # MODIFY_DATE\n" -; -static char openoffice[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Tab delimited useful for OpenOffice, Ploticus etc.\n" -"# Author: Tobias Minich\n" -"# Date: 07/18/2005\n" -"#\n" -"#\n" - -"DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc.\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS TAB\n" - -"#\n" -"# HEADER STUFF:\n" -"#\n" -"PROLOGUE Index Lat Lon Icon Name Description Notes URL Link Text Altitude (m) Distance (km) Speed (m/s) Course (°) Time HDOP VDOP PDOP Satellites Fix\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS:\n" -"#\n" -"IFIELD INDEX, \"\", \"%d\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" -"IFIELD LAT_DIR, \"\", \"%c\"\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" -"IFIELD LON_DECIMAL, \"\", \"%f\"\n" -"IFIELD LON_DIR, \"\", \"%c\"\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" -"IFIELD ICON_DESCR, \"\", \"%s\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD NOTES, \"\", \"%s\"\n" -"IFIELD URL, \"\", \"%s\" \n" -"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" -"IFIELD ALT_METERS, \"\", \"%f\"\n" -"IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" -"IFIELD PATH_SPEED, \"\", \"%f\"\n" -"IFIELD PATH_COURSE, \"\", \"%f\"\n" -"IFIELD EXCEL_TIME, \"\", \"%f\"\n" -"IFIELD GPS_HDOP, \"\", \"%f\"\n" -"IFIELD GPS_VDOP, \"\", \"%f\"\n" -"IFIELD GPS_PDOP, \"\", \"%f\"\n" -"IFIELD GPS_SAT, \"\", \"%d\"\n" -"IFIELD GPS_FIX, \"\", \"%s\"\n" -; -static char ricoh[] = -"DESCRIPTION Ricoh GPS Log File\n" -"EXTENSION log\n" -"DATATYPE TRACK\n" - -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" - -"IFIELD LON_DECIMAL,\"\",\"%f\"\n" -"IFIELD LAT_DECIMAL,\"\",\"%f\"\n" -"IFIELD ALT_METERS,\"\",\"%f\"\n" -"IFIELD TRACK_NEW,\"\",\"%d\"\n" -"IFIELD GMT_TIME,\"\",\"%d-%m-%Y %H:%M:%S\"\n" - -; -static char s_and_t[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: MS S&T 2002/2003\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"# As requested by Noel Shrum on the gpsbabel-code mailing list.\n" -"# Name,Latitude,Longitude,Name 2,URL,Type\n" -"# GCCBF,44.479133,-85.56515,High Rollaway by rjlint,http://www.geocaching.com/seek/cache_details.aspx?ID=3263,Traditional Cache\n" -"# GC110D,44.6522,-85.492483,Brown Bridge Pond Peek-a-Boo Cache by Big Bird,http://www.geocaching.com/seek/cache_details.aspx?ID=4365,Traditional Cache\n" -"# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache\n" -"#\n" - -"DESCRIPTION Microsoft Streets and Trips 2002-2007\n" -"EXTENSION txt\n" - - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" - -"PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN\n" -"# HAVE OUR WAY WITH THE FORMATTING. \n" -"#\n" -"IFIELD SHORTNAME, \"\", \"%s\" # Name\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" -"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" -"IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" -"IFIELD URL, \"\", \"%s\" # URL\n" -"IFIELD GEOCACHE_TYPE, \"\", \"%s\" # Geocache Type\n" -"IFIELD GEOCACHE_CONTAINER, \"\", \"%s\" # Geocache Type\n" -"IFIELD GEOCACHE_DIFF, \"\", \"%3.1f\" # Geocache Type\n" -"IFIELD GEOCACHE_TERR, \"\", \"%3.1f\" # Geocache Type\n" -; -static char saplus[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: \n" -"# Author: Jim Bensman\n" -"# Date: 02/22/04\n" -"#\n" - -"DESCRIPTION DeLorme Street Atlas Plus\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS ,\"\n" - -"PROLOGUE Name 2,Name,Latitude,Longitude,URL,Type\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" -"IFIELD SHORTNAME, \"\", \"%s\" # Name\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" -"IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" -"IFIELD URL, \"\", \"%s\" # URL\n" -"IFIELD IGNORE, \"\", \"\" # Holder for Geocache Type\n" - -; -static char sportsim[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Sportsim track files\n" -"# Author: Olaf Klein\n" -"# Date: 07/05/2006\n" -"#\n" -"DESCRIPTION Sportsim track files (part of zipped .ssz files) \n" -"EXTENSION txt\n" -"DATATYPE TRACK\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER SEMICOLON\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS TAB\n" - -"#\n" -"# FILE HEADER\n" -"#\n" -"PROLOGUE SportsimVersion:01\n" -"PROLOGUE \\#Sportsim TrackFile\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS:\n" -"#\n" -"IFIELD INDEX, \"\", \"%05d\"\n" -"IFIELD CONSTANT, \"0\", \"%s\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%f\"\n" -"IFIELD ALT_FEET, \"\", \"%.f\"\n" -"IFIELD TIMET_TIME, \"\", \"%ld\"\n" -"IFIELD CONSTANT, \";\", \"%s\"\n" -; -static char tabsep[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: Dumps all fields in a traditional Unix tab separated style\n" -"#\n" -"# The order of the fields (with the exception of LAT_DIR/LON_DIR) was\n" -"# the same as documented in README.style when this format was created.\n" -"# LAT_DIR/LON_DIR were undocumented, so I stuck them at the end of the\n" -"# other lat/lon fields.\n" -"#\n" -"# However, please add any new gpsbabel fields to the end (to avoid\n" -"# upsetting existing applications) regardless of where they land in\n" -"# the README.style documentation.\n" -"#\n" - -"DESCRIPTION All database fields on one tab-separated line\n" - -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER TAB\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS TAB\n" -"FORMAT_TYPE INTERNAL\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS:\n" -"#\n" -"IFIELD INDEX, \"\", \"%d\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" -"IFIELD NOTES, \"\", \"%s\"\n" -"IFIELD URL, \"\", \"%s\" \n" -"IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" -"IFIELD ICON_DESCR, \"\", \"%s\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%f\"\n" -"IFIELD LON_DECIMAL, \"\", \"%f\"\n" -"IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" -"IFIELD LON_INT32DEG, \"\", \"%ld\"\n" -"IFIELD LAT_DECIMALDIR, \"\", \"%f%c\"\n" -"IFIELD LON_DECIMALDIR, \"\", \"%f%c\"\n" -"IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" -"IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" -"IFIELD LAT_DIR, \"\", \"%c\"\n" -"IFIELD LON_DIR, \"\", \"%c\"\n" -"IFIELD ALT_FEET, \"\", \"%fF\"\n" -"IFIELD ALT_METERS, \"\", \"%fM\"\n" -"IFIELD EXCEL_TIME, \"\", \"%f\"\n" -"IFIELD TIMET_TIME, \"\", \"%ld\"\n" -"IFIELD GEOCACHE_DIFF,\"\",\"%3.1f\"\n" -"IFIELD GEOCACHE_TERR,\"\",\"%3.1f\"\n" -"IFIELD GEOCACHE_CONTAINER,\"\",\"%s\"\n" -"IFIELD GEOCACHE_TYPE,\"\",\"%s\"\n" -"IFIELD PATH_DISTANCE_MILES,\"\",\"%f\"\n" -"IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" -"IFIELD GEOCACHE_PLACER,\"\",\"%s\"\n" -"IFIELD YYYYMMDD_TIME,\"\",\"%ld\"\n" -"IFIELD GEOCACHE_HINT, \"\", \"%s\"\n" -"IFIELD GEOCACHE_LAST_FOUND, \"\", \"%d\"\n" -; -static char tomtom_asc[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: TomTom Navigator Places of Interest\n" -"# Author: Olaf Klein\n" -"# Date: 04/17/2007\n" -"#\n" -"DESCRIPTION TomTom POI file (.asc)\n" -"EXTENSION asc\n" -"DATATYPE WAYPOINT\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS ,\"\n" -"ENCODING MS-ANSI\n" -"#\n" -"PROLOGUE TomTom Navigator Places of Interest\n" -"PROLOGUE GPSBabel-__VERSION__ ASCII Export\n" -"PROLOGUE Points\n" -"PROLOGUE Created at: __DATE_AND_TIME__\n" -"# #\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LON_DECIMAL, \"\", \"%.6f\"\n" -"IFIELD LAT_DECIMAL, \"\", \"%.6f\"\n" -"IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" -; -static char tomtom_itn[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: TomTom Navigator Itineraries (Routes)\n" -"# Author: Olaf Klein\n" -"# Date: 04/17/2007\n" -"#\n" -"DESCRIPTION TomTom Itineraries (.itn)\n" -"EXTENSION itn\n" -"DATATYPE ROUTE\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER PIPE\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS ,|\n" -"ENCODING MS-ANSI\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LON_10E5, \"\", \"%.f\"\n" -"IFIELD LAT_10E5, \"\", \"%.f\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD CONSTANT, \"0\", \"%s\"\n" -; -static char tomtom_itn_places[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: TomTom Navigator Itineraries (Routes)\n" -"# Author: Olaf Klein\n" -"# Date: 04/17/2007\n" -"#\n" -"DESCRIPTION TomTom Places Itineraries (.itn)\n" -"EXTENSION itn\n" -"DATATYPE ROUTE\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER PIPE\n" -"RECORD_DELIMITER CRNEWLINE\n" -"BADCHARS ,|\n" -"ENCODING MS-ANSI\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LON_10E5, \"\", \"%.f\"\n" -"IFIELD LAT_10E5, \"\", \"%.f\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" -"IFIELD CONSTANT, \"2\", \"%s\"\n" -; -static char xmap[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: DeLorme Xmap Conduit\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"# As defined in csv.c/xmap\n" -"#\n" - -"DESCRIPTION DeLorme XMap HH Native .WPT\n" -"EXTENSION wpt\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMASPACE\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"PROLOGUE BEGIN SYMBOL\n" -"EPILOGUE END\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" -"IFIELD DESCRIPTION, \"\", \"%s\"\n" - -"OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" -"OFIELD DESCRIPTION, \"\", \"%s\"\n" -; -static char xmap2006[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit\n" -"# Author: Pasha Phares\n" -"# Date: 5/5/2006\n" -"#\n" -"# Amazingly, 2006 won't read the \"COMMASPACE\" that we used in \n" -"# in Xmap prior to this and versions before 2006 won't read files\n" -"# separated by only a comma.\n" -"# \n" - -"DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT\n" -"EXTENSION txt\n" - -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COMMA\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COMMA\n" - -"PROLOGUE BEGIN SYMBOL\n" -"EPILOGUE END\n" -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD LAT_HUMAN_READABLE, \"\", \"%.12g\"\n" -"IFIELD LON_HUMAN_READABLE, \"\", \"%.12g\"\n" -"IFIELD SHORTNAME, \"\", \"%s\"\n" - -"OFIELD LAT_DECIMAL, \"\", \"%.12g\"\n" -"OFIELD LON_DECIMAL, \"\", \"%.12g\"\n" -"OFIELD SHORTNAME, \"\", \"%s\"\n" - - - - -; -static char xmapwpt[] = -"# gpsbabel XCSV style file\n" -"#\n" -"# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC)\n" -"# Author: Alex Mottram\n" -"# Date: 12/09/2002\n" -"#\n" -"# \n" -"DESCRIPTION DeLorme XMat HH Street Atlas USA .WPT (PPC)\n" -"SHORTLEN 32\n" -"SHORTWHITE 0\n" - -"#\n" -"#\n" -"# FILE LAYOUT DEFINITIIONS:\n" -"#\n" -"FIELD_DELIMITER COLON\n" -"RECORD_DELIMITER NEWLINE\n" -"BADCHARS COLON\n" - -"#\n" -"# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" -"#\n" -"IFIELD CONSTANT, \"1296126539\", \"%s\"\n" -"IFIELD CONSTANT, \"1481466224\", \"%s\"\n" -"IFIELD LAT_INT32DEG, \"\", \"%d\"\n" -"IFIELD LON_INT32DEG, \"\", \"%d\"\n" -"IFIELD CONSTANT, \"3137157\", \"%s\"\n" -"IFIELD SHORTNAME, \"\", \"%-.31s\"\n" -"IFIELD IGNORE, \"\", \"%-.31s\"\n" -"IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" -; +static char arc[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: GPSBabel arc filter format\n" + "# Author: Ron Parker\n" + "# Date: 17 July 2003\n" + "#\n" + + "DESCRIPTION GPSBabel arc filter file\n" + "EXTENSION txt\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + ; +static char cambridge[] = + "DESCRIPTION Cambridge/Winpilot glider software\n" + "SHORTLEN 8\n" + "EXTENSION dat\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "IFIELD INDEX,\"1\",\"%d\"\n" + "IFIELD LAT_HUMAN_READABLE,\"\",\"%d:%06.3f%c\"\n" + "IFIELD LON_HUMAN_READABLE,\"\",\"%03d:%06.3f%c\"\n" + "IFIELD ALT_METERS,\"\",\"%3.0fM\"\n" + "IFIELD CONSTANT,\"\",\"T\"\n" + "IFIELD SHORTNAME,\"\",\"%s\"\n" + "IFIELD DESCRIPTION,\"\",\"%s\"\n" + ; +static char csv[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: DeLorme SA 9.0 CSV\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "DESCRIPTION Comma separated values\n" + "SHORTLEN 8\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMASPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD DESCRIPTION, \"\", \"%s\"\n" + ; +static char cup[] = + "#\n" + "# (c) 2006, Robert Lipe, based on sample files by Krzysztof Wojtas\n" + "# Reference info: http://www.seeyou.ws/thankyou.php?fname=cup_format.pdf\n" + "#\n" + + "DESCRIPTION See You flight analysis data\n" + "SHORTLEN 8\n" + "EXTENSION cup\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + "PROLOGUE name,code,country,lat,lon,elev,style,rwdir,rwlen,freq,desc\n" + "EPILOGUE -----Related Tasks-----\n" + + + "IFIELD SHORTNAME,\"\", \"\"%s\"\"\n" + "IFIELD SHORTNAME,\"\", \"%s\"\n" + "IFIELD CONSTANT,\"\", \"\"\n" + "IFIELD LAT_DDMMDIR, \"%f\", \"%08.3f\", \"absolute\"\n" + "IFIELD LON_DDMMDIR, \"%f\", \"%09.3f\", \"absolute\"\n" + "IFIELD ALT_METERS,\"\", \"%dm\"\n" + "IFIELD CONSTANT,\"\", \"1\"\n" + "IFIELD CONSTANT,\"\", \"\"\n" + "IFIELD CONSTANT,\"\", \"\"\n" + "IFIELD CONSTANT,\"\", \"\"\n" + "IFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + + "OFIELD SHORTNAME,\"\", \"\"%s\"\"\n" + "OFIELD SHORTNAME,\"\", \"%s\"\n" + "OFIELD CONSTANT,\"\", \"\"\n" + "OFIELD LAT_DDMMDIR, \"\", \"%08.3f%c\"\n" + "OFIELD LON_DDMMDIR, \"\", \"%09.3f%c\"\n" + "OFIELD ALT_METERS,\"\", \"%3.1fm\"\n" + "OFIELD CONSTANT,\"\", \"1\"\n" + "OFIELD CONSTANT,\"\", \"\"\n" + "OFIELD CONSTANT,\"\", \"\"\n" + "OFIELD CONSTANT,\"\", \"\"\n" + "OFIELD DESCRIPTION,\"\", \"\"%s\"\"\n" + + + ; +static char custom[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Custom \"Everything\" Style\n" + "# Author: Alex Mottram\n" + "# Date: 11/24/2002\n" + "#\n" + "#\n" + + "DESCRIPTION Custom \"Everything\" Style\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + "FORMAT_TYPE INTERNAL\n" + + "#\n" + "# HEADER STUFF:\n" + "#\n" + "PROLOGUE Prologue Line 1 __FILE__\n" + "PROLOGUE Prologue Line 2\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS:\n" + "#\n" + "IFIELD CONSTANT, \"CONSTANT\", \"%s\"\n" + "IFIELD INDEX, \"\", \"%d\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" + "IFIELD LAT_DIR, \"\", \"%c\"\n" + "IFIELD LON_DECIMAL, \"\", \"%f\"\n" + "IFIELD LON_DIR, \"\", \"%c\"\n" + "IFIELD ICON_DESCR, \"\", \"%s\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD NOTES, \"\", \"%s\"\n" + "IFIELD URL, \"\", \"%s\" \n" + "IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" + "IFIELD ALT_METERS, \"\", \"%fM\"\n" + "IFIELD ALT_FEET, \"\", \"%fF\"\n" + "IFIELD LAT_DECIMALDIR, \"\", \"%f/%c\"\n" + "IFIELD LON_DECIMALDIR, \"\", \"%f/%c\"\n" + "IFIELD LAT_DIRDECIMAL, \"\", \"%c/%f\"\n" + "IFIELD LON_DIRDECIMAL, \"\", \"%c/%f\"\n" + "IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" + "IFIELD LON_INT32DEG, \"\", \"%ld\"\n" + "IFIELD TIMET_TIME, \"\", \"%ld\"\n" + "IFIELD EXCEL_TIME, \"\", \"%f\"\n" + + "# EPILOGUE: \n" + "EPILOGUE Epilogue Line 1\n" + "EPILOGUE Epilogue Line 2\n" + ; +static char dna[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: DNA Marker Format\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "# As defined in dna.c\n" + "#\n" + "#\n" + + "DESCRIPTION Navitrak DNA marker format\n" + "EXTENSION dna\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD INDEX, \"\", \"%d\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + + ; +static char flysight[] = + "# Format: FlySight\n" + "# Author: LukeH\n" + "# Date: 10/10/10\n" + + "DESCRIPTION FlySight GPS File\n" + "EXTENSION csv\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + + "PROLOGUE time lat lon hMSL velN velE velD hAcc vAcc sAcc gpsFix numSV\n" + "PROLOGUE\n" + + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "IFIELD ISO_TIME, \"\", \"%s\" # Date & time\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" + "IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" + "IFIELD ALT_METERS, \"\", \"%.0f\" # Altitude above MSL (m)\n" + "IFIELD IGNORE, \"\", \"%s\" # Velocity north (m/s)\n" + "IFIELD IGNORE, \"\", \"%s\" # Velocity east (m/s)\n" + "IFIELD IGNORE, \"\", \"%s\" # Velocity down (m/s)\n" + "IFIELD IGNORE, \"\", \"%s\" # Horizontal accuracy (m)\n" + "IFIELD IGNORE, \"\", \"%s\" # Vertical accuracy (m)\n" + "IFIELD IGNORE, \"\", \"%s\" # Speed accuracy (m/s)\n" + "IFIELD GPS_FIX, \"\", \"%s\" # GPS fix type\n" + "IFIELD GPS_SAT, \"\", \"%d\" # Number of satellites used in fix\n" + ; +static char fugawi[] = + "# fugawi XCSV style file\n" + "#\n" + "# Format: Fugawi\n" + "# Author: Robert Lipe, Patrick Ohly\n" + "# Date: 07/24/2005\n" + "#\n" + "# \n" + + "DESCRIPTION Fugawi\n" + "EXTENSION txt\n" + "SHORTLEN 10\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "PROLOGUE \\# Latitude, Longitude and UTM coordinates are in WGS84 datum\n" + "PROLOGUE \\#\n" + "PROLOGUE \\# Every set of data contains the following:\n" + "PROLOGUE \\#\n" + "PROLOGUE \\# Waypoint name\n" + "PROLOGUE \\# Waypoint comment\n" + "PROLOGUE \\# Waypoint description\n" + "PROLOGUE \\# Latitude in Degree and decimals (soutern hemisphere has neg. degrees)\n" + "PROLOGUE \\# Longitude in degree and decimals (neg. numbers: west of Greenwich)\n" + "PROLOGUE \\# Height in meters [optional when importing, always present when exporting: Date (GMT) as ISO YYYYMMDD, Time of the day relative to the date as HHMMSS\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD NOTES, \"\", \"%s\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%-.7f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%-.7f\"\n" + "IFIELD ALT_METERS, \"\", \"%-7.1f\"\n" + "IFIELD GMT_TIME, \"\", \"%Y%m%d\"\n" + "IFIELD HMSG_TIME, \"\", \"%02d%02d%02d\"\n" + ; +static char garmin301[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Garmin 301 Position + Heartrate data\n" + "# Author: Jeff Kalikstein\n" + "# Date: 08/29/2005\n" + "#\n" + + "DESCRIPTION Garmin 301 Custom position and heartrate\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + "#FORMAT_TYPE INTERNAL\n" + + "#\n" + "# HEADER STUFF:\n" + "#\n" + "PROLOGUE Garmin 301 data __FILE__ \n" + "PROLOGUE Timestamp,Latitude, Longitude, Altitude(ft), heart rate\n" + "#\n" + "# INDIVIDUAL DATA FIELDS:\n" + "#\n" + "IFIELD TIMET_TIME,\"\",\"%ld\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%f\"\n" + "IFIELD ALT_FEET, \"\", \"%fF\"\n" + "IFIELD HEART_RATE,\"\",\" %d\" # beats per minute\n" + + + "# EPILOGUE: \n" + "#EPILOGUE Epilogue Line 1\n" + "#EPILOGUE Epilogue Line 2\n" + ; +static char garmin_poi[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Garmin POI\n" + "# Author: Robert Lipe\n" + "# Date: 10/07/2005\n" + "# Reference: http://forums.groundspeak.com/GC/index.php?showtopic=110641&st=0&#entry1752204\n" + "#\n" + "DESCRIPTION Garmin POI database\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + "SHORTLEN 24\n" + "# PROLOGUE Longitude,Latitude,Name, comment\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD SHORTNAME, \"\", \"%-.24s\"\n" + "OFIELD GEOCACHE_TYPE, \"\", \" %-.4s\", \"no_delim_before,optional\"\n" + "OFIELD GEOCACHE_CONTAINER, \"\", \"/%-.4s \", \"no_delim_before,optional\"\n" + "OFIELD GEOCACHE_DIFF, \"\", \"(%3.1f\", \"no_delim_before,optional\"\n" + "OFIELD GEOCACHE_TERR, \"\", \"/%3.1f)\", \"no_delim_before,optional\"\n" + "OFIELD DESCRIPTION, \"\", \"%-.50s\"\n" + ; +static char geonet[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: GEOnet Names Server (GNS) (http://earth-info.nga.mil/gns/html/cntry_files.html)\n" + "# Author: Olaf Klein\n" + "# Date: 08/20/2002\n" + "#\n" + + "DESCRIPTION GEOnet Names Server (GNS)\n" + "EXTENSION txt\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS TAB\n" + "ENCODING UTF-8\n" + + "PROLOGUE RC UFI UNI LAT LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD IGNORE, \"\", \"%s\" # RC ( http://earth-info.nga.mil/gns/html/gis_contryfiles.html )\n" + "IFIELD IGNORE, \"\", \"%s\" # UFI\n" + "IFIELD IGNORE, \"\", \"%s\" # UNI\n" + "IFIELD LAT_DECIMAL, \"\", \"%03.7f\" # LAT\n" + "IFIELD LON_DECIMAL, \"\", \"%03.7f\" # LONG\n" + "IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" + "IFIELD IGNORE, \"\", \"%s\" # DMS_LONG\n" + "IFIELD IGNORE, \"\", \"%s\" # UTM\n" + "IFIELD IGNORE, \"\", \"%s\" # JOG\n" + "IFIELD IGNORE, \"\", \"%s\" # FC\n" + "IFIELD IGNORE, \"\", \"%s\" # DSG\n" + "IFIELD IGNORE, \"\", \"%s\" # PC\n" + "IFIELD IGNORE, \"\", \"%s\" # CC1\n" + "IFIELD IGNORE, \"\", \"%s\" # ADM1\n" + "IFIELD IGNORE, \"\", \"%s\" # ADM2\n" + "IFIELD IGNORE, \"\", \"%s\" # DIM\n" + "IFIELD IGNORE, \"\", \"%s\" # CC2\n" + "IFIELD IGNORE, \"\", \"%s\" # NT\n" + "IFIELD IGNORE, \"\", \"%s\" # LC\n" + "IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" + "IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" + "IFIELD SHORTNAME, \"\", \"%s\" # SHORT_NAME\n" + "IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME\n" + "IFIELD IGNORE, \"\", \"%s\" # FULL_NAME_ND\n" + "IFIELD IGNORE, \"\", \"%s\" # MOD_DATE\n" + ; +static char gpsdrive[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: GPSDrive\n" + "# Author: Alex Mottram\n" + "# Date: 12/11/2002\n" + "#\n" + "# \n" + "#\n" + + "DESCRIPTION GpsDrive Format\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER WHITESPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,'\"\n" + + "SHORTLEN 20\n" + "SHORTWHITE 0\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD ICON_DESCR, \"\", \"%s\"\n" + + "OFIELD ANYNAME, \"\", \"%s\"\n" + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD ICON_DESCR, \"\", \"%s\"\n" + ; +static char gpsdrivetrack[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: GPSDriveTrack\n" + "# Author: Tobias Minich\n" + "# Date: 12/07/2005\n" + "#\n" + "# \n" + "#\n" + + "DESCRIPTION GpsDrive Format for Tracks\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER WHITESPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,'\"\n" + + "SHORTLEN 20\n" + "SHORTWHITE 0\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + + "IFIELD LAT_DECIMAL, \"\", \"%10.6f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%10.6f\"\n" + "IFIELD ALT_METERS, \"\", \"%10.0f\"\n" + "# Reports are that this format stores in local time, not GMT as \n" + "# originally thought.\n" + "# IFIELD GMT_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" + "IFIELD LOCAL_TIME, \"\", \"%a %b %d %H:%M:%S %Y\"\n" + ; +static char gpsman[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: GPSMAN Format\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "# As defined in gpsman.c\n" + "#\n" + "#\n" + + "DESCRIPTION GPSman\n" + "SHORTLEN 8\n" + "SHORTWHITE 0\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS TAB\n" + + "PROLOGUE !Format: DDD 1 WGS 84\n" + "PROLOGUE !W:\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD SHORTNAME, \"\", \"%-8.8s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" + "IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" + "IFIELD IGNORE, \"\", \"%s\"\n" + + "# gpsman.c likes mkshort len = 8, whitespace = 0.\n" + ; +static char iblue747[] = + "# GPSBabel XCSV Style File http://www.gpsbabel.org/htmldoc-development/Styles.html\n" + "# Author: Christian Barmala http://www.barmala.de/\n" + "# License GNU Public License http://opensource.org/licenses/gpl-license.php\n" + + "DESCRIPTION Data Logger iBlue747 csv\n" + "EXTENSION csv\n" + "# full length csv with all options\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "# BADCHARS COMMA\n" + "# SHORTLEN 16\n" + "# SHORTWHITE 0\n" + "# ENCODING UTF-8\n" + "DATATYPE TRACK\n" + "PROLOGUE INDEX,RCR,DATE,TIME,VALID,LATITUDE,N/S,LONGITUDE,E/W,HEIGHT,SPEED,PDOP,HDOP,VDOP,NSAT,DISTANCE,\n" + + + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + + "IFIELD INDEX,\"1\",\"%d\" # INDEX\n" + "IFIELD CONSTANT,\"T\",\"%s\" # RCR\n" + "IFIELD GMT_TIME,\"\",\"%Y/%m/%d\" # DATE\n" + "IFIELD HMSG_TIME,\"\",\"%02d:%02d:%02d\" # TIME\n" + "IFIELD GPS_FIX,\"\",\"%s\" # VALID # No fix, SPS, DGPS, PPS\n" + "IFIELD LAT_DECIMAL,\"\",\"%f\" # LATITUDE\n" + "IFIELD LAT_DIR,\"\",\"%c\" # N/S\n" + "IFIELD LON_DECIMAL,\"\",\"%f\" # LONGITUDE\n" + "IFIELD LON_DIR,\"\",\"%c\" # E/W\n" + "IFIELD ALT_METERS,\"\",\"%.0f\" # HEIGHT\n" + "IFIELD PATH_SPEED_KPH,\"\",\"%.1f\" # SPEED\n" + "IFIELD IGNORE,\"\",\"%f\" # HEADING\n" + "IFIELD IGNORE,\"\",\"%d\" # DSTA\n" + "IFIELD IGNORE,\"\",\"%f\" # DAGE\n" + "IFIELD GPS_PDOP,\"\",\"%f\" # PDOP\n" + "IFIELD GPS_HDOP,\"\",\"%f\" # HDOP\n" + "IFIELD GPS_VDOP,\"\",\"%f\" # VDOP\n" + "IFIELD GPS_SAT,\"\",\"%d(\" # NSAT USED/VIEW\n" + "IFIELD IGNORE,\"\",\"%s\" # SAT INFO\n" + "IFIELD PATH_DISTANCE_KM,\"\",\"%f\" # DISTANCE\n" + ; +static char igo2008_poi[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: iGO2008 points of interest\n" + "# Author: Olaf Klein\n" + "# Date: 09/05/2008\n" + "#\n" + "DESCRIPTION iGO2008 points of interest (.upoi)\n" + "EXTENSION upoi\n" + "DATATYPE WAYPOINT\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER PIPE\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS \"|\n" + "ENCODING MS-ANSI\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD INDEX,\"1\",\"%d\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD IGNORE, \"\", \"%s\" # nothing\n" + "IFIELD LAT_DECIMAL, \"\", \"%.6f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%.6f\"\n" + "IFIELD IGNORE, \"\", \"%s\" # Name of map\n" + "IFIELD IGNORE, \"\", \"%s\" # nothing\n" + "IFIELD POSTAL_CODE, \"\", \"%s\"\n" + "IFIELD CITY, \"\", \"%s\"\n" + "IFIELD STREET_ADDR, \"\", \"%s\" # Street without number\n" + "IFIELD IGNORE, \"\", \"%s\" # Street number\n" + "IFIELD NOTES, \"\", \"%s\"\n" + "IFIELD PHONE_NR, \"\", \"%s\"\n" + ; +static char kompass_tk[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" + "# Author: Olaf Klein\n" + "# Date: 01/10/2007\n" + "#\n" + "# \n" + "DESCRIPTION Kompass (DAV) Track (.tk)\n" + "DATATYPE TRACK\n" + "EXTENSION wp\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" + ; +static char kompass_wp[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Kompass / Deutscher Alpenverein (DAV) Waypoints\n" + "# Author: Olaf Klein\n" + "# Date: 01/10/2007\n" + "#\n" + "# \n" + "DESCRIPTION Kompass (DAV) Waypoints (.wp)\n" + "DATATYPE WAYPOINT\n" + "EXTENSION wp\n" + "ENCODING UTF-8\n" + "FIELD_DELIMITER SEMICOLON\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS ,\"\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD LON_DECIMAL, \"\", \"%.7f\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%.7f\"\n" + "IFIELD ALT_METERS, \"\", \"%.0f\"\n" + "IFIELD LOCAL_TIME,\"\",\"%d.%m.%Y %H:%M:%S\"\n" + "IFIELD CONSTANT, \"Icons\\Wegpunkt grün.bmp\", \"%s\"\n" + "IFIELD IGNORE, \"\", \"%s\"\n" + "IFIELD CONSTANT, \"1\", \"%s\" # unknown\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + ; +static char ktf2[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Kartex KTF 2.0 Degrees with decimals\n" + "# Author: Harald Nordius\n" + "# Date: 4/13 2006\n" + "#\n" + "# \n" + "DESCRIPTION Kartex 5 Track File\n" + "EXTENSION ktf\n" + "DATATYPE TRACK\n" + "SHORTLEN 10\n" + "SHORTWHITE 1\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER CRNEWLINE\n" + "#\n" + "#\n" + "# FILE HEADER\n" + "#\n" + "PROLOGUE //Kartex Track File created by GPSBabel\n" + "PROLOGUE &KTF 2.0,sweref 99 lat long,0\n" + "#\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD CONSTANT, %, \"%s\"\n" + "IFIELD INDEX, \"\", \"%d\"\n" + "IFIELD LATLON_HUMAN_READABLE, \"\", \"%c%f°\"\n" + "IFIELD ALT_METERS, \"\", \"%.2f\"\n" + "IFIELD GMT_TIME, \"\", \"%Y-%m-%d %H:%M:%S\"\n" + "IFIELD IGNORE, \"\", \"%s\" #Empty field\n" + "IFIELD IGNORE, \"\", \"%s\" #Empty field\n" + "IFIELD CONSTANT, \"$\", \"%s\"\n" + ; +static char kwf2[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Kartex KWF 2.0 Degrees with decimals\n" + "# Author: Harald Nordius\n" + "# Date: 12/08 2004\n" + "#\n" + "# \n" + "DESCRIPTION Kartex 5 Waypoint File\n" + "EXTENSION kwf\n" + "SHORTLEN 10\n" + "SHORTWHITE 1\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER CRNEWLINE\n" + "ENCODING CP1252\n" + "#\n" + "#\n" + "# FILE HEADER\n" + "#\n" + "PROLOGUE //Kartex Waypoint File created by GPSBabel\n" + "PROLOGUE &KWF 2.0,sweref 99 lat long,0\n" + "#\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD CONSTANT, \\#, \"%s\"\n" + "IFIELD INDEX,\"\",\"%d\"\n" + "IFIELD SHORTNAME,\"\",\"%s\"\n" + "IFIELD LATLON_HUMAN_READABLE,\"\",\"%c%f°\"\n" + "IFIELD ALT_METERS,\"\",\"%.2f\"\n" + "IFIELD IGNORE, \"\",\"%s\" #Empty field\n" + "IFIELD IGNORE, \"\",\"%s\" #Empty field\n" + "IFIELD CONSTANT, \"0\",\"%s\" #Waypoint symbol code\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD CONSTANT, \"$\", \"%s\"\n" + ; +static char land_air_sea[] = + "# Format: GPS Tracking Key Pro text file\n" + "# Author: Tyler Ritchie\n" + "# Date: 2011.02.04\n" + + "DESCRIPTION GPS Tracking Key Pro text\n" + "EXTENSION txt\n" + "ENCODING LATIN1\n" + + "DATUM WGS 84\n" + "DATATYPE TRACK\n" + "#File layout definitions\n" + + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + + "# Individual data fields in order of appearance\n" + + "IFIELD LOCAL_TIME,\"\",\"%m-%d-%Y\"\n" + "IFIELD HMSG_TIME,\"\",\"%d:%d:%d\"\n" + "IFIELD LAT_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" + "IFIELD LON_HUMAN_READABLE,\"\",\"%c %d°%d'%f\\\"\"\n" + "IFIELD PATH_SPEED_MPH,\"\",\"%.1fmph\"\n" + "IFIELD IGNORE,\"\",\"%s\" #This is the bearing data\n" + "IFIELD ALT_FEET,\"\",\"%dft\"\n" + ; +static char mapconverter[] = + "# Format: Mapopolis.com Mapconverter\n" + "# Author: Gary Paulson\n" + "# Date: 01/13/2003\n" + "# Requires unsupported mapconverter.exe from mapopolis.com.\n" + "#\n" + "# Modifications by Alex Mottram documented 6/30/2003\n" + "# Change %-40.40s on description output to %-.40s to stop padding.\n" + "# Add QUOTE as badchars, remove COMMA.\n" + "# Removed Mapconverter.exe's README information from style file.\n" + "# Changed OFIELD to IFIELD in case you ever want to read one of these things.\n" + "#\n" + "#\n" + "DESCRIPTION Mapopolis.com Mapconverter CSV\n" + "EXTENSION txt\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + + "FIELD_DELIMITER COMMASPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS \",\n" + + "# Map Info Record (header):\n" + "PROLOGUE M, \"Geocaches\", \"GPSBabel\", Geocaches, __FILE__\n" + "#\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "# L Records:\n" + "IFIELD CONSTANT, \"L\", \"%s\" # [L]ANDMARK\n" + "IFIELD CONSTANT, \"Geocaches\", \"%s\" # Category for Landmark Searches\n" + "IFIELD DESCRIPTION, \"\", \"%-.40s\" # Name\n" + "IFIELD CONSTANT, \"1\", \"%s\" # View at Zoom Level 1 (1-4)\n" + "IFIELD LON_DECIMAL, \"\", \"%08.5f\" # Longitude\n" + "IFIELD LAT_DECIMAL, \"\", \"%08.5f\" # Latitude\n" + ; +static char mxf[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Ozi Explorer\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "# As used in mxf.c\n" + "#\n" + "#\n" + + "DESCRIPTION MapTech Exchange Format\n" + "EXTENSION mxf\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMASPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "IFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" + "IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" + "IFIELD IGNORE, \"\", \"%s\"\n" + "IFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" + "IFIELD CONSTANT, \"47\", \"%s\" # ICON\n" + + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" + "OFIELD SHORTNAME, \"\", \"\"%s\"\"\n" + "OFIELD DESCRIPTION, \"\", \"\"%s\"\"\n" + "OFIELD CONSTANT, \"ff0000\", \"%s\" # COLOR\n" + "OFIELD CONSTANT, \"47\", \"%s\" # ICON\n" + ; +static char navigonwpt[] = + "# gpsbabel XCSV style file\n" + "# Author: Tom Glaab\n" + "#\n" + "DESCRIPTION Navigon Waypoints\n" + "SHORTLEN 8\n" + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER |\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS |\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + + "OFIELD SHORTNAME, \"\",\"[%-.14s \"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"\",\"]\"\n" + "OFIELD CONSTANT, \"%s\",\"[0][17]\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"\"\n" + "OFIELD CONSTANT, \"%s\",\"49\"\n" + ; +static char nima[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: NIMA/GNIS Geographic Names File\n" + "# Author: Alex Mottram\n" + "# Date: 11/24/2002\n" + "#\n" + + "DESCRIPTION NIMA/GNIS Geographic Names File\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS TAB\n" + "PROLOGUE RC UFI UNI DD_LAT DD_LONG DMS_LAT DMS_LONG UTM JOG FC DSG PC CC1 ADM1 ADM2 DIM CC2 NT LC SHORT_FORM GENERIC SORT_NAME FULL_NAME FULL_NAME_ND MODIFY_DATE\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD IGNORE, \"\", \"%s\" # RC\n" + "IFIELD IGNORE, \"\", \"%s\" # UFI\n" + "IFIELD IGNORE, \"\", \"%s\" # UNI\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\" # DD_LAT\n" + "IFIELD LON_DECIMAL, \"\", \"%f\" # DD_LON\n" + "IFIELD IGNORE, \"\", \"%s\" # DMS_LAT\n" + "IFIELD IGNORE, \"\", \"%s\" # DMS_LON\n" + "IFIELD IGNORE, \"\", \"%s\" # UTM\n" + "IFIELD IGNORE, \"\", \"%s\" # JOG\n" + "IFIELD IGNORE, \"\", \"%s\" # FC\n" + "IFIELD IGNORE, \"\", \"%s\" # DSG\n" + "IFIELD IGNORE, \"\", \"%s\" # PC\n" + "IFIELD IGNORE, \"\", \"%s\" # CC1\n" + "IFIELD IGNORE, \"\", \"%s\" # ADM1\n" + "IFIELD IGNORE, \"\", \"%s\" # ADM2\n" + "IFIELD IGNORE, \"\", \"%s\" # DIM\n" + "IFIELD IGNORE, \"\", \"%s\" # CC2\n" + "IFIELD IGNORE, \"\", \"%s\" # NT\n" + "IFIELD IGNORE, \"\", \"%s\" # LC\n" + "IFIELD IGNORE, \"\", \"%s\" # SHORT_FORM\n" + "IFIELD IGNORE, \"\", \"%s\" # GENERIC\n" + "IFIELD SHORTNAME, \"\", \"%s\" # SORT_NAME \n" + "IFIELD IGNORE, \"\", \"%s\" # FULL_NAME (unicoded!)\n" + "IFIELD DESCRIPTION, \"\", \"%s\" # FULL_NAME_ND\n" + "IFIELD IGNORE, \"\", \"%s\" # MODIFY_DATE\n" + ; +static char openoffice[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Tab delimited useful for OpenOffice, Ploticus etc.\n" + "# Author: Tobias Minich\n" + "# Date: 07/18/2005\n" + "#\n" + "#\n" + + "DESCRIPTION Tab delimited fields useful for OpenOffice, Ploticus etc.\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS TAB\n" + + "#\n" + "# HEADER STUFF:\n" + "#\n" + "PROLOGUE Index Lat Lon Icon Name Description Notes URL Link Text Altitude (m) Distance (km) Speed (m/s) Course (°) Time HDOP VDOP PDOP Satellites Fix\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS:\n" + "#\n" + "IFIELD INDEX, \"\", \"%d\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" + "IFIELD LAT_DIR, \"\", \"%c\"\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" + "IFIELD LON_DECIMAL, \"\", \"%f\"\n" + "IFIELD LON_DIR, \"\", \"%c\"\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%d° %f' %c\"\n" + "IFIELD ICON_DESCR, \"\", \"%s\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD NOTES, \"\", \"%s\"\n" + "IFIELD URL, \"\", \"%s\" \n" + "IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" + "IFIELD ALT_METERS, \"\", \"%f\"\n" + "IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" + "IFIELD PATH_SPEED, \"\", \"%f\"\n" + "IFIELD PATH_COURSE, \"\", \"%f\"\n" + "IFIELD EXCEL_TIME, \"\", \"%f\"\n" + "IFIELD GPS_HDOP, \"\", \"%f\"\n" + "IFIELD GPS_VDOP, \"\", \"%f\"\n" + "IFIELD GPS_PDOP, \"\", \"%f\"\n" + "IFIELD GPS_SAT, \"\", \"%d\"\n" + "IFIELD GPS_FIX, \"\", \"%s\"\n" + ; +static char ricoh[] = + "DESCRIPTION Ricoh GPS Log File\n" + "EXTENSION log\n" + "DATATYPE TRACK\n" + + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + + "IFIELD LON_DECIMAL,\"\",\"%f\"\n" + "IFIELD LAT_DECIMAL,\"\",\"%f\"\n" + "IFIELD ALT_METERS,\"\",\"%f\"\n" + "IFIELD TRACK_NEW,\"\",\"%d\"\n" + "IFIELD GMT_TIME,\"\",\"%d-%m-%Y %H:%M:%S\"\n" + + ; +static char s_and_t[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: MS S&T 2002/2003\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "# As requested by Noel Shrum on the gpsbabel-code mailing list.\n" + "# Name,Latitude,Longitude,Name 2,URL,Type\n" + "# GCCBF,44.479133,-85.56515,High Rollaway by rjlint,http://www.geocaching.com/seek/cache_details.aspx?ID=3263,Traditional Cache\n" + "# GC110D,44.6522,-85.492483,Brown Bridge Pond Peek-a-Boo Cache by Big Bird,http://www.geocaching.com/seek/cache_details.aspx?ID=4365,Traditional Cache\n" + "# GC171C,44.70605,-85.62265,The Michigan Frog by RealDcoy & LRB,http://www.geocaching.com/seek/cache_details.aspx?ID=5916,Traditional Cache\n" + "#\n" + + "DESCRIPTION Microsoft Streets and Trips 2002-2007\n" + "EXTENSION txt\n" + + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + + "PROLOGUE Name Latitude Longitude Description URL Type Container Diff Terr\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "# NOTE: MS S&T ONLY IMPORTS DATA, IT DOESN'T EXPORT THIS ANYWHERE SO WE CAN\n" + "# HAVE OUR WAY WITH THE FORMATTING. \n" + "#\n" + "IFIELD SHORTNAME, \"\", \"%s\" # Name\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" + "IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" + "IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" + "IFIELD URL, \"\", \"%s\" # URL\n" + "IFIELD GEOCACHE_TYPE, \"\", \"%s\" # Geocache Type\n" + "IFIELD GEOCACHE_CONTAINER, \"\", \"%s\" # Geocache Type\n" + "IFIELD GEOCACHE_DIFF, \"\", \"%3.1f\" # Geocache Type\n" + "IFIELD GEOCACHE_TERR, \"\", \"%3.1f\" # Geocache Type\n" + ; +static char saplus[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: \n" + "# Author: Jim Bensman\n" + "# Date: 02/22/04\n" + "#\n" + + "DESCRIPTION DeLorme Street Atlas Plus\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS ,\"\n" + + "PROLOGUE Name 2,Name,Latitude,Longitude,URL,Type\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD DESCRIPTION, \"\", \"%s\" # Name 2 (Big Description)\n" + "IFIELD SHORTNAME, \"\", \"%s\" # Name\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\" # Latitude\n" + "IFIELD LON_DECIMAL, \"\", \"%f\" # Longitude\n" + "IFIELD URL, \"\", \"%s\" # URL\n" + "IFIELD IGNORE, \"\", \"\" # Holder for Geocache Type\n" + + ; +static char sportsim[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Sportsim track files\n" + "# Author: Olaf Klein\n" + "# Date: 07/05/2006\n" + "#\n" + "DESCRIPTION Sportsim track files (part of zipped .ssz files) \n" + "EXTENSION txt\n" + "DATATYPE TRACK\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER SEMICOLON\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS TAB\n" + + "#\n" + "# FILE HEADER\n" + "#\n" + "PROLOGUE SportsimVersion:01\n" + "PROLOGUE \\#Sportsim TrackFile\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS:\n" + "#\n" + "IFIELD INDEX, \"\", \"%05d\"\n" + "IFIELD CONSTANT, \"0\", \"%s\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%f\"\n" + "IFIELD ALT_FEET, \"\", \"%.f\"\n" + "IFIELD TIMET_TIME, \"\", \"%ld\"\n" + "IFIELD CONSTANT, \";\", \"%s\"\n" + ; +static char tabsep[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: Dumps all fields in a traditional Unix tab separated style\n" + "#\n" + "# The order of the fields (with the exception of LAT_DIR/LON_DIR) was\n" + "# the same as documented in README.style when this format was created.\n" + "# LAT_DIR/LON_DIR were undocumented, so I stuck them at the end of the\n" + "# other lat/lon fields.\n" + "#\n" + "# However, please add any new gpsbabel fields to the end (to avoid\n" + "# upsetting existing applications) regardless of where they land in\n" + "# the README.style documentation.\n" + "#\n" + + "DESCRIPTION All database fields on one tab-separated line\n" + + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER TAB\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS TAB\n" + "FORMAT_TYPE INTERNAL\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS:\n" + "#\n" + "IFIELD INDEX, \"\", \"%d\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + "IFIELD NOTES, \"\", \"%s\"\n" + "IFIELD URL, \"\", \"%s\" \n" + "IFIELD URL_LINK_TEXT, \"\", \"%s\"\n" + "IFIELD ICON_DESCR, \"\", \"%s\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%f\"\n" + "IFIELD LON_DECIMAL, \"\", \"%f\"\n" + "IFIELD LAT_INT32DEG, \"\", \"%ld\"\n" + "IFIELD LON_INT32DEG, \"\", \"%ld\"\n" + "IFIELD LAT_DECIMALDIR, \"\", \"%f%c\"\n" + "IFIELD LON_DECIMALDIR, \"\", \"%f%c\"\n" + "IFIELD LAT_DIRDECIMAL, \"\", \"%c%f\"\n" + "IFIELD LON_DIRDECIMAL, \"\", \"%c%f\"\n" + "IFIELD LAT_DIR, \"\", \"%c\"\n" + "IFIELD LON_DIR, \"\", \"%c\"\n" + "IFIELD ALT_FEET, \"\", \"%fF\"\n" + "IFIELD ALT_METERS, \"\", \"%fM\"\n" + "IFIELD EXCEL_TIME, \"\", \"%f\"\n" + "IFIELD TIMET_TIME, \"\", \"%ld\"\n" + "IFIELD GEOCACHE_DIFF,\"\",\"%3.1f\"\n" + "IFIELD GEOCACHE_TERR,\"\",\"%3.1f\"\n" + "IFIELD GEOCACHE_CONTAINER,\"\",\"%s\"\n" + "IFIELD GEOCACHE_TYPE,\"\",\"%s\"\n" + "IFIELD PATH_DISTANCE_MILES,\"\",\"%f\"\n" + "IFIELD PATH_DISTANCE_KM, \"\", \"%f\"\n" + "IFIELD GEOCACHE_PLACER,\"\",\"%s\"\n" + "IFIELD YYYYMMDD_TIME,\"\",\"%ld\"\n" + "IFIELD GEOCACHE_HINT, \"\", \"%s\"\n" + "IFIELD GEOCACHE_LAST_FOUND, \"\", \"%d\"\n" + ; +static char tomtom_asc[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: TomTom Navigator Places of Interest\n" + "# Author: Olaf Klein\n" + "# Date: 04/17/2007\n" + "#\n" + "DESCRIPTION TomTom POI file (.asc)\n" + "EXTENSION asc\n" + "DATATYPE WAYPOINT\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS ,\"\n" + "ENCODING MS-ANSI\n" + "#\n" + "PROLOGUE TomTom Navigator Places of Interest\n" + "PROLOGUE GPSBabel-__VERSION__ ASCII Export\n" + "PROLOGUE Points\n" + "PROLOGUE Created at: __DATE_AND_TIME__\n" + "# #\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LON_DECIMAL, \"\", \"%.6f\"\n" + "IFIELD LAT_DECIMAL, \"\", \"%.6f\"\n" + "IFIELD SHORTNAME, \"\", \"\"%s\"\"\n" + ; +static char tomtom_itn[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: TomTom Navigator Itineraries (Routes)\n" + "# Author: Olaf Klein\n" + "# Date: 04/17/2007\n" + "#\n" + "DESCRIPTION TomTom Itineraries (.itn)\n" + "EXTENSION itn\n" + "DATATYPE ROUTE\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER PIPE\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS ,|\n" + "ENCODING MS-ANSI\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LON_10E5, \"\", \"%.f\"\n" + "IFIELD LAT_10E5, \"\", \"%.f\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD CONSTANT, \"0\", \"%s\"\n" + ; +static char tomtom_itn_places[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: TomTom Navigator Itineraries (Routes)\n" + "# Author: Olaf Klein\n" + "# Date: 04/17/2007\n" + "#\n" + "DESCRIPTION TomTom Places Itineraries (.itn)\n" + "EXTENSION itn\n" + "DATATYPE ROUTE\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER PIPE\n" + "RECORD_DELIMITER CRNEWLINE\n" + "BADCHARS ,|\n" + "ENCODING MS-ANSI\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LON_10E5, \"\", \"%.f\"\n" + "IFIELD LAT_10E5, \"\", \"%.f\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + "IFIELD CONSTANT, \"2\", \"%s\"\n" + ; +static char xmap[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: DeLorme Xmap Conduit\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "# As defined in csv.c/xmap\n" + "#\n" + + "DESCRIPTION DeLorme XMap HH Native .WPT\n" + "EXTENSION wpt\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMASPACE\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "PROLOGUE BEGIN SYMBOL\n" + "EPILOGUE END\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%08.5f\"\n" + "IFIELD DESCRIPTION, \"\", \"%s\"\n" + + "OFIELD LAT_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD LON_DECIMAL, \"\", \"%08.5f\"\n" + "OFIELD DESCRIPTION, \"\", \"%s\"\n" + ; +static char xmap2006[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: DeLorme Xmap/Street Atlas Handheld 2006 Conduit\n" + "# Author: Pasha Phares\n" + "# Date: 5/5/2006\n" + "#\n" + "# Amazingly, 2006 won't read the \"COMMASPACE\" that we used in \n" + "# in Xmap prior to this and versions before 2006 won't read files\n" + "# separated by only a comma.\n" + "# \n" + + "DESCRIPTION DeLorme XMap/SAHH 2006 Native .TXT\n" + "EXTENSION txt\n" + + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COMMA\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COMMA\n" + + "PROLOGUE BEGIN SYMBOL\n" + "EPILOGUE END\n" + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD LAT_HUMAN_READABLE, \"\", \"%.12g\"\n" + "IFIELD LON_HUMAN_READABLE, \"\", \"%.12g\"\n" + "IFIELD SHORTNAME, \"\", \"%s\"\n" + + "OFIELD LAT_DECIMAL, \"\", \"%.12g\"\n" + "OFIELD LON_DECIMAL, \"\", \"%.12g\"\n" + "OFIELD SHORTNAME, \"\", \"%s\"\n" + + + + + ; +static char xmapwpt[] = + "# gpsbabel XCSV style file\n" + "#\n" + "# Format: DeLorme Xmap HH Street Atlas USA .WPT (PocketPC)\n" + "# Author: Alex Mottram\n" + "# Date: 12/09/2002\n" + "#\n" + "# \n" + "DESCRIPTION DeLorme XMat HH Street Atlas USA .WPT (PPC)\n" + "SHORTLEN 32\n" + "SHORTWHITE 0\n" + + "#\n" + "#\n" + "# FILE LAYOUT DEFINITIIONS:\n" + "#\n" + "FIELD_DELIMITER COLON\n" + "RECORD_DELIMITER NEWLINE\n" + "BADCHARS COLON\n" + + "#\n" + "# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:\n" + "#\n" + "IFIELD CONSTANT, \"1296126539\", \"%s\"\n" + "IFIELD CONSTANT, \"1481466224\", \"%s\"\n" + "IFIELD LAT_INT32DEG, \"\", \"%d\"\n" + "IFIELD LON_INT32DEG, \"\", \"%d\"\n" + "IFIELD CONSTANT, \"3137157\", \"%s\"\n" + "IFIELD SHORTNAME, \"\", \"%-.31s\"\n" + "IFIELD IGNORE, \"\", \"%-.31s\"\n" + "IFIELD DESCRIPTION, \"\", \"%-.78s\"\n" + ; style_vecs_t style_list[] = {{ "xmapwpt", xmapwpt } , { "xmap2006", xmap2006 } , { "xmap", xmap } , { "tomtom_itn_places", tomtom_itn_places } , { "tomtom_itn", tomtom_itn } , { "tomtom_asc", tomtom_asc } , { "tabsep", tabsep } , { "sportsim", sportsim } , { "saplus", saplus } , { "s_and_t", s_and_t } , { "ricoh", ricoh } , { "openoffice", openoffice } , { "nima", nima } , { "navigonwpt", navigonwpt } , { "mxf", mxf } , { "mapconverter", mapconverter } , { "land_air_sea", land_air_sea } , { "kwf2", kwf2 } , { "ktf2", ktf2 } , { "kompass_wp", kompass_wp } , { "kompass_tk", kompass_tk } , { "igo2008_poi", igo2008_poi } , { "iblue747", iblue747 } , { "gpsman", gpsman } , { "gpsdrivetrack", gpsdrivetrack } , { "gpsdrive", gpsdrive } , { "geonet", geonet } , { "garmin_poi", garmin_poi } , { "garmin301", garmin301 } , { "fugawi", fugawi } , { "flysight", flysight } , { "dna", dna } , { "custom", custom } , { "cup", cup } , { "csv", csv } , { "cambridge", cambridge } , { "arc", arc } , {0,0}}; size_t nstyles = 37; #else /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/interpolate.c b/gpsbabel/interpolate.c index 776513cc7..39a47a51b 100644 --- a/gpsbabel/interpolate.c +++ b/gpsbabel/interpolate.c @@ -34,161 +34,167 @@ static char *opt_route = NULL; static arglist_t interpfilt_args[] = { - {"time", &opt_interval, "Time interval in seconds", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, - "0", NULL }, - {"distance", &opt_dist, "Distance interval in miles or kilometers", - NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, - ARG_NOMINMAX }, - {"route", &opt_route, "Interpolate routes instead", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "time", &opt_interval, "Time interval in seconds", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_INT, + "0", NULL + }, + { + "distance", &opt_dist, "Distance interval in miles or kilometers", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "route", &opt_route, "Interpolate routes instead", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -void +void interpfilt_process(void) { - queue *backuproute = NULL; - queue *elem, *tmp, *elem2, *tmp2; - route_head *rte_new; - int count = 0; - int first = 0; - double lat1 = 0, lon1 = 0; - int time1 = 0; - int timen; - double distn; - double curdist; - double rt1, rn1, rt2, rn2; - - if ( opt_route ) { - route_backup( &count, &backuproute ); - route_flush_all_routes(); - } - else { - track_backup( &count, &backuproute ); - route_flush_all_tracks(); - } - QUEUE_FOR_EACH( backuproute, elem, tmp ) - { - route_head *rte_old = (route_head *)elem; - - rte_new = route_head_alloc(); - rte_new->rte_name = xstrdup( rte_old->rte_name ); - rte_new->rte_desc = xstrdup( rte_old->rte_desc ); - rte_new->fs = fs_chain_copy( rte_old->fs ); - rte_new->rte_num = rte_old->rte_num; - if ( opt_route ) { - route_add_head( rte_new ); - } - else { - track_add_head( rte_new ); - } - first = 1; - QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) - { - waypoint *wpt = (waypoint *)elem2; - if ( first ) { - first = 0; - } - else { - if ( opt_interval && - wpt->creation_time - time1 > interval ) { - for ( timen = time1+interval; - timen < wpt->creation_time; - timen += interval ) { - waypoint *wpt_new = waypt_dupe(wpt); - wpt_new->creation_time = timen; - if (wpt_new->shortname) xfree(wpt_new->shortname); - if (wpt_new->description) xfree(wpt_new->description); - wpt_new->shortname = wpt_new->description = NULL; - linepart( lat1, lon1, - wpt->latitude, wpt->longitude, - (double)(timen-time1)/ - (double)(wpt->creation_time-time1), - &wpt_new->latitude, - &wpt_new->longitude ); - if (opt_route) - route_add_wpt( rte_new, wpt_new); - else - track_add_wpt( rte_new, wpt_new); - } - } - else if ( opt_dist ) { - rt1 = RAD(lat1); - rn1 = RAD(lon1); - rt2 = RAD(wpt->latitude); - rn2 = RAD(wpt->longitude); - curdist = gcdist( rt1, rn1, rt2, rn2 ); - curdist = radtomiles(curdist); - if ( curdist > dist ) { - for ( distn = dist; - distn < curdist; - distn += dist ) { - waypoint *wpt_new = waypt_dupe(wpt); - wpt_new->creation_time = distn/curdist* - (wpt->creation_time - time1) + time1; - if (wpt_new->shortname) xfree(wpt_new->shortname); - if (wpt_new->description) xfree(wpt_new->description); - wpt_new->shortname = wpt_new->description = NULL; - linepart( lat1, lon1, - wpt->latitude, wpt->longitude, - distn/curdist, - &wpt_new->latitude, - &wpt_new->longitude ); - if (opt_route) - route_add_wpt( rte_new, wpt_new ); - else - track_add_wpt( rte_new, wpt_new); - } - } - } - } - if ( opt_route ) { - route_add_wpt( rte_new, waypt_dupe(wpt)); - } - else { - track_add_wpt( rte_new, waypt_dupe(wpt)); - } - - lat1 = wpt->latitude; - lon1 = wpt->longitude; - time1 = wpt->creation_time; - } - } - route_flush( backuproute ); - xfree( backuproute ); + queue *backuproute = NULL; + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int count = 0; + int first = 0; + double lat1 = 0, lon1 = 0; + int time1 = 0; + int timen; + double distn; + double curdist; + double rt1, rn1, rt2, rn2; + + if (opt_route) { + route_backup(&count, &backuproute); + route_flush_all_routes(); + } else { + track_backup(&count, &backuproute); + route_flush_all_tracks(); + } + QUEUE_FOR_EACH(backuproute, elem, tmp) { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup(rte_old->rte_name); + rte_new->rte_desc = xstrdup(rte_old->rte_desc); + rte_new->fs = fs_chain_copy(rte_old->fs); + rte_new->rte_num = rte_old->rte_num; + if (opt_route) { + route_add_head(rte_new); + } else { + track_add_head(rte_new); + } + first = 1; + QUEUE_FOR_EACH(&rte_old->waypoint_list, elem2, tmp2) { + waypoint *wpt = (waypoint *)elem2; + if (first) { + first = 0; + } else { + if (opt_interval && + wpt->creation_time - time1 > interval) { + for (timen = time1+interval; + timen < wpt->creation_time; + timen += interval) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = timen; + if (wpt_new->shortname) { + xfree(wpt_new->shortname); + } + if (wpt_new->description) { + xfree(wpt_new->description); + } + wpt_new->shortname = wpt_new->description = NULL; + linepart(lat1, lon1, + wpt->latitude, wpt->longitude, + (double)(timen-time1)/ + (double)(wpt->creation_time-time1), + &wpt_new->latitude, + &wpt_new->longitude); + if (opt_route) { + route_add_wpt(rte_new, wpt_new); + } else { + track_add_wpt(rte_new, wpt_new); + } + } + } else if (opt_dist) { + rt1 = RAD(lat1); + rn1 = RAD(lon1); + rt2 = RAD(wpt->latitude); + rn2 = RAD(wpt->longitude); + curdist = gcdist(rt1, rn1, rt2, rn2); + curdist = radtomiles(curdist); + if (curdist > dist) { + for (distn = dist; + distn < curdist; + distn += dist) { + waypoint *wpt_new = waypt_dupe(wpt); + wpt_new->creation_time = distn/curdist* + (wpt->creation_time - time1) + time1; + if (wpt_new->shortname) { + xfree(wpt_new->shortname); + } + if (wpt_new->description) { + xfree(wpt_new->description); + } + wpt_new->shortname = wpt_new->description = NULL; + linepart(lat1, lon1, + wpt->latitude, wpt->longitude, + distn/curdist, + &wpt_new->latitude, + &wpt_new->longitude); + if (opt_route) { + route_add_wpt(rte_new, wpt_new); + } else { + track_add_wpt(rte_new, wpt_new); + } + } + } + } + } + if (opt_route) { + route_add_wpt(rte_new, waypt_dupe(wpt)); + } else { + track_add_wpt(rte_new, waypt_dupe(wpt)); + } + + lat1 = wpt->latitude; + lon1 = wpt->longitude; + time1 = wpt->creation_time; + } + } + route_flush(backuproute); + xfree(backuproute); } void -interpfilt_init(const char *args) { - - char *fm; - if ( opt_interval && opt_dist ) { - fatal( MYNAME ": Can't interpolate on both time and distance.\n"); - } - else if (opt_interval && opt_route ) { - fatal( MYNAME ": Can't interpolate routes on time.\n" ); - } - else if ( opt_interval ) { - interval = atoi(opt_interval); - } - else if ( opt_dist ) { - dist = strtod(opt_dist, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to miles */ - dist *= .6214; - } - } - else { - fatal( MYNAME ": No interval specified.\n"); - } +interpfilt_init(const char *args) +{ + + char *fm; + if (opt_interval && opt_dist) { + fatal(MYNAME ": Can't interpolate on both time and distance.\n"); + } else if (opt_interval && opt_route) { + fatal(MYNAME ": Can't interpolate routes on time.\n"); + } else if (opt_interval) { + interval = atoi(opt_interval); + } else if (opt_dist) { + dist = strtod(opt_dist, &fm); + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to miles */ + dist *= .6214; + } + } else { + fatal(MYNAME ": No interval specified.\n"); + } } filter_vecs_t interpolatefilt_vecs = { - interpfilt_init, - interpfilt_process, - NULL, - NULL, - interpfilt_args + interpfilt_init, + interpfilt_process, + NULL, + NULL, + interpfilt_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/itracku.c b/gpsbabel/itracku.c index ee23585db..e0d69b598 100644 --- a/gpsbabel/itracku.c +++ b/gpsbabel/itracku.c @@ -17,17 +17,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* - This module will download track data from a - +/* + This module will download track data from a + XAiOX iTrackU BLUETOOTH GPS-RECEIVER SiRF III http://www.xaiox.com/itracku_sirf3.htm Example usage:: - - # Read from USB port, output trackpoints & waypoints in GPX format + + # Read from USB port, output trackpoints & waypoints in GPX format ./gpsbabel -i itracku -f com14 -o gpx -F out.gpx - + */ #include "defs.h" #include @@ -38,12 +38,12 @@ /* memory layout of the iTrackU data record */ typedef struct { - gbuint8 longitude[4]; - gbuint8 latitude[4]; - gbuint8 creation_time[4]; - gbuint8 altitude[2]; - gbuint8 speed; - gbuint8 flag; + gbuint8 longitude[4]; + gbuint8 latitude[4]; + gbuint8 creation_time[4]; + gbuint8 altitude[2]; + gbuint8 speed; + gbuint8 flag; } itracku_data_record; static int itracku_is_valid_data_record(itracku_data_record* d); @@ -63,9 +63,9 @@ static const char update_end_marker[] = "WP Update Over"; /* end marker for the static const int update_end_marker_size = sizeof(update_end_marker); #if LATER static const int port_auto_detect_max_port = 32; -/* Special port name for auto detect. If used, gpsbabel will try to detect the serial +/* Special port name for auto detect. If used, gpsbabel will try to detect the serial port with the itracku device automatically. */ -static const char port_auto_detect_filename[] = "auto:"; +static const char port_auto_detect_filename[] = "auto:"; #endif static int update_data_buffer_read_count = 0; @@ -94,93 +94,93 @@ static char *only_new; /* "new" command option */ static void dbg(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - fprintf(stderr, MYNAME ": "); - vfprintf(stderr,msg, ap); - fprintf(stderr, "\n"); - fflush(stderr); - } - va_end(ap); + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + fprintf(stderr, MYNAME ": "); + vfprintf(stderr,msg, ap); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(ap); } static void itracku_device_write_string(const char* s) { - int size = strlen(s) + 1; - dbg(1, "write to device: %s", s); - gbser_write(fd, s, size); + int size = strlen(s) + 1; + dbg(1, "write to device: %s", s); + gbser_write(fd, s, size); } static const char* itracku_device_read_string() { - const int size = 1024; - char* s = xmalloc(size); - gbser_read_line(fd, s, size, 1000, 0, 0); - dbg(1, "read from device: %s", s); - return s; + const int size = 1024; + char* s = xmalloc(size); + gbser_read_line(fd, s, size, 1000, 0, 0); + dbg(1, "read from device: %s", s); + return s; } -static int +static int itracku_device_update_data_init() { - update_data_buffer_read = update_data_buffer; - update_data_buffer_write = update_data_buffer; - update_data_buffer_end = update_data_buffer + sizeof(update_data_buffer); - update_data_buffer_read_count = 0; - dbg(1, "start memory dump"); - return 0; + update_data_buffer_read = update_data_buffer; + update_data_buffer_write = update_data_buffer; + update_data_buffer_end = update_data_buffer + sizeof(update_data_buffer); + update_data_buffer_read_count = 0; + dbg(1, "start memory dump"); + return 0; } -static int +static int itracku_device_update_data_read(void* buf, int len) { - int rc; + int rc; + + if (update_data_buffer_write - update_data_buffer_read >= len) { + memcpy(buf, update_data_buffer_read, len); + update_data_buffer_read += len; + return len; + } - if (update_data_buffer_write - update_data_buffer_read >= len) { - memcpy(buf, update_data_buffer_read, len); - update_data_buffer_read += len; - return len; - } - - if (update_data_buffer_read + update_end_marker_size > update_data_buffer_end) { - memcpy(update_data_buffer, update_data_buffer_read, update_data_buffer_write - update_data_buffer_read); - update_data_buffer_write = update_data_buffer + (update_data_buffer_write - update_data_buffer_read); - update_data_buffer_read = update_data_buffer; - } + if (update_data_buffer_read + update_end_marker_size > update_data_buffer_end) { + memcpy(update_data_buffer, update_data_buffer_read, update_data_buffer_write - update_data_buffer_read); + update_data_buffer_write = update_data_buffer + (update_data_buffer_write - update_data_buffer_read); + update_data_buffer_read = update_data_buffer; + } - rc = gbser_read_wait(fd, update_data_buffer_write, update_data_buffer_end - update_data_buffer_write, timeout); - if (rc == gbser_ERROR) { - return 0; - } + rc = gbser_read_wait(fd, update_data_buffer_write, update_data_buffer_end - update_data_buffer_write, timeout); + if (rc == gbser_ERROR) { + return 0; + } - update_data_buffer_write += rc; - update_data_buffer_read_count += rc; - dbg(1, "%5d kbyte read", update_data_buffer_read_count / 1024); + update_data_buffer_write += rc; + update_data_buffer_read_count += rc; + dbg(1, "%5d kbyte read", update_data_buffer_read_count / 1024); - if (0 == strncmp(update_end_marker, update_data_buffer_write - update_end_marker_size, update_end_marker_size - 1)) { - dbg(1, "end memory dump"); - return 0; - } + if (0 == strncmp(update_end_marker, update_data_buffer_write - update_end_marker_size, update_end_marker_size - 1)) { + dbg(1, "end memory dump"); + return 0; + } - return itracku_device_update_data_read(buf, len); + return itracku_device_update_data_read(buf, len); } /* Convert the degrees format of itracku to double. itracku stores degrees in a - 32-bit unsigned integer. The lower + 32-bit unsigned integer. The lower 6 digits in 10-base notation denote the - minutes multiplied by 10000, and digits + minutes multiplied by 10000, and digits 7-9 denote the degrees. To express a negative number 0x80000000 is added to integer. - Example: the integer 49347687 is interpreted + Example: the integer 49347687 is interpreted as ddmmmmmm @@ -200,27 +200,27 @@ itracku_device_update_data_read(void* buf, int len) double deg_min_to_deg(volatile gbuint32 x) { - double sign; - gbuint32 sep; - gbuint32 d; - gbuint32 m10000; - // determine the sign - if (x > 0x80000000) { - sign = -1.0; - x -= 0x80000000; - } else { - sign = 1.0; - } + double sign; + gbuint32 sep; + gbuint32 d; + gbuint32 m10000; + // determine the sign + if (x > 0x80000000) { + sign = -1.0; + x -= 0x80000000; + } else { + sign = 1.0; + } - sep = 1000000; - - // extract degrees - d = (unsigned int) x / (unsigned int) sep; - // extract (minutes * 10000) - m10000 = x - d * sep; + sep = 1000000; - // convert minutes and degrees to a double - return sign * ((double)d + ((double)m10000) / 600000.0); + // extract degrees + d = (unsigned int) x / (unsigned int) sep; + // extract (minutes * 10000) + m10000 = x - d * sep; + + // convert minutes and degrees to a double + return sign * ((double)d + ((double)m10000) / 600000.0); } /* @@ -229,45 +229,44 @@ deg_min_to_deg(volatile gbuint32 x) gbuint32 deg_to_deg_min(double x) { - gbint32 sign; - double d; - double f; + gbint32 sign; + double d; + double f; - // determine sign - if (x >= 0) { - sign = 1; - } - else { - sign = -1; - x = -x; - } + // determine sign + if (x >= 0) { + sign = 1; + } else { + sign = -1; + x = -x; + } - // integer degrees - d = floor(x); + // integer degrees + d = floor(x); - // fractional part - f = x - d; + // fractional part + f = x - d; - return - (gbuint32)d * 1000000 + // multiply integer degrees to shift it to the right digits. - (gbuint32)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. - ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees + return + (gbuint32)d * 1000000 + // multiply integer degrees to shift it to the right digits. + (gbuint32)(f * 600000.0) + // multiply fractional part to convert to minutes and to to shift it to the right digits. + ((sign > 0) ? 0 : 0x80000000); // add 0x80000000 for negative degrees } /* Convert the itracku time format to time_t. */ -static time_t +static time_t decode_itracku_time(gbuint32 date) { - struct tm t; - t.tm_sec = date & 63; - t.tm_min = (date >> 6) & 63; - t.tm_hour = (date >> 12) & 31; - t.tm_mday = (date >> 17) & 31; - t.tm_mon = ((date >> 22) & 15) - 1; - t.tm_year = ((date >> 26) & 63) + 100; - return mkgmtime(&t); + struct tm t; + t.tm_sec = date & 63; + t.tm_min = (date >> 6) & 63; + t.tm_hour = (date >> 12) & 31; + t.tm_mday = (date >> 17) & 31; + t.tm_mon = ((date >> 22) & 15) - 1; + t.tm_year = ((date >> 26) & 63) + 100; + return mkgmtime(&t); } /* @@ -276,86 +275,85 @@ decode_itracku_time(gbuint32 date) static gbuint32 encode_itracku_time(time_t time) { - struct tm* t = gmtime(&time); - return - (t->tm_sec) + - (t->tm_min << 6) + - (t->tm_hour << 12) + - (t->tm_mday << 17) + - ((t->tm_mon + 1) << 22) + - ((t->tm_year - 100) << 26); + struct tm* t = gmtime(&time); + return + (t->tm_sec) + + (t->tm_min << 6) + + (t->tm_hour << 12) + + (t->tm_mday << 17) + + ((t->tm_mon + 1) << 22) + + ((t->tm_year - 100) << 26); } /* Converts a itracku waypoint record to a gpsbabel waypoint. */ -static waypoint* +static waypoint* to_waypoint(itracku_data_record* d) { - waypoint* wp; - wp = waypt_new(); - wp->longitude = deg_min_to_deg(le_read32(d->longitude)); - wp->latitude = deg_min_to_deg(le_read32(d->latitude)); - wp->creation_time = decode_itracku_time(le_read32(d->creation_time)); - wp->speed = KNOTS_TO_MPS((float)d->speed); - wp->wpt_flags.speed = 1; - wp->altitude = le_read16(d->altitude); - return wp; + waypoint* wp; + wp = waypt_new(); + wp->longitude = deg_min_to_deg(le_read32(d->longitude)); + wp->latitude = deg_min_to_deg(le_read32(d->latitude)); + wp->creation_time = decode_itracku_time(le_read32(d->creation_time)); + wp->speed = KNOTS_TO_MPS((float)d->speed); + wp->wpt_flags.speed = 1; + wp->altitude = le_read16(d->altitude); + return wp; } static void to_itracku_data_record(const waypoint* wp, itracku_data_record* d) { - le_write32(d->longitude, deg_to_deg_min(wp->longitude)); - le_write32(d->latitude, deg_to_deg_min(wp->latitude)); - le_write32(d->creation_time, encode_itracku_time(wp->creation_time)); - d->speed = MPS_TO_KNOTS(wp->speed); - le_write16(d->altitude, wp->altitude); - d->flag = 0xff; + le_write32(d->longitude, deg_to_deg_min(wp->longitude)); + le_write32(d->latitude, deg_to_deg_min(wp->latitude)); + le_write32(d->creation_time, encode_itracku_time(wp->creation_time)); + d->speed = MPS_TO_KNOTS(wp->speed); + le_write16(d->altitude, wp->altitude); + d->flag = 0xff; } /* - Tries to initialize an itracku device attached to + Tries to initialize an itracku device attached to serial port fd. fd must already be opened. - Returns gbser_OK if the initialization is sucessful, a + Returns gbser_OK if the initialization is sucessful, a non-zero integer otherwise. */ int init_device() { - int rc; - const char* greeting; - // verify that we have a MTK based logger... - dbg(1, "verifying device on port %s", port); - - itracku_device_write_string("WP AP-Exit"); - gbser_flush(fd); - itracku_device_write_string("W'P Camera Detect"); - greeting = itracku_device_read_string(); - - if (0 == strcmp(greeting , "WP GPS+BT")) { - dbg(1, "device recognised on port %s", port); - rc = gbser_OK; - } - else { - dbg(1, "device not recognised on port %s", port); - rc = gbser_ERROR; - } - xfree((void*)greeting); - return rc; -} - -// Any arg in this list will appear in command line help and will be + int rc; + const char* greeting; + // verify that we have a MTK based logger... + dbg(1, "verifying device on port %s", port); + + itracku_device_write_string("WP AP-Exit"); + gbser_flush(fd); + itracku_device_write_string("W'P Camera Detect"); + greeting = itracku_device_read_string(); + + if (0 == strcmp(greeting , "WP GPS+BT")) { + dbg(1, "device recognised on port %s", port); + rc = gbser_OK; + } else { + dbg(1, "device not recognised on port %s", port); + rc = gbser_ERROR; + } + xfree((void*)greeting); + return rc; +} + +// Any arg in this list will appear in command line help and will be // populated for you. -// Values for ARGTYPE_xxx can be found in defs.h and are used to +// Values for ARGTYPE_xxx can be found in defs.h and are used to // select the type of option. static arglist_t itracku_args[] = { - { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, -// "default", ARGYTPE_STRING, ARG_NOMINMAX} , - ARG_TERMINATOR + { "backup", &backup_file_name, "Appends the input to a backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "new", &only_new, "Only waypoints that are not the backup file", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, +// "default", ARGYTPE_STRING, ARG_NOMINMAX} , + ARG_TERMINATOR }; /******************************************************************************* @@ -365,129 +363,115 @@ arglist_t itracku_args[] = { static void itracku_rd_init_common(const char *fname) { - new_waypoint_count = 0; - - if (backup_file_name != NULL) - { - fbackup = gbfopen(backup_file_name, "a+", MYNAME); - backup_last_creation_time = itracku_file_read_last_time(fbackup); - gbfseek(fbackup, 0, SEEK_END); - } - else - { - fbackup = NULL; - backup_last_creation_time = 0; - } - } + new_waypoint_count = 0; + + if (backup_file_name != NULL) { + fbackup = gbfopen(backup_file_name, "a+", MYNAME); + backup_last_creation_time = itracku_file_read_last_time(fbackup); + gbfseek(fbackup, 0, SEEK_END); + } else { + fbackup = NULL; + backup_last_creation_time = 0; + } +} static void itracku_rd_ser_init(const char *fname) { #if LATER - int i; - if (0 == strcmp(fname, port_auto_detect_filename)) { - dbg(1, "auto detecting port for iTrackU device"); - for (i=1; !fd && icreation_time) > backup_last_creation_time) { - backup_last_creation_time = le_read32(d->creation_time); - gbfwrite(d, sizeof(*d), 1, fbackup); - result = -1; - } - else { - result = (only_new == NULL); - } - } - else { - result = -1; - } - } - if (result) { - ++new_waypoint_count; - } - return result; + int result = 0; + + if (!itracku_is_valid_data_record(d)) { + result = 0; + } else { + if (fbackup) { + if ((gbuint32)le_read32(d->creation_time) > backup_last_creation_time) { + backup_last_creation_time = le_read32(d->creation_time); + gbfwrite(d, sizeof(*d), 1, fbackup); + result = -1; + } else { + result = (only_new == NULL); + } + } else { + result = -1; + } + } + if (result) { + ++new_waypoint_count; + } + return result; } static int itracku_is_valid_data_record(itracku_data_record* d) { - return !(le_read32(d->longitude) == -1); + return !(le_read32(d->longitude) == -1); } static void itracku_device_dump_waypts(void* fd, void (*waypt_add)(waypoint *wpt)) { - itracku_data_record d; + itracku_data_record d; + + dbg(1, "reading memory"); + gbser_write(fd, read_update_data_command, sizeof(read_update_data_command)); - dbg(1, "reading memory"); - gbser_write(fd, read_update_data_command, sizeof(read_update_data_command)); - - itracku_device_update_data_init(); + itracku_device_update_data_init(); - while (itracku_device_update_data_read(&d, sizeof(d))) - { - if (itracku_is_valid_data_record(&d)) { - if (import_data_record(&d)) { - waypt_add(to_waypoint(&d)); - } - } - } + while (itracku_device_update_data_read(&d, sizeof(d))) { + if (itracku_is_valid_data_record(&d)) { + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } + } } static void itracku_file_read_data_record(gbfile* fin, itracku_data_record* d) { - gbfread(d, sizeof(*d), 1, fin); + gbfread(d, sizeof(*d), 1, fin); } static gbuint32 itracku_file_read_last_time(gbfile* fin) { - itracku_data_record d; - gbsize_t s; - s = sizeof(itracku_data_record); - gbfseek(fin, 0, SEEK_END); - if (gbftell(fin) < s) - { - return 0; - } - gbfseek(fin, -(int)s, SEEK_END); - itracku_file_read_data_record(fin, &d); - return (gbuint32) le_read32(d.creation_time); + itracku_data_record d; + gbsize_t s; + s = sizeof(itracku_data_record); + gbfseek(fin, 0, SEEK_END); + if (gbftell(fin) < s) { + return 0; + } + gbfseek(fin, -(int)s, SEEK_END); + itracku_file_read_data_record(fin, &d); + return (gbuint32) le_read32(d.creation_time); } static void itracku_file_read_waypts(gbfile* fin, void (*waypt_add)(waypoint *wpt)) { - itracku_data_record d; + itracku_data_record d; - while (gbfread(&d, sizeof(d), 1, fin)) - { - if (le_read32(d.longitude) == -1) { - continue; - } - if (import_data_record(&d)) { - waypt_add(to_waypoint(&d)); - } - } + while (gbfread(&d, sizeof(d), 1, fin)) { + if (le_read32(d.longitude) == -1) { + continue; + } + if (import_data_record(&d)) { + waypt_add(to_waypoint(&d)); + } + } } static void itracku_file_write_waypt(gbfile* fout, const waypoint *wpt) { - itracku_data_record d; - to_itracku_data_record(wpt, &d); - gbfwrite(&d, sizeof(d), 1, fout); + itracku_data_record d; + to_itracku_data_record(wpt, &d); + gbfwrite(&d, sizeof(d), 1, fout); } static void itracku_waypt_input(void (*waypt_add)(waypoint *wpt)) { - if (fd) - { - itracku_device_dump_waypts(fd, waypt_add); - } - else - { - itracku_file_read_waypts(fin, waypt_add); - } + if (fd) { + itracku_device_dump_waypts(fd, waypt_add); + } else { + itracku_file_read_waypts(fin, waypt_add); + } } static void itracku_read_waypt(void) { - itracku_waypt_input(&waypt_add); + itracku_waypt_input(&waypt_add); } static route_head* itracku_read_trk_track; @@ -617,57 +592,57 @@ static route_head* itracku_read_trk_track; static void itracku_read_trk_waypt_add(waypoint *wpt) { - track_add_wpt(itracku_read_trk_track, wpt); + track_add_wpt(itracku_read_trk_track, wpt); } static void itracku_read_trk(void) { - itracku_read_trk_track = route_head_alloc(); - track_add_head(itracku_read_trk_track); - itracku_waypt_input(&itracku_read_trk_waypt_add); + itracku_read_trk_track = route_head_alloc(); + track_add_head(itracku_read_trk_track); + itracku_waypt_input(&itracku_read_trk_waypt_add); } static void itracku_read(void) { - switch(global_opts.objective) { - case wptdata: - itracku_read_waypt(); - break; - case trkdata: - itracku_read_trk(); - break; - case rtedata: - fatal(MYNAME ": reading routes is not supported.\n"); - break; - case posndata: - break; - } -} - + switch (global_opts.objective) { + case wptdata: + itracku_read_waypt(); + break; + case trkdata: + itracku_read_trk(); + break; + case rtedata: + fatal(MYNAME ": reading routes is not supported.\n"); + break; + case posndata: + break; + } +} + static void itracku_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); } static void itracku_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void itracku_output_waypoint(const waypoint * wp) { - itracku_file_write_waypt(fout, wp); + itracku_file_write_waypt(fout, wp); } static void itracku_write(void) { - waypt_disp_all(itracku_output_waypoint); + waypt_disp_all(itracku_output_waypoint); } static void @@ -678,85 +653,83 @@ itracku_exit(void) /* optional */ static void itracku_rt_init(const char *fname) { - itracku_rd_ser_init(fname); - itracku_device_write_string("WP AP-Exit"); + itracku_rd_ser_init(fname); + itracku_device_write_string("WP AP-Exit"); } static void nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) { - if (time->tm_year == 0) - { - wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use == 0) - { - wpt->wpt_flags.fmt_use = 1; - } - } - else - { - wpt->creation_time = mkgmtime(time); - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use != 0) - { - wpt->wpt_flags.fmt_use = 0; - } - } + if (time->tm_year == 0) { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) { + wpt->wpt_flags.fmt_use = 1; + } + } else { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) { + wpt->wpt_flags.fmt_use = 0; + } + } } static waypoint * gprmc_parse(char *ibuf) { - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - char fix; - unsigned int dmy; - double speed,course; - waypoint *waypt; - double microseconds; - struct tm tm; + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint *waypt; + double microseconds; + struct tm tm; + + int rc = sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course, &dmy); - int rc = sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf,%u", - &hms, &fix, &latdeg, &latdir, - &lngdeg, &lngdir, - &speed, &course, &dmy); + if (rc == 0) { + return NULL; + } - if (rc == 0) - { - return NULL; - } + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; - tm.tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; - waypt = waypt_new(); + waypt = waypt_new(); - WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); - WAYPT_SET(waypt, course, course); - - nmea_set_waypoint_time(waypt, &tm, microseconds); + WAYPT_SET(waypt, course, course); - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); + nmea_set_waypoint_time(waypt, &tm, microseconds); - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); - return waypt; + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + return waypt; } /* @@ -769,69 +742,67 @@ gprmc_parse(char *ibuf) static waypoint * itracku_rt_position(posn_status *posn_status) { - char line[1024]; - waypoint* wpt; - while (1) - { - gbser_read_line(fd, line, sizeof(line), 5000, 13, 10); - dbg(1, line); - wpt = gprmc_parse(line); - if (wpt) - { - return wpt; - } - } + char line[1024]; + waypoint* wpt; + while (1) { + gbser_read_line(fd, line, sizeof(line), 5000, 13, 10); + dbg(1, line); + wpt = gprmc_parse(line); + if (wpt) { + return wpt; + } + } } static void itracku_rt_deinit(void) { - itracku_rd_deinit(); + itracku_rd_deinit(); } /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// please change this depending on your new module +// please change this depending on your new module ff_vecs_t itracku_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - itracku_rd_ser_init, - NULL, - itracku_rd_deinit, - NULL, - itracku_read, - itracku_write, - itracku_exit, - itracku_args, - CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ - { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL } + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_ser_init, + NULL, + itracku_rd_deinit, + NULL, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { itracku_rt_init, itracku_rt_position, itracku_rt_deinit, NULL, NULL, NULL } }; ff_vecs_t itracku_fvecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - itracku_rd_init, - itracku_wr_init, - itracku_rd_deinit, - itracku_wr_deinit, - itracku_read, - itracku_write, - itracku_exit, - itracku_args, - CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ - { NULL, NULL, NULL, NULL, NULL, NULL } + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + itracku_rd_init, + itracku_wr_init, + itracku_rd_deinit, + itracku_wr_deinit, + itracku_read, + itracku_write, + itracku_exit, + itracku_args, + CET_CHARSET_ASCII, 0, /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ + { NULL, NULL, NULL, NULL, NULL, NULL } }; diff --git a/gpsbabel/jeeps/garminusb.h b/gpsbabel/jeeps/garminusb.h index a05f9c15d..44cd53481 100644 --- a/gpsbabel/jeeps/garminusb.h +++ b/gpsbabel/jeeps/garminusb.h @@ -23,35 +23,35 @@ /* This structure is a bit funny looking to avoid variable length * arrays which aren't present in C89. This contains the visible * fields in the USB packets of the Garmin USB receivers (60C, 76C, etc.) - * All data are little endian. + * All data are little endian. */ -typedef +typedef union { - struct { - unsigned char type; - unsigned char reserved1; - unsigned char reserved2; - unsigned char reserved3; - unsigned char pkt_id[2]; - unsigned char reserved6; - unsigned char reserved7; - unsigned char datasz[4]; - unsigned char databuf[1]; /* actually an variable length array... */ - } gusb_pkt; - unsigned char dbuf[1024]; + struct { + unsigned char type; + unsigned char reserved1; + unsigned char reserved2; + unsigned char reserved3; + unsigned char pkt_id[2]; + unsigned char reserved6; + unsigned char reserved7; + unsigned char datasz[4]; + unsigned char databuf[1]; /* actually an variable length array... */ + } gusb_pkt; + unsigned char dbuf[1024]; } garmin_usb_packet; /* - * Internal interfaces that are common regardless of underlying - * OS implementation. + * Internal interfaces that are common regardless of underlying + * OS implementation. */ #define GUSB_MAX_UNITS 20 struct garmin_unit_info { - unsigned long serial_number; - unsigned long unit_id; - unsigned long unit_version; - char *os_identifier; /* In case the OS has another name for it. */ - char *product_identifier; /* From the hardware itself. */ + unsigned long serial_number; + unsigned long unit_id; + unsigned long unit_version; + char *os_identifier; /* In case the OS has another name for it. */ + char *product_identifier; /* From the hardware itself. */ } garmin_unit_info[GUSB_MAX_UNITS]; int gusb_cmd_send(const garmin_usb_packet *obuf, size_t sz); @@ -63,5 +63,5 @@ int gusb_close(gpsdevh *); * New packet types in USB. */ #define GUSB_SESSION_START 5 /* We request units attention */ -#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ +#define GUSB_SESSION_ACK 6 /* Unit responds that we have its attention */ #define GUSB_REQUEST_BULK 2 /* Unit requests we read from bulk pipe */ diff --git a/gpsbabel/jeeps/gps.h b/gpsbabel/jeeps/gps.h index ed9d2dacb..48c0e9136 100644 --- a/gpsbabel/jeeps/gps.h +++ b/gpsbabel/jeeps/gps.h @@ -28,23 +28,21 @@ extern "C" #define ETX 0x03 -extern int32 gps_errno; -extern int32 gps_warning; -extern int32 gps_error; -extern int32 gps_user; -extern int32 gps_show_bytes; -extern char gps_categories[16][17]; + extern int32 gps_errno; + extern int32 gps_warning; + extern int32 gps_error; + extern int32 gps_user; + extern int32 gps_show_bytes; + extern char gps_categories[16][17]; -typedef struct GPS_SPacket -{ + typedef struct GPS_SPacket { US type; uint32 n; UC *data; -} GPS_OPacket, *GPS_PPacket; + } GPS_OPacket, *GPS_PPacket; -typedef struct GPS_Serial_SPacket -{ + typedef struct GPS_Serial_SPacket { UC dle; UC type; UC n; @@ -52,20 +50,18 @@ typedef struct GPS_Serial_SPacket UC chk; UC edle; UC etx; -} GPS_Serial_OPacket, *GPS_Serial_PPacket; + } GPS_Serial_OPacket, *GPS_Serial_PPacket; -typedef struct GPS_SProduct_Data_Type -{ + typedef struct GPS_SProduct_Data_Type { int16 id; int16 version; char desc[MAX_GPS_PACKET_SIZE]; -} GPS_OProduct_Data_Type, *GPS_PProduct_Data_Type; + } GPS_OProduct_Data_Type, *GPS_PProduct_Data_Type; -typedef struct GPS_SPvt_Data_Type -{ + typedef struct GPS_SPvt_Data_Type { float alt; float epe; float eph; @@ -80,12 +76,11 @@ typedef struct GPS_SPvt_Data_Type float msl_hght; int16 leap_scnds; int32 wn_days; -} GPS_OPvt_Data, *GPS_PPvt_Data; + } GPS_OPvt_Data, *GPS_PPvt_Data; -typedef struct GPS_STrack -{ + typedef struct GPS_STrack { double lat; /* Degrees */ double lon; /* Degrees */ time_t Time; /* Unix time */ @@ -104,13 +99,12 @@ typedef struct GPS_STrack float distance; /* distance traveled in meters.*/ int distance_populated; /* True if above is valid. */ char trk_ident[256]; /* Track identifier */ -} -GPS_OTrack, *GPS_PTrack; + } + GPS_OTrack, *GPS_PTrack; -typedef struct GPS_SAlmanac -{ + typedef struct GPS_SAlmanac { UC svid; int16 wn; float toa; @@ -124,11 +118,10 @@ typedef struct GPS_SAlmanac float odot; float i; UC hlth; -} GPS_OAlmanac, *GPS_PAlmanac; + } GPS_OAlmanac, *GPS_PAlmanac; -typedef struct GPS_SWay -{ + typedef struct GPS_SWay { char ident[256]; double lat; double lon; @@ -169,48 +162,46 @@ typedef struct GPS_SWay char temperature_populated; float temperature; /* Degrees celsius. */ uint16 category; - -} GPS_OWay, *GPS_PWay; - -/* - * Forerunner/Edge Lap data. - */ -typedef struct GPS_SLap { - uint32 index; /* unique index in device or -1 */ - time_t start_time; - uint32 total_time; /* Hundredths of a second */ - float total_distance; /* In meters */ - double begin_lat; - double begin_lon; - double end_lat; - double end_lon; - int16 calories; - uint32 track_index; /* ref to track or -1 */ - float max_speed; /* In meters per second */ - unsigned char avg_heart_rate; /* In beats-per-minute, 0 if invalid */ - unsigned char max_heart_rate; /* In beats-per-minute, 0 if invalid */ - unsigned char intensity; /* Same as D1001 */ - unsigned char avg_cadence; /* In revolutions-per-minute, 0xFF if invalid */ - unsigned char trigger_method; - /*Some D1015 unknown */ - /* unsigned char unk1015_1; - int16 unk1015_2; - int16 unk1015_3; - */ -} GPS_OLap, *GPS_PLap; - - -typedef struct GPS_SCourse -{ + + } GPS_OWay, *GPS_PWay; + + /* + * Forerunner/Edge Lap data. + */ + typedef struct GPS_SLap { + uint32 index; /* unique index in device or -1 */ + time_t start_time; + uint32 total_time; /* Hundredths of a second */ + float total_distance; /* In meters */ + double begin_lat; + double begin_lon; + double end_lat; + double end_lon; + int16 calories; + uint32 track_index; /* ref to track or -1 */ + float max_speed; /* In meters per second */ + unsigned char avg_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char max_heart_rate; /* In beats-per-minute, 0 if invalid */ + unsigned char intensity; /* Same as D1001 */ + unsigned char avg_cadence; /* In revolutions-per-minute, 0xFF if invalid */ + unsigned char trigger_method; + /*Some D1015 unknown */ + /* unsigned char unk1015_1; + int16 unk1015_2; + int16 unk1015_3; + */ + } GPS_OLap, *GPS_PLap; + + + typedef struct GPS_SCourse { uint32 index; /* Unique among courses on device */ char course_name[16]; /* Null-terminated unique course name */ uint32 track_index; /* Index of the associated track * Must be 0xFFFFFFFF if there is none*/ -} GPS_OCourse, *GPS_PCourse; + } GPS_OCourse, *GPS_PCourse; -typedef struct GPS_SCourse_Lap -{ + typedef struct GPS_SCourse_Lap { uint32 course_index; /* Index of associated course */ uint32 lap_index; /* This lap's index in the course */ uint32 total_time; /* In hundredths of a second */ @@ -224,10 +215,9 @@ typedef struct GPS_SCourse_Lap UC intensity; /* 0=standard, active lap. 1=rest lap in a workout */ UC avg_cadence; /* In revolutions-per-minute */ -} GPS_OCourse_Lap, *GPS_PCourse_Lap; + } GPS_OCourse_Lap, *GPS_PCourse_Lap; -typedef struct GPS_SCourse_Point -{ + typedef struct GPS_SCourse_Point { char name[11]; /* Null-terminated name */ uint32 course_index; /* Index of associated course */ time_t track_point_time; /* Time */ @@ -247,18 +237,17 @@ typedef struct GPS_SCourse_Point * first_category = 13, * hors_category = 14, * sprint = 15 */ -} GPS_OCourse_Point, *GPS_PCourse_Point; + } GPS_OCourse_Point, *GPS_PCourse_Point; -typedef struct GPS_SCourse_Limits -{ + typedef struct GPS_SCourse_Limits { uint32 max_courses; uint32 max_course_laps; uint32 max_course_pnt; uint32 max_course_trk_pnt; -} GPS_OCourse_Limits, *GPS_PCourse_Limits; + } GPS_OCourse_Limits, *GPS_PCourse_Limits; -typedef int (*pcb_fn) (int, struct GPS_SWay **); + typedef int (*pcb_fn)(int, struct GPS_SWay **); #include "gpsdevice.h" #include "gpssend.h" @@ -274,22 +263,22 @@ typedef int (*pcb_fn) (int, struct GPS_SWay **); #include "gpsinput.h" #include "gpsproj.h" -time_t gps_save_time; -double gps_save_lat; -double gps_save_lon; -extern int32 gps_save_id; -extern double gps_save_version; -extern char gps_save_string[GPS_ARB_LEN]; -extern int gps_is_usb; - -extern struct COMMANDDATA COMMAND_ID[2]; -extern struct LINKDATA LINK_ID[3]; -extern struct GPS_MODEL_PROTOCOL GPS_MP[]; - -extern char *gps_marine_sym[]; -extern char *gps_land_sym[]; -extern char *gps_aviation_sym[]; -extern char *gps_16_sym[]; + time_t gps_save_time; + double gps_save_lat; + double gps_save_lon; + extern int32 gps_save_id; + extern double gps_save_version; + extern char gps_save_string[GPS_ARB_LEN]; + extern int gps_is_usb; + + extern struct COMMANDDATA COMMAND_ID[2]; + extern struct LINKDATA LINK_ID[3]; + extern struct GPS_MODEL_PROTOCOL GPS_MP[]; + + extern char *gps_marine_sym[]; + extern char *gps_land_sym[]; + extern char *gps_aviation_sym[]; + extern char *gps_16_sym[]; #endif diff --git a/gpsbabel/jeeps/gpsapp.c b/gpsbabel/jeeps/gpsapp.c index e8b5fc755..21c5f0b39 100644 --- a/gpsbabel/jeeps/gpsapp.c +++ b/gpsbabel/jeeps/gpsapp.c @@ -123,19 +123,23 @@ typedef enum { UpperNo = 0, UpperYes = 1 } copycase; static void copy_char_array(UC **dst, char* src, int count, copycase mustupper) { - UC *d = *dst; - int ocount = count; - do { - UC sc = *src++; - if (sc == 0) { - while (count--) - *d++ = ' '; - break; - } - if (!isalnum(sc)) continue; - else *d++ = mustupper == UpperYes ? toupper(sc) : sc; - } while (--count) ; - *dst += ocount; + UC *d = *dst; + int ocount = count; + do { + UC sc = *src++; + if (sc == 0) { + while (count--) { + *d++ = ' '; + } + break; + } + if (!isalnum(sc)) { + continue; + } else { + *d++ = mustupper == UpperYes ? toupper(sc) : sc; + } + } while (--count) ; + *dst += ocount; } @@ -152,28 +156,30 @@ void copy_char_array(UC **dst, char* src, int count, copycase mustupper) ************************************************************************/ int32 GPS_Init(const char *port) { - int32 ret; - - (void) GPS_Util_Little(); + int32 ret; - ret = GPS_A000(port); - if(ret<0) return ret; - gps_save_time = GPS_Command_Get_Time(port); + (void) GPS_Util_Little(); - /* - * Some units may be unable to return time, such as a C320 when in - * charging mode. Only consider it fatal if the unit returns an error, - * not just absence of returning a time. - */ - if(gps_save_time < 0) { - return FRAMING_ERROR; - } - - if (0 == strncmp(gps_save_string, "GPilotS", 7)) { - return 1; - } + ret = GPS_A000(port); + if (ret<0) { + return ret; + } + gps_save_time = GPS_Command_Get_Time(port); + + /* + * Some units may be unable to return time, such as a C320 when in + * charging mode. Only consider it fatal if the unit returns an error, + * not just absence of returning a time. + */ + if (gps_save_time < 0) { + return FRAMING_ERROR; + } + + if (0 == strncmp(gps_save_string, "GPilotS", 7)) { + return 1; + } - return GPS_Command_Get_Position(port,&gps_save_lat,&gps_save_lon); + return GPS_Command_Get_Position(port,&gps_save_lat,&gps_save_lon); } @@ -187,171 +193,177 @@ int32 GPS_Init(const char *port) ************************************************************************/ static int32 GPS_A000(const char *port) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int16 version; - int16 id; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int16 version; + int16 id; - if(!GPS_Device_On(port, &fd)) - return gps_errno; + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } - if(!GPS_Device_Flush(fd)) - return gps_errno; + if (!GPS_Device_Flush(fd)) { + return gps_errno; + } - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - GPS_Make_Packet(&tra, LINK_ID[0].Pid_Product_Rqst,NULL,0); - if(!GPS_Write_Packet(fd,tra)) - return SERIAL_ERROR; + GPS_Make_Packet(&tra, LINK_ID[0].Pid_Product_Rqst,NULL,0); + if (!GPS_Write_Packet(fd,tra)) { + return SERIAL_ERROR; + } - if(!GPS_Get_Ack(fd, &tra, &rec)) - return SERIAL_ERROR; + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return SERIAL_ERROR; + } - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); - id = GPS_Util_Get_Short(rec->data); - version = GPS_Util_Get_Short((rec->data)+2); + id = GPS_Util_Get_Short(rec->data); + version = GPS_Util_Get_Short((rec->data)+2); - (void) strcpy(gps_save_string,(char *)rec->data+4); - gps_save_id = id; - gps_save_version = (double)((double)version/(double)100.); + (void) strcpy(gps_save_string,(char *)rec->data+4); + gps_save_id = id; + gps_save_version = (double)((double)version/(double)100.); - GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", - gps_save_string, gps_save_id, gps_save_version); + GPS_User("Unit:\t%s\nID:\t%d\nVersion:\t%.2f", + gps_save_string, gps_save_id, gps_save_version); #if 0 - gps_date_time_transfer = pA600; - gps_date_time_type = pD600; /* All models so far */ - gps_position_transfer = pA700; - gps_position_type = pD700; /* All models so far */ + gps_date_time_transfer = pA600; + gps_date_time_type = pD600; /* All models so far */ + gps_position_transfer = pA700; + gps_position_type = pD700; /* All models so far */ #else - gps_date_time_transfer = -1; - gps_date_time_type = -1; - gps_position_transfer = -1; - gps_position_type = -1; + gps_date_time_transfer = -1; + gps_date_time_type = -1; + gps_position_transfer = -1; + gps_position_type = -1; #endif - gps_pvt_transfer = -1; - gps_pvt_type = -1; - gps_trk_transfer = -1; - gps_trk_type = -1; - gps_trk_hdr_type = -1; - gps_rte_link_type = -1; - - gps_waypt_transfer = -1; - gps_waypt_type = -1; - gps_route_transfer = -1; - gps_rte_hdr_type = -1; - gps_rte_type = -1; - - gps_prx_waypt_transfer = -1; - gps_prx_waypt_type = -1; - gps_almanac_transfer = -1; - gps_almanac_type = -1; - - gps_lap_transfer = -1; - gps_lap_type = -1; - gps_run_transfer = -1; - gps_run_type = -1; - gps_run_crs_trk_type = -1; - gps_run_crs_trk_hdr_type = -1; - gps_workout_transfer = -1; - gps_workout_type = -1; - gps_workout_occurrence_type = -1; - gps_user_profile_transfer = -1; - gps_user_profile_type = -1; - gps_workout_limits_transfer = -1; - gps_workout_limits_type = -1; - gps_course_transfer = -1; - gps_course_type = -1; - gps_course_lap_transfer = -1; - gps_course_lap_type = -1; - gps_course_point_transfer = -1; - gps_course_point_type = -1; - gps_course_limits_transfer = -1; - gps_course_limits_type = -1; - gps_course_trk_transfer = -1; - - gps_device_command = -1; - gps_link_type = -1; - - if(!GPS_Device_Wait(fd)) - { - GPS_Warning("A001 protocol not supported"); - id = GPS_Protocol_Version_Change(id,version); - if(GPS_Protocol_Table_Set(id)<0) - return GPS_UNSUPPORTED; - } - else - { - int i; - /* - * The unit may return more than one packet, so read and - * discard all but the product inquiry response. We have - * no way of knowing how many we'll get, so we have to keep - * reading until we incur a timeout. - * Worse still, the serial layer assumes a read timeout is a - * fatal error, while the USB layer (correctly) returns that error - * to the caller. So we call GPS_Device_Wait which spins into - * a delay/select for the serial system and a NOP for USB. - * - * Worse _yet_, this is the one place in all of Garmin Protocolsville - * where we don't know a priori how many packets will be sent in - * response. Since we want the lower levels of the USB handler - * to handle the ugliness of the "return to interrupt" packets, we - * reach behind that automation here and hand that ourselves. - */ - for (i = 0; i < 25; i++) { - rec->type = 0; - - if (gps_is_usb) { - GPS_Packet_Read_usb(fd, &rec, 0); - } else { - if(!GPS_Device_Wait(fd)) - goto carry_on; - - if (GPS_Packet_Read(fd, &rec) <= 0) { - goto carry_on; - } - - GPS_Send_Ack(fd, &tra, &rec); - } - - if (rec->type == 0xfd) { - GPS_A001(rec); - goto carry_on; - } - - /* - * If a 296 has previously been interrupted, it's going to - * ignore the session request (grrrr) and continue to send - * us left over packets. So if we see anything that isn't - * part of our A000 discovery cycle, reset the counter and - * continue to loop. - * - * Garmin acknowledges this is a firmware defect. - */ - if (rec->type < 0xf8) { - i = 0; - } - } - fatal("Failed to find a product inquiry response.\n"); + gps_pvt_transfer = -1; + gps_pvt_type = -1; + gps_trk_transfer = -1; + gps_trk_type = -1; + gps_trk_hdr_type = -1; + gps_rte_link_type = -1; + + gps_waypt_transfer = -1; + gps_waypt_type = -1; + gps_route_transfer = -1; + gps_rte_hdr_type = -1; + gps_rte_type = -1; + + gps_prx_waypt_transfer = -1; + gps_prx_waypt_type = -1; + gps_almanac_transfer = -1; + gps_almanac_type = -1; + + gps_lap_transfer = -1; + gps_lap_type = -1; + gps_run_transfer = -1; + gps_run_type = -1; + gps_run_crs_trk_type = -1; + gps_run_crs_trk_hdr_type = -1; + gps_workout_transfer = -1; + gps_workout_type = -1; + gps_workout_occurrence_type = -1; + gps_user_profile_transfer = -1; + gps_user_profile_type = -1; + gps_workout_limits_transfer = -1; + gps_workout_limits_type = -1; + gps_course_transfer = -1; + gps_course_type = -1; + gps_course_lap_transfer = -1; + gps_course_lap_type = -1; + gps_course_point_transfer = -1; + gps_course_point_type = -1; + gps_course_limits_transfer = -1; + gps_course_limits_type = -1; + gps_course_trk_transfer = -1; + + gps_device_command = -1; + gps_link_type = -1; + + if (!GPS_Device_Wait(fd)) { + GPS_Warning("A001 protocol not supported"); + id = GPS_Protocol_Version_Change(id,version); + if (GPS_Protocol_Table_Set(id)<0) { + return GPS_UNSUPPORTED; + } + } else { + int i; + /* + * The unit may return more than one packet, so read and + * discard all but the product inquiry response. We have + * no way of knowing how many we'll get, so we have to keep + * reading until we incur a timeout. + * Worse still, the serial layer assumes a read timeout is a + * fatal error, while the USB layer (correctly) returns that error + * to the caller. So we call GPS_Device_Wait which spins into + * a delay/select for the serial system and a NOP for USB. + * + * Worse _yet_, this is the one place in all of Garmin Protocolsville + * where we don't know a priori how many packets will be sent in + * response. Since we want the lower levels of the USB handler + * to handle the ugliness of the "return to interrupt" packets, we + * reach behind that automation here and hand that ourselves. + */ + for (i = 0; i < 25; i++) { + rec->type = 0; + + if (gps_is_usb) { + GPS_Packet_Read_usb(fd, &rec, 0); + } else { + if (!GPS_Device_Wait(fd)) { + goto carry_on; + } + + if (GPS_Packet_Read(fd, &rec) <= 0) { + goto carry_on; + } + + GPS_Send_Ack(fd, &tra, &rec); + } + + if (rec->type == 0xfd) { + GPS_A001(rec); + goto carry_on; + } + + /* + * If a 296 has previously been interrupted, it's going to + * ignore the session request (grrrr) and continue to send + * us left over packets. So if we see anything that isn't + * part of our A000 discovery cycle, reset the counter and + * continue to loop. + * + * Garmin acknowledges this is a firmware defect. + */ + if (rec->type < 0xf8) { + i = 0; + } } + fatal("Failed to find a product inquiry response.\n"); + } carry_on: - /* Make sure PVT is off as some GPS' have it on by default */ - if(gps_pvt_transfer != -1) - GPS_A800_Off(port,&fd); + /* Make sure PVT is off as some GPS' have it on by default */ + if (gps_pvt_transfer != -1) { + GPS_A800_Off(port,&fd); + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -368,426 +380,467 @@ carry_on: ************************************************************************/ static void GPS_A001(GPS_PPacket packet) { - int32 entries; - int32 i; - UC *p; - US tag; - US data; - US lasta=0; - - entries = packet->n / 3; - p = packet->data; - - for(i=0;i=200 && data <=202) - { - gps_rte_hdr_type = data; - continue; - } - if(data==210) - { - gps_rte_link_type = data; - continue; - } - - if(data<=110 && data>=100) - { - gps_rte_type = data; - continue; - } - if(data<153 && data>=150) - { - gps_rte_type = data; - continue; - } - if(data<156 && data>=154) - { - gps_rte_type = data; - continue; - } - if(data<451) - { - if(data==400) - gps_rte_type = pD400; - else if(data==403) - gps_rte_type = pD403; - else if(data==450) - gps_rte_type = pD450; - else - GPS_Protocol_Error(tag,data); - continue; - } - } - - else if(lasta<400) - { - switch (data) { - case 300: gps_trk_type = pD300; break; - case 301: gps_trk_type = pD301; break; - case 302: gps_trk_type = pD302; break; - case 303: gps_trk_type = pD303; break; - case 304: gps_trk_type = pD304; break; - case 310: gps_trk_hdr_type = pD310; break; - case 311: gps_trk_hdr_type = pD311; break; - case 312: gps_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - if (lasta==302 && gps_course_trk_transfer == pA302) - switch (data) { - case 300: gps_run_crs_trk_type = pD300; break; - case 301: gps_run_crs_trk_type = pD301; break; - case 302: gps_run_crs_trk_type = pD302; break; - case 303: gps_run_crs_trk_type = pD303; break; - case 304: gps_run_crs_trk_type = pD304; break; - case 310: gps_run_crs_trk_hdr_type = pD310; break; - case 311: gps_run_crs_trk_hdr_type = pD311; break; - case 312: gps_run_crs_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - continue; - } - - else if(lasta<500) - { - if((data<=110 && data>=100) || - (data<153 && data>=150) || - (data<156 && data>=154)) { - gps_prx_waypt_type = data; - } - else if(data==400) - gps_prx_waypt_type = pD400; - else if(data==403) - gps_prx_waypt_type = pD403; - else if(data==450) - gps_prx_waypt_type = pD450; - else - GPS_Protocol_Error(tag,data); - continue; - } - - else if(lasta<600) - { - if(data==500) - gps_almanac_type = pD500; - else if(data==501) - gps_almanac_type = pD501; - else if(data==550) - gps_almanac_type = pD550; - else if(data==551) - gps_almanac_type = pD551; - else - GPS_Protocol_Error(tag,data); - continue; - } - - else if(lasta<650) - { - if (data == 600) { - gps_date_time_type = pD600; - } else { - /* Stupid undocumented 60 D601 packets */ - /* GPS_Protocol_Error(tag,data); */ - continue; - } - continue; - } - - else if(lasta<651) - { - /* FlightBook Transfer Protocol, not handled */ - continue; - } - - else if(lasta<800) - { - if(data!=700) - GPS_Protocol_Error(tag,data); - else - gps_position_type = pD700; - continue; - } - - else if(lasta<900) - { - if (data == 800) - gps_pvt_type = pD800; - /* - * Stupid, undocumented Vista 3.60 D802 packets - else - GPS_Protocol_Error(tag,data); - */ - continue; - } - - else if (lasta < 1000) - { - if (data == 906) - gps_lap_type = pD906; - else if (data == 1001) - gps_lap_type = pD1001; - else if (data == 1011) - gps_lap_type = pD1011; - else if (data == 1015) - gps_lap_type = pD1015; - continue; - } - - else if (lasta < 1002) - { - if (data == 1000) - gps_run_type = pD1000; - else if (data == 1009) - gps_run_type = pD1009; - else if (data == 1010) - gps_run_type = pD1010; - continue; - } - - else if (lasta < 1003) - { - if (data == 1002) - gps_workout_type = pD1002; - else if (data == 1008) - gps_workout_type = pD1008; - continue; - } - - else if (lasta < 1004) - { - if (data == 1003) - gps_workout_occurrence_type = pD1003; - continue; - } - - else if (lasta < 1005) - { - if (data == 1004) - gps_user_profile_type = pD1004; - continue; - } - - else if (lasta < 1006) - { - if (data == 1005) - gps_workout_limits_type = pD1005; - continue; - } - - else if (lasta < 1007) - { - if (data == 1006) - gps_course_type = pD1006; - continue; - } - - else if (lasta < 1008) - { - if (data == 1007) - gps_course_lap_type = pD1007; - continue; - } - - else if (lasta < 1009) - { - if (data == 1012) - gps_course_point_type = pD1012; - continue; - } - - else if (lasta < 1010) - { - if (data == 1013) - gps_course_limits_type = pD1013; - continue; - } - else if (lasta == 1012) - { - /* We don't know which data types to expect for A1012. For now, - * accept the same ones as for A302 since it is used as a - * replacement for this. - */ - switch (data) { - case 300: gps_run_crs_trk_type = pD300; break; - case 301: gps_run_crs_trk_type = pD301; break; - case 302: gps_run_crs_trk_type = pD302; break; - case 303: gps_run_crs_trk_type = pD303; break; - case 304: gps_run_crs_trk_type = pD304; break; - case 310: gps_run_crs_trk_hdr_type = pD310; break; - case 311: gps_run_crs_trk_hdr_type = pD311; break; - case 312: gps_run_crs_trk_hdr_type = pD312; break; - default: GPS_Protocol_Error(tag,data); break; - } - continue; - } - } - } - - GPS_User("\nLink_type %d Device_command %d\n", - gps_link_type, gps_device_command); - GPS_User("Waypoint: Transfer %d Type %d\n", - gps_waypt_transfer, gps_waypt_type); - GPS_User("Route: Transfer %d Header %d Type %d\n", - gps_route_transfer, gps_rte_hdr_type, gps_rte_type); - GPS_User("Track: Transfer %d Type %d\n", - gps_trk_transfer, gps_trk_type); + int32 entries; + int32 i; + UC *p; + US tag; + US data; + US lasta=0; + + entries = packet->n / 3; + p = packet->data; + + for (i=0; i=200 && data <=202) { + gps_rte_hdr_type = data; + continue; + } + if (data==210) { + gps_rte_link_type = data; + continue; + } + + if (data<=110 && data>=100) { + gps_rte_type = data; + continue; + } + if (data<153 && data>=150) { + gps_rte_type = data; + continue; + } + if (data<156 && data>=154) { + gps_rte_type = data; + continue; + } + if (data<451) { + if (data==400) { + gps_rte_type = pD400; + } else if (data==403) { + gps_rte_type = pD403; + } else if (data==450) { + gps_rte_type = pD450; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + } + + else if (lasta<400) { + switch (data) { + case 300: + gps_trk_type = pD300; + break; + case 301: + gps_trk_type = pD301; + break; + case 302: + gps_trk_type = pD302; + break; + case 303: + gps_trk_type = pD303; + break; + case 304: + gps_trk_type = pD304; + break; + case 310: + gps_trk_hdr_type = pD310; + break; + case 311: + gps_trk_hdr_type = pD311; + break; + case 312: + gps_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + if (lasta==302 && gps_course_trk_transfer == pA302) + switch (data) { + case 300: + gps_run_crs_trk_type = pD300; + break; + case 301: + gps_run_crs_trk_type = pD301; + break; + case 302: + gps_run_crs_trk_type = pD302; + break; + case 303: + gps_run_crs_trk_type = pD303; + break; + case 304: + gps_run_crs_trk_type = pD304; + break; + case 310: + gps_run_crs_trk_hdr_type = pD310; + break; + case 311: + gps_run_crs_trk_hdr_type = pD311; + break; + case 312: + gps_run_crs_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + continue; + } + + else if (lasta<500) { + if ((data<=110 && data>=100) || + (data<153 && data>=150) || + (data<156 && data>=154)) { + gps_prx_waypt_type = data; + } else if (data==400) { + gps_prx_waypt_type = pD400; + } else if (data==403) { + gps_prx_waypt_type = pD403; + } else if (data==450) { + gps_prx_waypt_type = pD450; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + + else if (lasta<600) { + if (data==500) { + gps_almanac_type = pD500; + } else if (data==501) { + gps_almanac_type = pD501; + } else if (data==550) { + gps_almanac_type = pD550; + } else if (data==551) { + gps_almanac_type = pD551; + } else { + GPS_Protocol_Error(tag,data); + } + continue; + } + + else if (lasta<650) { + if (data == 600) { + gps_date_time_type = pD600; + } else { + /* Stupid undocumented 60 D601 packets */ + /* GPS_Protocol_Error(tag,data); */ + continue; + } + continue; + } + + else if (lasta<651) { + /* FlightBook Transfer Protocol, not handled */ + continue; + } + + else if (lasta<800) { + if (data!=700) { + GPS_Protocol_Error(tag,data); + } else { + gps_position_type = pD700; + } + continue; + } + + else if (lasta<900) { + if (data == 800) { + gps_pvt_type = pD800; + } + /* + * Stupid, undocumented Vista 3.60 D802 packets + else + GPS_Protocol_Error(tag,data); + */ + continue; + } + + else if (lasta < 1000) { + if (data == 906) { + gps_lap_type = pD906; + } else if (data == 1001) { + gps_lap_type = pD1001; + } else if (data == 1011) { + gps_lap_type = pD1011; + } else if (data == 1015) { + gps_lap_type = pD1015; + } + continue; + } + + else if (lasta < 1002) { + if (data == 1000) { + gps_run_type = pD1000; + } else if (data == 1009) { + gps_run_type = pD1009; + } else if (data == 1010) { + gps_run_type = pD1010; + } + continue; + } + + else if (lasta < 1003) { + if (data == 1002) { + gps_workout_type = pD1002; + } else if (data == 1008) { + gps_workout_type = pD1008; + } + continue; + } + + else if (lasta < 1004) { + if (data == 1003) { + gps_workout_occurrence_type = pD1003; + } + continue; + } + + else if (lasta < 1005) { + if (data == 1004) { + gps_user_profile_type = pD1004; + } + continue; + } + + else if (lasta < 1006) { + if (data == 1005) { + gps_workout_limits_type = pD1005; + } + continue; + } + + else if (lasta < 1007) { + if (data == 1006) { + gps_course_type = pD1006; + } + continue; + } + + else if (lasta < 1008) { + if (data == 1007) { + gps_course_lap_type = pD1007; + } + continue; + } + + else if (lasta < 1009) { + if (data == 1012) { + gps_course_point_type = pD1012; + } + continue; + } + + else if (lasta < 1010) { + if (data == 1013) { + gps_course_limits_type = pD1013; + } + continue; + } else if (lasta == 1012) { + /* We don't know which data types to expect for A1012. For now, + * accept the same ones as for A302 since it is used as a + * replacement for this. + */ + switch (data) { + case 300: + gps_run_crs_trk_type = pD300; + break; + case 301: + gps_run_crs_trk_type = pD301; + break; + case 302: + gps_run_crs_trk_type = pD302; + break; + case 303: + gps_run_crs_trk_type = pD303; + break; + case 304: + gps_run_crs_trk_type = pD304; + break; + case 310: + gps_run_crs_trk_hdr_type = pD310; + break; + case 311: + gps_run_crs_trk_hdr_type = pD311; + break; + case 312: + gps_run_crs_trk_hdr_type = pD312; + break; + default: + GPS_Protocol_Error(tag,data); + break; + } + continue; + } + } + } + + GPS_User("\nLink_type %d Device_command %d\n", + gps_link_type, gps_device_command); + GPS_User("Waypoint: Transfer %d Type %d\n", + gps_waypt_transfer, gps_waypt_type); + GPS_User("Route: Transfer %d Header %d Type %d\n", + gps_route_transfer, gps_rte_hdr_type, gps_rte_type); + GPS_User("Track: Transfer %d Type %d\n", + gps_trk_transfer, gps_trk_type); + + return; } @@ -804,146 +857,145 @@ static void GPS_A001(GPS_PPacket packet) ************************************************************************/ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - - if(!GPS_Write_Packet(fd,tra)) - { - GPS_Error("A100_Get: Cannot write packet"); - return FRAMING_ERROR; - } - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A100_Get: No acknowledge"); - return FRAMING_ERROR; - } - - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A100_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data, 109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data, 110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); - return PROTOCOL_ERROR; - } - /* Issue callback for status updates. */ - if (cb) { - cb(n, &((*way)[i])); - } - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A100_GET: Waypoint entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if (!GPS_Write_Packet(fd,tra)) { + GPS_Error("A100_Get: Cannot write packet"); + return FRAMING_ERROR; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A100_Get: No acknowledge"); + return FRAMING_ERROR; + } + + GPS_Packet_Read(fd, &rec); + GPS_Send_Ack(fd, &tra, &rec); + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A100_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + for (i=0; idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data, 109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data, 110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A100_GET: Unknown waypoint protocol: %d", gps_waypt_type); + return PROTOCOL_ERROR; + } + /* Issue callback for status updates. */ + if (cb) { + cb(n, &((*way)[i])); + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A100_GET: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A100_GET: Waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -962,124 +1014,126 @@ int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int, GPS_PWay *)) ************************************************************************/ int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, (short) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("Waypoint start data not acknowledged"); - return gps_errno; - } - - - for(i=0;idata); + for (i = 0; i < n; ++i) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A101_Get: No acknowledge"); - return FRAMING_ERROR; + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } - - GPS_Packet_Read(fd, &rec); - GPS_Send_Ack(fd, &tra, &rec); - - n = GPS_Util_Get_Short(rec->data); - for (i = 0; i < n; ++i) { - if(!GPS_Packet_Read(fd, &rec)) { - return gps_errno; - } - if(!GPS_Send_Ack(fd, &tra, &rec)) { - return gps_errno; - } - switch(gps_category_type) { - case pD120: - GPS_D120_Get(i,(char *) rec->data); - break; - } + switch (gps_category_type) { + case pD120: + GPS_D120_Get(i,(char *) rec->data); + break; } - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; + } + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); - return FRAMING_ERROR; - } + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A101_Get: Error transferring waypoints. Expected %d completion code. Got %d. %d of %d received", LINK_ID[gps_link_type].Pid_Xfer_Cmplt, rec->type, i, n); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -1166,25 +1222,29 @@ int32 GPS_A101_Get(const char *port) ************************************************************************/ static void GPS_D100_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 100; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 100; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - return; + return; } @@ -1200,30 +1260,34 @@ static void GPS_D100_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D101_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 101; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 101; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = *p; + (*way)->smbl = *p; - return; + return; } @@ -1239,31 +1303,35 @@ static void GPS_D101_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D102_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 102; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 102; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = GPS_Util_Get_Short(p); + (*way)->smbl = GPS_Util_Get_Short(p); - return; + return; } @@ -1279,29 +1347,33 @@ static void GPS_D102_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D103_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 103; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 103; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p; + (*way)->smbl = *p++; + (*way)->dspl = *p; - return; + return; } @@ -1317,33 +1389,37 @@ static void GPS_D103_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D104_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 104; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 104; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*way)->dspl = *p; + (*way)->dspl = *p; - return; + return; } @@ -1359,26 +1435,26 @@ static void GPS_D104_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D105_Get(GPS_PWay *way, UC *s) { - UC *p; - UC *q; + UC *p; + UC *q; - p=s; + p=s; - (*way)->prot = 105; + (*way)->prot = 105; - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - q = (UC *) (*way)->wpt_ident; - while((*q++ = *p++)); + q = (UC *)(*way)->wpt_ident; + while ((*q++ = *p++)); - return; + return; } @@ -1394,33 +1470,35 @@ static void GPS_D105_Get(GPS_PWay *way, UC *s) ************************************************************************/ void GPS_D106_Get(GPS_PWay *way, UC *s) { - UC *p; - UC *q; - int32 i; + UC *p; + UC *q; + int32 i; - p=s; + p=s; - (*way)->prot = 106; + (*way)->prot = 106; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - for(i=0;i<13;++i) (*way)->subclass[i] = *p++; + for (i=0; i<13; ++i) { + (*way)->subclass[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - q = (UC *) (*way)->wpt_ident; - while((*q++ = *p++)); - q = (UC *) (*way)->lnk_ident; - while((*q++ = *p++)); + q = (UC *)(*way)->wpt_ident; + while ((*q++ = *p++)); + q = (UC *)(*way)->lnk_ident; + while ((*q++ = *p++)); - return; + return; } @@ -1436,33 +1514,37 @@ void GPS_D106_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D107_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 107; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 107; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p++; + (*way)->smbl = *p++; + (*way)->dspl = *p++; - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*way)->colour = *p++; + (*way)->colour = *p++; - return; + return; } @@ -1478,58 +1560,64 @@ static void GPS_D107_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D108_Get(GPS_PWay *way, UC *s) { - UC *p; - UC *q; + UC *p; + UC *q; - int32 i; + int32 i; - p=s; + p=s; - (*way)->prot = 108; + (*way)->prot = 108; - (*way)->wpt_class = *p++; - (*way)->colour = *p++; - (*way)->dspl = *p++; - (*way)->attr = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->subclass[i] = *p++; + (*way)->wpt_class = *p++; + (*way)->colour = *p++; + (*way)->dspl = *p++; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->subclass[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - q = (UC *) (*way)->ident; - while((*q++ = *p++)); + q = (UC *)(*way)->ident; + while ((*q++ = *p++)); - q = (UC *) (*way)->cmnt; - while((*q++ = *p++)); + q = (UC *)(*way)->cmnt; + while ((*q++ = *p++)); - q = (UC *) (*way)->facility; - while((*q++ = *p++)); + q = (UC *)(*way)->facility; + while ((*q++ = *p++)); - q = (UC *) (*way)->city; - while((*q++ = *p++)); + q = (UC *)(*way)->city; + while ((*q++ = *p++)); - q = (UC *) (*way)->addr; - while((*q++ = *p++)); + q = (UC *)(*way)->addr; + while ((*q++ = *p++)); - q = (UC *) (*way)->cross_road; - while((*q++ = *p++)); + q = (UC *)(*way)->cross_road; + while ((*q++ = *p++)); - return; + return; } /* @funcstatic GPS_D109_Get ******************************************** @@ -1546,83 +1634,89 @@ static void GPS_D108_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) { - UC *p; - UC *q; - - int32 i; - - p=s; - - (*way)->prot = protoid; - - p++; /* data packet type */ - (*way)->wpt_class = *p++; - (*way)->colour = *p & 0x1f; - (*way)->dspl = (*p++ >> 5) & 3; - (*way)->attr = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->subclass[i] = *p++; - - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); - - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - - p += 4; /* Skip over "outbound link ete in seconds */ - if (protoid == 110) { - float gps_temp; - int gps_time; - gps_temp = GPS_Util_Get_Float(p); - p+=4; - if (gps_temp <= 1.0e24) { - (*way)->temperature_populated = 1; - (*way)->temperature = gps_temp; - } + UC *p; + UC *q; + + int32 i; + + p=s; + + (*way)->prot = protoid; + + p++; /* data packet type */ + (*way)->wpt_class = *p++; + (*way)->colour = *p & 0x1f; + (*way)->dspl = (*p++ >> 5) & 3; + (*way)->attr = *p++; + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->subclass[i] = *p++; + } + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + + p += 4; /* Skip over "outbound link ete in seconds */ + if (protoid == 110) { + float gps_temp; + int gps_time; + gps_temp = GPS_Util_Get_Float(p); + p+=4; + if (gps_temp <= 1.0e24) { + (*way)->temperature_populated = 1; + (*way)->temperature = gps_temp; + } - gps_time = GPS_Util_Get_Uint(p); - p+=4; - /* The spec says that 0xffffffff is unknown, but the 60CSX with - * firmware 2.5.0 writes zero. - */ - if (gps_time != 0xffffffff && gps_time != 0) { - (*way)->time_populated = 1; - (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); - } - (*way)->category = GPS_Util_Get_Short(p); - p += 2; + gps_time = GPS_Util_Get_Uint(p); + p+=4; + /* The spec says that 0xffffffff is unknown, but the 60CSX with + * firmware 2.5.0 writes zero. + */ + if (gps_time != 0xffffffff && gps_time != 0) { + (*way)->time_populated = 1; + (*way)->time = GPS_Math_Gtime_To_Utime(gps_time); } + (*way)->category = GPS_Util_Get_Short(p); + p += 2; + } - q = (UC *) (*way)->ident; - while((*q++ = *p++)); + q = (UC *)(*way)->ident; + while ((*q++ = *p++)); - q = (UC *) (*way)->cmnt; - while((*q++ = *p++)); + q = (UC *)(*way)->cmnt; + while ((*q++ = *p++)); - q = (UC *) (*way)->facility; - while((*q++ = *p++)); + q = (UC *)(*way)->facility; + while ((*q++ = *p++)); - q = (UC *) (*way)->city; - while((*q++ = *p++)); + q = (UC *)(*way)->city; + while ((*q++ = *p++)); - q = (UC *) (*way)->addr; - while((*q++ = *p++)); + q = (UC *)(*way)->addr; + while ((*q++ = *p++)); - q = (UC *) (*way)->cross_road; - while((*q++ = *p++)); + q = (UC *)(*way)->cross_road; + while ((*q++ = *p++)); - return; + return; } @@ -1637,31 +1731,43 @@ static void GPS_D109_Get(GPS_PWay *way, UC *s, int protoid) ************************************************************************/ static void GPS_D150_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; - - p=s; - - (*way)->prot = 150; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - (*way)->wpt_class = *p++; - - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); - - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; - - return; + UC *p; + int32 i; + + p=s; + + (*way)->prot = 150; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + (*way)->wpt_class = *p++; + + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } + + return; } @@ -1677,41 +1783,53 @@ static void GPS_D150_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D151_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 151; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 151; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p; + (*way)->wpt_class = *p; - return; + return; } @@ -1727,41 +1845,53 @@ static void GPS_D151_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D152_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 152; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 152; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p; + (*way)->wpt_class = *p; - return; + return; } @@ -1776,43 +1906,55 @@ static void GPS_D152_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D154_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 154; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 154; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); + (*way)->smbl = GPS_Util_Get_Short(p); - return; + return; } @@ -1827,46 +1969,58 @@ static void GPS_D154_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D155_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 155; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 155; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*way)->dst = GPS_Util_Get_Float(p); + p+=sizeof(float); - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<2;++i) (*way)->cc[i] = *p++; + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } - ++p; + ++p; - (*way)->wpt_class = *p++; + (*way)->wpt_class = *p++; - (*way)->smbl = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->smbl = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*way)->dspl = *p; + (*way)->dspl = *p; - return; + return; } /* @@ -1881,19 +2035,19 @@ char gps_categories[16][17]; static void GPS_D120_Get(int cat_num, char *s) { - /* we're guaranteed to have no more than 16 chars plus a - * null terminator. - * - * If the unit returned no string, the user has not configured one, - * so mimic the behaviour of the 276/296. - */ - - if (*s) { - strncpy(gps_categories[cat_num], s, sizeof (gps_categories[0])); - } else { - snprintf(gps_categories[cat_num], sizeof (gps_categories[0]), - "Category %d", cat_num+1); - } + /* we're guaranteed to have no more than 16 chars plus a + * null terminator. + * + * If the unit returned no string, the user has not configured one, + * so mimic the behaviour of the 276/296. + */ + + if (*s) { + strncpy(gps_categories[cat_num], s, sizeof(gps_categories[0])); + } else { + snprintf(gps_categories[cat_num], sizeof(gps_categories[0]), + "Category %d", cat_num+1); + } } @@ -1909,22 +2063,22 @@ void GPS_D120_Get(int cat_num, char *s) ************************************************************************/ static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *len = 58; + *len = 58; - return; + return; } @@ -1940,28 +2094,28 @@ static void GPS_D100_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *p = way->smbl; + *p = way->smbl; - *len = 63; + *len = 63; - return; + return; } @@ -1977,27 +2131,27 @@ static void GPS_D101_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - GPS_Util_Put_Short(p,(US) way->smbl); + GPS_Util_Put_Short(p,(US) way->smbl); - *len = 64; + *len = 64; - return; + return; } @@ -2013,26 +2167,26 @@ static void GPS_D102_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p++ = (UC) way->smbl; - *p = (UC) way->dspl; + *p++ = (UC) way->smbl; + *p = (UC) way->dspl; - *len = 60; + *len = 60; - return; + return; } @@ -2048,34 +2202,34 @@ static void GPS_D103_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - - p = data; - - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - /* byonke confirms that sending lower case comment data to a III+ - * results in the comment being truncated there. So we uppercase - * the entire comment. - */ - copy_char_array(&p, way->cmnt, 40, UpperYes); + UC *p; - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + p = data; - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + /* byonke confirms that sending lower case comment data to a III+ + * results in the comment being truncated there. So we uppercase + * the entire comment. + */ + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p = 3; /* display symbol with waypoint name */ + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *len = 65; + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - return; + *p = 3; /* display symbol with waypoint name */ + + *len = 65; + + return; } @@ -2091,26 +2245,26 @@ static void GPS_D104_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - UC *q; + UC *p; + UC *q; - p = data; + p = data; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - q = (UC *) way->wpt_ident; - while((*p++ = *q++)); + q = (UC *) way->wpt_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -2126,30 +2280,32 @@ static void GPS_D105_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - UC *q; - int32 i; + UC *p; + UC *q; + int32 i; - p = data; + p = data; - *p++ = way->wpt_class; - for(i=0;i<13;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + *p++ = way->wpt_class; + for (i=0; i<13; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p, (int16) way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p, (int16) way->smbl); + p+=sizeof(int16); - q = (UC *) way->wpt_ident; - while((*p++ = *q++)); - q = (UC *) way->lnk_ident; - while((*p++ = *q++)); + q = (UC *) way->wpt_ident; + while ((*p++ = *q++)); + q = (UC *) way->lnk_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -2165,30 +2321,30 @@ static void GPS_D106_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *p++ = way->smbl; - *p++ = way->dspl; + *p++ = way->smbl; + *p++ = way->dspl; - GPS_Util_Put_Float(p,way->dst); - p+= sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+= sizeof(float); - *p = way->colour; + *p = way->colour; - *len = 65; + *len = 65; - return; + return; } @@ -2205,62 +2361,68 @@ static void GPS_D107_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - UC *q; - - int32 i; - - p = data; - - *p++ = way->wpt_class; - *p++ = way->colour; - *p++ = way->dspl; - *p++ = 0x60; - GPS_Util_Put_Short(p,(US) way->smbl); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - - if (way->alt_is_unknown) { - GPS_Util_Put_Float(p,(const float) 1.0e25); - } else { - GPS_Util_Put_Float(p,way->alt); - } - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dpth); - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); - - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - - - q = (UC *) way->ident; - i = XMIN(51, sizeof(way->ident)); - while((*p++ = *q++) && i--); - q = (UC *) way->cmnt; - i = XMIN(51, sizeof(way->cmnt)); - while((*p++ = *q++) && i--); - q = (UC *) way->facility; - i = XMIN(31, sizeof(way->facility)); - while((*p++ = *q++) && i--); - q = (UC *) way->city; - i = XMIN(25, sizeof(way->city)); - while((*p++ = *q++) && i--); - q = (UC *) way->addr; - i = XMIN(51, sizeof(way->addr)); - while((*p++ = *q++) && i--); - q = (UC *) way->cross_road; - i = XMIN(51, sizeof(way->cross_road)); - while((*p++ = *q++) && i--); - - *len = p-data; - - return; + UC *p; + UC *q; + + int32 i; + + p = data; + + *p++ = way->wpt_class; + *p++ = way->colour; + *p++ = way->dspl; + *p++ = 0x60; + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + + + q = (UC *) way->ident; + i = XMIN(51, sizeof(way->ident)); + while ((*p++ = *q++) && i--); + q = (UC *) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while ((*p++ = *q++) && i--); + q = (UC *) way->facility; + i = XMIN(31, sizeof(way->facility)); + while ((*p++ = *q++) && i--); + q = (UC *) way->city; + i = XMIN(25, sizeof(way->city)); + while ((*p++ = *q++) && i--); + q = (UC *) way->addr; + i = XMIN(51, sizeof(way->addr)); + while ((*p++ = *q++) && i--); + q = (UC *) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while ((*p++ = *q++) && i--); + + *len = p-data; + + return; } @@ -2277,83 +2439,93 @@ static void GPS_D108_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) { - UC *p; - UC *q; - - int32 i; - - p = data; - - *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ - *p++ = way->wpt_class; - - *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ - - if (protoid == 109) { /* attr */ - *p++ = 0x70; - } else if (protoid == 110) { - *p++ = 0x80; + UC *p; + UC *q; + + int32 i; + + p = data; + + *p++ = 1; /* data packet type; must be 1 for D109 and D110 */ + *p++ = way->wpt_class; + + *p++ = ((way->dspl & 3) << 5) | 0x1f; /* colour & display */ + + if (protoid == 109) { /* attr */ + *p++ = 0x70; + } else if (protoid == 110) { + *p++ = 0x80; + } else { + GPS_Warning("Unknown protoid in GPS_D109_Send."); + } + GPS_Util_Put_Short(p,(US) way->smbl); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->subclass[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + if (way->alt_is_unknown) { + GPS_Util_Put_Float(p,(const float) 1.0e25); + } else { + GPS_Util_Put_Float(p,way->alt); + } + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dpth); + p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); + + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + for (i=0; i<4; ++i) { + *p++ = 0xff; /* D109 silliness for ETE */ + } + if (protoid == 110) { + float temp = 1.0e25f; + + GPS_Util_Put_Float(p, temp); + p += 4; + + if (way->time_populated) { + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); + p+=sizeof(uint32); } else { - GPS_Warning("Unknown protoid in GPS_D109_Send."); + for (i=0; i<4; ++i) { + *p++ = 0xff; /* unknown time*/ + } } - GPS_Util_Put_Short(p,(US) way->smbl); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->subclass[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - if (way->alt_is_unknown) { - GPS_Util_Put_Float(p,(const float) 1.0e25); - } else { - GPS_Util_Put_Float(p,way->alt); - } - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dpth); - p+=sizeof(float); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - for(i=0;i<4;++i) *p++ = 0xff; /* D109 silliness for ETE */ - if (protoid == 110) { - float temp = 1.0e25f; - - GPS_Util_Put_Float(p, temp); - p += 4; - - if (way->time_populated) { - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(way->time)); - p+=sizeof(uint32); - } else { - for(i=0;i<4;++i) *p++ = 0xff; /* unknown time*/ - } - - GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ - p += 2; - } - - q = (UC *) way->ident; - i = XMIN(51, sizeof(way->ident)); - while((*p++ = *q++) && i--); - q = (UC *) way->cmnt; - i = XMIN(51, sizeof(way->cmnt)); - while((*p++ = *q++) && i--); - q = (UC *) way->facility; - i = XMIN(31, sizeof(way->facility)); - while((*p++ = *q++) && i--); - q = (UC *) way->city; - i = XMIN(25, sizeof(way->city)); - while((*p++ = *q++) && i--); - q = (UC *) way->addr; - i = XMIN(51, sizeof(way->addr)); - while((*p++ = *q++) && i--); - q = (UC *) way->cross_road; - i = XMIN(51, sizeof(way->cross_road)); - while((*p++ = *q++) && i--); - *len = p-data; - return; + GPS_Util_Put_Short(p, (US) way->category);; /* D110 category */ + p += 2; + } + + q = (UC *) way->ident; + i = XMIN(51, sizeof(way->ident)); + while ((*p++ = *q++) && i--); + q = (UC *) way->cmnt; + i = XMIN(51, sizeof(way->cmnt)); + while ((*p++ = *q++) && i--); + q = (UC *) way->facility; + i = XMIN(31, sizeof(way->facility)); + while ((*p++ = *q++) && i--); + q = (UC *) way->city; + i = XMIN(25, sizeof(way->city)); + while ((*p++ = *q++) && i--); + q = (UC *) way->addr; + i = XMIN(51, sizeof(way->addr)); + while ((*p++ = *q++) && i--); + q = (UC *) way->cross_road; + i = XMIN(51, sizeof(way->cross_road)); + while ((*p++ = *q++) && i--); + *len = p-data; + return; } @@ -2369,33 +2541,37 @@ static void GPS_D109_Send(UC *data, GPS_PWay way, int32 *len, int protoid) ************************************************************************/ static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); - for(i=0;i<2;++i) *p++ = way->cc[i]; + copy_char_array(&p, way->ident, 6, UpperYes); + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } - if(way->wpt_class == 7) way->wpt_class = 0; - *p++ = way->wpt_class; + if (way->wpt_class == 7) { + way->wpt_class = 0; + } + *p++ = way->wpt_class; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->cmnt, 40, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->cmnt, 40, UpperYes); - *len = 115; + *len = 115; - return; + return; } @@ -2411,39 +2587,43 @@ static void GPS_D150_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 3) way->wpt_class = 0; - *p = way->wpt_class; + if (way->wpt_class == 3) { + way->wpt_class = 0; + } + *p = way->wpt_class; - *len = 124; + *len = 124; - return; + return; } @@ -2460,39 +2640,43 @@ static void GPS_D151_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 5) way->wpt_class = 0; - *p = way->wpt_class; + if (way->wpt_class == 5) { + way->wpt_class = 0; + } + *p = way->wpt_class; - *len = 124; + *len = 124; - return; + return; } @@ -2508,42 +2692,46 @@ static void GPS_D152_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = 0; + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = 0; - if(way->wpt_class == 9) way->wpt_class = 0; - *p++ = way->wpt_class; + if (way->wpt_class == 9) { + way->wpt_class = 0; + } + *p++ = way->wpt_class; - GPS_Util_Put_Short(p,(int16)way->smbl); + GPS_Util_Put_Short(p,(int16)way->smbl); - *len = 126; + *len = 126; - return; + return; } @@ -2560,43 +2748,43 @@ static void GPS_D154_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - copy_char_array(&p, way->ident, 6, UpperYes); + copy_char_array(&p, way->ident, 6, UpperYes); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - copy_char_array(&p, way->cmnt, 40, UpperYes); - GPS_Util_Put_Float(p,way->dst); - p+=sizeof(float); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + copy_char_array(&p, way->cmnt, 40, UpperYes); + GPS_Util_Put_Float(p,way->dst); + p+=sizeof(float); - copy_char_array(&p, way->name, 30, UpperYes); - copy_char_array(&p, way->city, 24, UpperYes); - copy_char_array(&p, way->state, 2, UpperYes); + copy_char_array(&p, way->name, 30, UpperYes); + copy_char_array(&p, way->city, 24, UpperYes); + copy_char_array(&p, way->state, 2, UpperYes); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - copy_char_array(&p, way->cc, 2, UpperYes); - *p++ = 0; + copy_char_array(&p, way->cc, 2, UpperYes); + *p++ = 0; - /* Ignore wpt_class; our D155 points are always user type which is "4". */ - *p++ = 4; + /* Ignore wpt_class; our D155 points are always user type which is "4". */ + *p++ = 4; - GPS_Util_Put_Short(p,(int16)way->smbl); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(int16)way->smbl); + p+=sizeof(int16); - *p = way->dspl; + *p = way->dspl; - *len = 127; + *len = 127; - return; + return; } @@ -2612,166 +2800,170 @@ static void GPS_D155_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ int32 GPS_A200_Get(const char *port, GPS_PWay **way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A200_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) - { - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Get(&((*way)[i]),rec->data); - break; - case pD201: - GPS_D201_Get(&((*way)[i]),rec->data); - break; - case pD202: - GPS_D202_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - continue; - } - - if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) - { - GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); - return FRAMING_ERROR; - } - - (*way)[i]->isrte = 0; - (*way)[i]->islink = 0; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Get(&((*way)[i]),rec->data); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i-1]->prot = (*way)[i]->prot; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A200_GET: Error transferring routes"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A200_GET: Route entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A200_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + for (i=0; itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) { + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + continue; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + if (i != n) { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } - return n; + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -2787,184 +2979,186 @@ int32 GPS_A200_Get(const char *port, GPS_PWay **way) ************************************************************************/ int32 GPS_A201_Get(const char *port, GPS_PWay **way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A201_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) - { - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Get(&((*way)[i]),rec->data); - break; - case pD201: - GPS_D201_Get(&((*way)[i]),rec->data); - break; - case pD202: - GPS_D202_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A201_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i]->islink = 0; - continue; - } - - - if(rec->type == LINK_ID[gps_link_type].Pid_Rte_Link_Data) - { - switch(gps_rte_link_type) - { - case pD210: - GPS_D210_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A201_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i]->isrte = 0; - (*way)[i]->islink = 1; - continue; - } - - if(rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) - { - GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); - return FRAMING_ERROR; - } - - (*way)[i]->isrte = 0; - (*way)[i]->islink = 0; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Get(&((*way)[i]),rec->data); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD103: - GPS_D103_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD150: - GPS_D150_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A200_GET: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (*way)[i-1]->prot = (*way)[i]->prot; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A200_GET: Error transferring routes"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A200_GET: Route entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Rte); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A201_Get: Insufficient memory"); + return MEMORY_ERROR; } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + + for (i=0; itype == LINK_ID[gps_link_type].Pid_Rte_Hdr) { + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Get(&((*way)[i]),rec->data); + break; + case pD201: + GPS_D201_Get(&((*way)[i]),rec->data); + break; + case pD202: + GPS_D202_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->islink = 0; + continue; + } + + + if (rec->type == LINK_ID[gps_link_type].Pid_Rte_Link_Data) { + switch (gps_rte_link_type) { + case pD210: + GPS_D210_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A201_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i]->isrte = 0; + (*way)[i]->islink = 1; + continue; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Rte_Wpt_Data) { + GPS_Error("A200_GET: Non Pid_rte_Wpt_Data"); + return FRAMING_ERROR; + } + + (*way)[i]->isrte = 0; + (*way)[i]->islink = 0; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Get(&((*way)[i]),rec->data); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD103: + GPS_D103_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD150: + GPS_D150_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A200_GET: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (*way)[i-1]->prot = (*way)[i]->prot; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A200_GET: Error transferring routes"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A200_GET: Route entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return n; + return n; } @@ -2981,139 +3175,136 @@ int32 GPS_A201_Get(const char *port, GPS_PWay **way) ************************************************************************/ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - US method; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;iisrte) - { - method = LINK_ID[gps_link_type].Pid_Rte_Hdr; - - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Send(data,way[i],&len); - break; - case pD201: - GPS_D201_Send(data,way[i],&len); - break; - case pD202: - GPS_D202_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else - { - method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Send(data,way[i],&len); - break; - case pD101: - GPS_D101_Send(data,way[i],&len); - break; - case pD102: - GPS_D102_Send(data,way[i],&len); - break; - case pD103: - GPS_D103_Send(data,way[i],&len); - break; - case pD104: - GPS_D104_Send(data,way[i],&len); - break; - case pD105: - GPS_D105_Send(data,way[i],&len); - break; - case pD106: - GPS_D106_Send(data,way[i],&len); - break; - case pD107: - GPS_D107_Send(data,way[i],&len); - break; - case pD108: - GPS_D108_Send(data,way[i],&len); - break; - case pD150: - GPS_D150_Send(data,way[i],&len); - break; - case pD151: - GPS_D151_Send(data,way[i],&len); - break; - case pD152: - GPS_D152_Send(data,way[i],&len); - break; - case pD154: - GPS_D154_Send(data,way[i],&len); - break; - case pD155: - GPS_D155_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iisrte) { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + GPS_Make_Packet(&tra, method, data, len); - return 1; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -3130,159 +3321,153 @@ int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n) ************************************************************************/ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - US method; - - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;iisrte) - { - method = LINK_ID[gps_link_type].Pid_Rte_Hdr; - - switch(gps_rte_hdr_type) - { - case pD200: - GPS_D200_Send(data,way[i],&len); - break; - case pD201: - GPS_D201_Send(data,way[i],&len); - break; - case pD202: - GPS_D202_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else if(way[i]->islink) - { - method = LINK_ID[gps_link_type].Pid_Rte_Link_Data; - - switch(gps_rte_link_type) - { - case pD210: - GPS_D210_Send(data,way[i],&len); - break; - default: - GPS_Error("A201_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - else - { - method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; - - switch(gps_rte_type) - { - case pD100: - GPS_D100_Send(data,way[i],&len); - break; - case pD101: - GPS_D101_Send(data,way[i],&len); - break; - case pD102: - GPS_D102_Send(data,way[i],&len); - break; - case pD103: - GPS_D103_Send(data,way[i],&len); - break; - case pD104: - GPS_D104_Send(data,way[i],&len); - break; - case pD105: - GPS_D105_Send(data,way[i],&len); - break; - case pD106: - GPS_D106_Send(data,way[i],&len); - break; - case pD107: - GPS_D107_Send(data,way[i],&len); - break; - case pD108: - GPS_D108_Send(data,way[i],&len); - break; - case pD109: - GPS_D109_Send(data,way[i],&len, 109); - break; - case pD110: - GPS_D109_Send(data,way[i],&len, 110); - break; - case pD150: - GPS_D150_Send(data,way[i],&len); - break; - case pD151: - GPS_D151_Send(data,way[i],&len); - break; - case pD152: - GPS_D152_Send(data,way[i],&len); - break; - case pD154: - GPS_D154_Send(data,way[i],&len); - break; - case pD155: - GPS_D155_Send(data,way[i],&len); - break; - default: - GPS_Error("A200_Send: Unknown route protocol"); - return PROTOCOL_ERROR; - } - } - - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A200_Send: Route complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iisrte) { + method = LINK_ID[gps_link_type].Pid_Rte_Hdr; + + switch (gps_rte_hdr_type) { + case pD200: + GPS_D200_Send(data,way[i],&len); + break; + case pD201: + GPS_D201_Send(data,way[i],&len); + break; + case pD202: + GPS_D202_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else if (way[i]->islink) { + method = LINK_ID[gps_link_type].Pid_Rte_Link_Data; + + switch (gps_rte_link_type) { + case pD210: + GPS_D210_Send(data,way[i],&len); + break; + default: + GPS_Error("A201_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } + } else { + method = LINK_ID[gps_link_type].Pid_Rte_Wpt_Data; + + switch (gps_rte_type) { + case pD100: + GPS_D100_Send(data,way[i],&len); + break; + case pD101: + GPS_D101_Send(data,way[i],&len); + break; + case pD102: + GPS_D102_Send(data,way[i],&len); + break; + case pD103: + GPS_D103_Send(data,way[i],&len); + break; + case pD104: + GPS_D104_Send(data,way[i],&len); + break; + case pD105: + GPS_D105_Send(data,way[i],&len); + break; + case pD106: + GPS_D106_Send(data,way[i],&len); + break; + case pD107: + GPS_D107_Send(data,way[i],&len); + break; + case pD108: + GPS_D108_Send(data,way[i],&len); + break; + case pD109: + GPS_D109_Send(data,way[i],&len, 109); + break; + case pD110: + GPS_D109_Send(data,way[i],&len, 110); + break; + case pD150: + GPS_D150_Send(data,way[i],&len); + break; + case pD151: + GPS_D151_Send(data,way[i],&len); + break; + case pD152: + GPS_D152_Send(data,way[i],&len); + break; + case pD154: + GPS_D154_Send(data,way[i],&len); + break; + case pD155: + GPS_D155_Send(data,way[i],&len); + break; + default: + GPS_Error("A200_Send: Unknown route protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + GPS_Make_Packet(&tra, method, data, len); - return 1; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Wpt); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A200_Send: Route complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -3300,11 +3485,11 @@ int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n) ************************************************************************/ static void GPS_D200_Get(GPS_PWay *way, UC *s) { - (*way)->rte_prot = 200; - (*way)->rte_num = *s; - (*way)->isrte = 1; + (*way)->rte_prot = 200; + (*way)->rte_num = *s; + (*way)->isrte = 1; - return; + return; } @@ -3320,17 +3505,19 @@ static void GPS_D200_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D201_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->rte_prot = 201; - (*way)->rte_num = *p++; - (*way)->isrte = 1; - for(i=0;i<20;++i) (*way)->rte_cmnt[i] = *p++; + (*way)->rte_prot = 201; + (*way)->rte_num = *p++; + (*way)->isrte = 1; + for (i=0; i<20; ++i) { + (*way)->rte_cmnt[i] = *p++; + } - return; + return; } @@ -3346,21 +3533,21 @@ static void GPS_D201_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D202_Get(GPS_PWay *way, UC *s) { - UC *p; - UC *q; + UC *p; + UC *q; - p=s; + p=s; - (*way)->rte_prot = 202; + (*way)->rte_prot = 202; #if 0 - /* D202 has only a null terminated string for rte_ident */ - (*way)->rte_num = *p++; + /* D202 has only a null terminated string for rte_ident */ + (*way)->rte_num = *p++; #endif - (*way)->isrte = 1; - q = (UC *) (*way)->rte_ident; - while((*q++=*p++)); + (*way)->isrte = 1; + q = (UC *)(*way)->rte_ident; + while ((*q++=*p++)); - return; + return; } @@ -3376,19 +3563,21 @@ static void GPS_D202_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D210_Get(GPS_PWay *way, UC *s) { - UC *p; - UC *q; - int32 i; + UC *p; + UC *q; + int32 i; - p=s; + p=s; - (*way)->rte_link_class = GPS_Util_Get_Short(p); - p+=sizeof(int16); - for(i=0;i<18;++i) (*way)->rte_link_subclass[i] = *p++; - q = (UC *) (*way)->rte_link_ident; - while((*q++=*p++)); + (*way)->rte_link_class = GPS_Util_Get_Short(p); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + (*way)->rte_link_subclass[i] = *p++; + } + q = (UC *)(*way)->rte_link_ident; + while ((*q++=*p++)); - return; + return; } @@ -3406,10 +3595,10 @@ static void GPS_D210_Get(GPS_PWay *way, UC *s) static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len) { - *data = way->rte_num; - *len = 1; + *data = way->rte_num; + *len = 1; - return; + return; } @@ -3426,15 +3615,15 @@ static void GPS_D200_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; + UC *p; - p = data; + p = data; - *p++ = way->rte_num; - copy_char_array(&p, way->rte_cmnt, 20, UpperYes); - *len = 21; + *p++ = way->rte_num; + copy_char_array(&p, way->rte_cmnt, 20, UpperYes); + *len = 21; - return; + return; } @@ -3451,17 +3640,17 @@ static void GPS_D201_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - UC *q; + UC *p; + UC *q; - p = data; - q = (UC *) way->rte_ident; + p = data; + q = (UC *) way->rte_ident; - while((*p++ = *q++)); + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -3478,22 +3667,24 @@ static void GPS_D202_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - UC *q; - int32 i; + UC *p; + UC *q; + int32 i; - p = data; + p = data; - GPS_Util_Put_Short(p,(US) way->rte_link_class); - p+=sizeof(int16); - for(i=0;i<18;++i) *p++ = way->rte_link_subclass[i]; + GPS_Util_Put_Short(p,(US) way->rte_link_class); + p+=sizeof(int16); + for (i=0; i<18; ++i) { + *p++ = way->rte_link_subclass[i]; + } - q = (UC *) way->rte_link_ident; - while((*p++ = *q++)); + q = (UC *) way->rte_link_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -3509,81 +3700,88 @@ static void GPS_D210_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - int32 ret; - - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* Only those GPS' with L001 can send track data */ - if(!LINK_ID[gps_link_type].Pid_Trk_Data) - { - GPS_Warning("A300 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) - { - GPS_Error("A300_Get: Insufficient memory"); - return MEMORY_ERROR; - } - for(i=0;idata); + + if (n) + if (!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) { + GPS_Error("A300_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for (i=0; itype == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - break; - } + GPS_PPacket tra; + GPS_PPacket rec; + static UC data[2]; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Runs); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + for (;;) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (rec->type == LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + break; + } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); return 0; } @@ -3644,176 +3847,178 @@ drain_run_cmd(gpsdevh *fd) ************************************************************************/ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; - int32 trk_type, trk_hdr_type; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* A301 and A302 are similar except for all these protocol IDs */ - switch (protoid) - { - case 301: - Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; - Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; - Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; - trk_type = gps_trk_type; - trk_hdr_type = gps_trk_hdr_type; - break; - case 302: - Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; - Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; - Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; - trk_type = gps_run_crs_trk_type; - trk_hdr_type = gps_run_crs_trk_hdr_type; - break; - default: - GPS_Error("A301_Get: Bad protocol ID %d", protoid); - return GPS_UNSUPPORTED; - } - - /* Only those GPS' with L001 can send track data */ - if(!Pid_Trk_Data) - { - GPS_Warning("A301 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if (protoid == 301 && trk_type == pD304 && gps_run_transfer != -1) { - drain_run_cmd(fd); - } - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) - { - GPS_Error("A301_Get: Insufficient memory"); - return MEMORY_ERROR; - } - for(i=0;itype == Pid_Trk_Hdr) - { - switch(trk_hdr_type) - { - case pD310: - case pD312: - GPS_D310_Get(&((*trk)[i]),rec->data); - break; - case pD311: - GPS_D311_Get(&((*trk)[i]),rec->data); - break; - default: - GPS_Error("A301_Get: Unknown track protocol"); - return PROTOCOL_ERROR; - } - (*trk)[i]->ishdr = 1; - continue; - } - - if(rec->type != Pid_Trk_Data) - { - GPS_Error("A301_Get: Non-Pid_Trk_Data"); - return FRAMING_ERROR; - } - - (*trk)[i]->ishdr = 0; - - switch(trk_type) - { - case pD300: - GPS_D300b_Get(&((*trk)[i]),rec->data); - break; - case pD301: - GPS_D301b_Get(&((*trk)[i]),rec->data); - break; - case pD302: - GPS_D302b_Get(&((*trk)[i]),rec->data); - break; - case pD303: - case pD304: - GPS_D303b_Get(&((*trk)[i]),rec->data); - /* Fitness devices don't send track segment markers, so we have - * to create them ourselves. We do so at the beginning of the - * track or if the device signals a pause by sending two - * invalid points in a row. - */ - if (i>0) - { - if ((*trk)[i-1]->ishdr || - (Is_Trackpoint_Invalid((*trk)[i-1]) && - Is_Trackpoint_Invalid((*trk)[i]))) - { - (*trk)[i]->tnew = 1; - } - } - break; - default: - GPS_Error("A301_GET: Unknown track protocol"); - return PROTOCOL_ERROR; - } - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) - cb(n, NULL); - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A301_Get: Error transferring tracks"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A301_GET: Track entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; + int32 trk_type, trk_hdr_type; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* A301 and A302 are similar except for all these protocol IDs */ + switch (protoid) { + case 301: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; + trk_type = gps_trk_type; + trk_hdr_type = gps_trk_hdr_type; + break; + case 302: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; + trk_type = gps_run_crs_trk_type; + trk_hdr_type = gps_run_crs_trk_hdr_type; + break; + default: + GPS_Error("A301_Get: Bad protocol ID %d", protoid); + return GPS_UNSUPPORTED; + } + + /* Only those GPS' with L001 can send track data */ + if (!Pid_Trk_Data) { + GPS_Warning("A301 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (protoid == 301 && trk_type == pD304 && gps_run_transfer != -1) { + drain_run_cmd(fd); + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*trk)=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack)))) { + GPS_Error("A301_Get: Insufficient memory"); + return MEMORY_ERROR; + } + for (i=0; itype == Pid_Trk_Hdr) { + switch (trk_hdr_type) { + case pD310: + case pD312: + GPS_D310_Get(&((*trk)[i]),rec->data); + break; + case pD311: + GPS_D311_Get(&((*trk)[i]),rec->data); + break; + default: + GPS_Error("A301_Get: Unknown track protocol"); + return PROTOCOL_ERROR; + } + (*trk)[i]->ishdr = 1; + continue; + } + + if (rec->type != Pid_Trk_Data) { + GPS_Error("A301_Get: Non-Pid_Trk_Data"); + return FRAMING_ERROR; + } - if(!GPS_Device_Off(fd)) - return gps_errno; + (*trk)[i]->ishdr = 0; - return n; + switch (trk_type) { + case pD300: + GPS_D300b_Get(&((*trk)[i]),rec->data); + break; + case pD301: + GPS_D301b_Get(&((*trk)[i]),rec->data); + break; + case pD302: + GPS_D302b_Get(&((*trk)[i]),rec->data); + break; + case pD303: + case pD304: + GPS_D303b_Get(&((*trk)[i]),rec->data); + /* Fitness devices don't send track segment markers, so we have + * to create them ourselves. We do so at the beginning of the + * track or if the device signals a pause by sending two + * invalid points in a row. + */ + if (i>0) { + if ((*trk)[i-1]->ishdr || + (Is_Trackpoint_Invalid((*trk)[i-1]) && + Is_Trackpoint_Invalid((*trk)[i]))) { + (*trk)[i]->tnew = 1; + } + } + break; + default: + GPS_Error("A301_GET: Unknown track protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A301_Get: Error transferring tracks"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A301_GET: Track entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -3829,83 +4034,84 @@ int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid) ************************************************************************/ int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - /* Only those GPS' with L001 can send track data */ - if(!LINK_ID[gps_link_type].Pid_Trk_Data) - { - GPS_Warning("A300 protocol unsupported"); - return GPS_UNSUPPORTED; - } - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A300_Send: Track start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iishdr) - { - method = Pid_Trk_Hdr; - - switch(trk_hdr_type) - { - case pD310: - case pD312: - GPS_D310_Send(data,trk[i],&len); - break; - case pD311: - GPS_D311_Send(data,trk[i],&len); - break; - default: - GPS_Error("A301_Send: Unknown track protocol %d", trk_hdr_type); - return PROTOCOL_ERROR; - } - } - else - { - method = Pid_Trk_Data; - - switch(trk_type) - { - case pD300: - GPS_D300_Send(data,trk[i],&len); - break; - case pD301: - GPS_D301_Send(data,trk[i],&len,301); - break; - case pD302: - GPS_D301_Send(data,trk[i],&len,302); - break; - case pD303: - case pD304: - GPS_D303_Send(data,trk[i],&len,(trk_type==pD303) ? 303 : 304); - break; - default: - GPS_Error("A301_Send: Unknown track protocol"); - return PROTOCOL_ERROR; - } - } - - GPS_Make_Packet(&tra, method, data, len); - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A301_Send: Track packet not acknowledged"); - return FRAMING_ERROR; - } - } - - GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A301_Send: Track complete data not acknowledged"); - return FRAMING_ERROR; + UC data[GPS_ARB_LEN]; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; + int32 len; + US method; + US Pid_Trk_Data, Pid_Trk_Hdr, Cmnd_Transfer_Trk; + int32 trk_type, trk_hdr_type; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* A301 and A302 are similar except for all these protocol IDs */ + switch (protoid) { + case 301: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Trk; + trk_type = gps_trk_type; + trk_hdr_type = gps_trk_hdr_type; + break; + case 302: + Pid_Trk_Data = LINK_ID[gps_link_type].Pid_Course_Trk_Data; + Pid_Trk_Hdr = LINK_ID[gps_link_type].Pid_Course_Trk_Hdr; + Cmnd_Transfer_Trk = COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Tracks; + trk_type = gps_run_crs_trk_type; + trk_hdr_type = gps_run_crs_trk_hdr_type; + break; + default: + GPS_Error("A301_Send: Bad protocol ID %d", protoid); + return GPS_UNSUPPORTED; + } + + /* Only those GPS' with L001 can send track data */ + if (!Pid_Trk_Data) { + GPS_Warning("A301 protocol unsupported"); + return GPS_UNSUPPORTED; + } + + if (protoid != 302 && !GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,(US) n); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track start data not acknowledged"); + return FRAMING_ERROR; + } + + + for (i=0; iishdr) { + method = Pid_Trk_Hdr; + + switch (trk_hdr_type) { + case pD310: + case pD312: + GPS_D310_Send(data,trk[i],&len); + break; + case pD311: + GPS_D311_Send(data,trk[i],&len); + break; + default: + GPS_Error("A301_Send: Unknown track protocol %d", trk_hdr_type); + return PROTOCOL_ERROR; + } + } else { + method = Pid_Trk_Data; + + switch (trk_type) { + case pD300: + GPS_D300_Send(data,trk[i],&len); + break; + case pD301: + GPS_D301_Send(data,trk[i],&len,301); + break; + case pD302: + GPS_D301_Send(data,trk[i],&len,302); + break; + case pD303: + case pD304: + GPS_D303_Send(data,trk[i],&len,(trk_type==pD303) ? 303 : 304); + break; + default: + GPS_Error("A301_Send: Unknown track protocol"); + return PROTOCOL_ERROR; + } } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Make_Packet(&tra, method, data, len); - if(protoid != 302 && !GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } - return 1; + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track packet not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data, Cmnd_Transfer_Trk); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A301_Send: Track complete data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (protoid != 302 && !GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -4077,41 +4279,44 @@ int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, ************************************************************************/ int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) { - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; + GPS_PPacket tra; + GPS_PPacket rec; + int32 i; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - for(i=0;idata, &trk[i]); + for (i=0; idata, &trk[i]); + } - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("D300_GET: Error transferring track log"); - return FRAMING_ERROR; - } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - return i; + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("D300_GET: Error transferring track log"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return i; } @@ -4128,8 +4333,8 @@ int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *fd) void GPS_D300b_Get(GPS_PTrack *trk, UC *data) { - GPS_A300_Translate(data, trk); - return; + GPS_A300_Translate(data, trk); + return; } @@ -4145,33 +4350,34 @@ void GPS_D300b_Get(GPS_PTrack *trk, UC *data) ************************************************************************/ void GPS_D301b_Get(GPS_PTrack *trk, UC *data) { - UC *p; - uint32 t; + UC *p; + uint32 t; - p=data; + p=data; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } /* @func GPS_D302b_Get ****************************************************** @@ -4185,45 +4391,46 @@ void GPS_D301b_Get(GPS_PTrack *trk, UC *data) ************************************************************************/ void GPS_D302b_Get(GPS_PTrack *trk, UC *data) { - UC *p; - uint32 t; - double gps_temp; + UC *p; + uint32 t; + double gps_temp; - p=data; + p=data; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*trk)->dpth = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*trk)->dpth = GPS_Util_Get_Float(p); + p+=sizeof(float); - /* The only difference between 302 and 301 is the presence of temp - * in the middle. Nice planning, eh? - */ - gps_temp = GPS_Util_Get_Float(p); - if (gps_temp <= 1.0e24) { - (*trk)->temperature_populated = 1; - (*trk)->temperature = gps_temp; - } + /* The only difference between 302 and 301 is the presence of temp + * in the middle. Nice planning, eh? + */ + gps_temp = GPS_Util_Get_Float(p); + if (gps_temp <= 1.0e24) { + (*trk)->temperature_populated = 1; + (*trk)->temperature = gps_temp; + } - p+=sizeof(float); + p+=sizeof(float); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } @@ -4238,81 +4445,85 @@ void GPS_D302b_Get(GPS_PTrack *trk, UC *data) ************************************************************************/ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) { - UC *p; - uint32 t; - uint32 raw_lat, raw_lon; - int lat_undefined, lon_undefined; - p=data; - - /* Latitude and longitude are sometimes invalid (0x7fffffff or - * maybe 0xffffffff?) I guess this makes sense if the device is - * reporting heart rate and time anyway. I presume that latitude - * and longitude are defined or left undefined together? - */ - raw_lat = GPS_Util_Get_Int(p); - lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff; - if (lat_undefined) - (*trk)->lat=0; - else - (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat); - p+=sizeof(int32); - - raw_lon = GPS_Util_Get_Int(p); - lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff; - if (lon_undefined) - (*trk)->lon=0; - else - (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); - p+=sizeof(int32); - - /* - * Let the caller decide if it wants to toss trackpionts with only - * heart rate and/or time data. - */ - if (lat_undefined || lon_undefined) { - (*trk)->no_latlon = 1; + UC *p; + uint32 t; + uint32 raw_lat, raw_lon; + int lat_undefined, lon_undefined; + p=data; + + /* Latitude and longitude are sometimes invalid (0x7fffffff or + * maybe 0xffffffff?) I guess this makes sense if the device is + * reporting heart rate and time anyway. I presume that latitude + * and longitude are defined or left undefined together? + */ + raw_lat = GPS_Util_Get_Int(p); + lat_undefined = !raw_lat || raw_lat==0x7fffffff || raw_lat==0xffffffff; + if (lat_undefined) { + (*trk)->lat=0; + } else { + (*trk)->lat = GPS_Math_Semi_To_Deg(raw_lat); + } + p+=sizeof(int32); + + raw_lon = GPS_Util_Get_Int(p); + lon_undefined = !raw_lon || raw_lon==0x7fffffff || raw_lon==0xffffffff; + if (lon_undefined) { + (*trk)->lon=0; + } else { + (*trk)->lon = GPS_Math_Semi_To_Deg(raw_lon); + } + p+=sizeof(int32); + + /* + * Let the caller decide if it wants to toss trackpionts with only + * heart rate and/or time data. + */ + if (lat_undefined || lon_undefined) { + (*trk)->no_latlon = 1; + } + + if (lat_undefined != lon_undefined) { + GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); + } + + t = GPS_Util_Get_Uint(p); + + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); + + (*trk)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); + + /* Heartrate is reported as 0 if there is no signal from + * a heartrate monitor. + * 303 and 304 are identical until now. + */ + switch (gps_trk_type) { + case pD304: + (*trk)->distance = GPS_Util_Get_Float(p); + (*trk)->distance_populated = ((*trk)->distance <= 1e24); + p+=sizeof(float); /* A float indicating number of meters travelled. */ + + (*trk)->heartrate = (*p++); + /* crank cadence, RPM, 0xff if invalid. */ + if (*p != 0xff) { + (*trk)->cadence = (*p); } + p++; - if (lat_undefined != lon_undefined) - GPS_Warning("GPS_D303b_Get: assumption (lat_undefined == lon_undefined) violated"); - - t = GPS_Util_Get_Uint(p); - - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + (*trk)->wsensor_pres = (*p++); - (*trk)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + break; + case pD303: + (*trk)->heartrate = *p++; + break; + } - /* Heartrate is reported as 0 if there is no signal from - * a heartrate monitor. - * 303 and 304 are identical until now. - */ - switch (gps_trk_type) { - case pD304: - (*trk)->distance = GPS_Util_Get_Float(p); - (*trk)->distance_populated = ((*trk)->distance <= 1e24); - p+=sizeof(float); /* A float indicating number of meters travelled. */ - - (*trk)->heartrate = (*p++); - /* crank cadence, RPM, 0xff if invalid. */ - if (*p != 0xff) { - (*trk)->cadence = (*p); - } - p++; - - (*trk)->wsensor_pres = (*p++); - - break; - case pD303: - (*trk)->heartrate = *p++; - break; - } - - return; + return; } @@ -4327,19 +4538,19 @@ void GPS_D303b_Get(GPS_PTrack *trk, UC *data) ************************************************************************/ void GPS_D310_Get(GPS_PTrack *trk, UC *s) { - UC *p; - UC *q; + UC *p; + UC *q; - p=s; + p=s; - (*trk)->dspl = *p++; - (*trk)->colour = *p++; + (*trk)->dspl = *p++; + (*trk)->colour = *p++; - q = (UC *) (*trk)->trk_ident; + q = (UC *)(*trk)->trk_ident; - while((*q++ = *p++)); + while ((*q++ = *p++)); - return; + return; } /* @func GPS_D311_Get ****************************************************** @@ -4353,16 +4564,16 @@ void GPS_D310_Get(GPS_PTrack *trk, UC *s) ************************************************************************/ void GPS_D311_Get(GPS_PTrack *trk, UC *s) { - UC *p; - short identifier; + UC *p; + short identifier; - p=s; + p=s; - /* Forerunner */ - identifier = GPS_Util_Get_Short(s); - sprintf((*trk)->trk_ident, "%d", identifier); + /* Forerunner */ + identifier = GPS_Util_Get_Short(s); + sprintf((*trk)->trk_ident, "%d", identifier); - return; + return; } @@ -4378,14 +4589,14 @@ void GPS_D311_Get(GPS_PTrack *trk, UC *s) ************************************************************************/ void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len) { - UC *p; + UC *p; - p = data; - GPS_A300_Encode(p,trk); + p = data; + GPS_A300_Encode(p,trk); - *len = 13; + *len = 13; - return; + return; } @@ -4403,29 +4614,29 @@ void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len) ************************************************************************/ void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type) { - UC *p; + UC *p; - p = data; - GPS_A300_Encode(p,trk); - p = data+12; + p = data; + GPS_A300_Encode(p,trk); + p = data+12; - GPS_Util_Put_Float(p,trk->alt); - p+=sizeof(float); - GPS_Util_Put_Float(p,trk->dpth); - p+=sizeof(float); + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + GPS_Util_Put_Float(p,trk->dpth); + p+=sizeof(float); - if (type == 302) { - /* Temperature */ - GPS_Util_Put_Float(p, 1.0e25f); - p+=sizeof(float); - } + if (type == 302) { + /* Temperature */ + GPS_Util_Put_Float(p, 1.0e25f); + p+=sizeof(float); + } - *p = trk->tnew; - p+=sizeof(UC); + *p = trk->tnew; + p+=sizeof(UC); - *len = p-data; + *len = p-data; - return; + return; } @@ -4442,34 +4653,34 @@ void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type) ************************************************************************/ void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid) { - UC *p; + UC *p; - p = data; - GPS_A300_Encode(p,trk); - p = data+12; + p = data; + GPS_A300_Encode(p,trk); + p = data+12; - GPS_Util_Put_Float(p,trk->alt); + GPS_Util_Put_Float(p,trk->alt); + p+=sizeof(float); + + if (protoid == 304) { + GPS_Util_Put_Float(p, trk->distance_populated ? trk->distance : 1e25); p+=sizeof(float); + } - if (protoid == 304) { - GPS_Util_Put_Float(p, trk->distance_populated ? trk->distance : 1e25); - p+=sizeof(float); - } + *p = trk->heartrate; + p+=sizeof(char); - *p = trk->heartrate; + if (protoid == 304) { + *p = trk->cadence > 0 ? trk->cadence : 0xff; p+=sizeof(char); - if (protoid == 304) { - *p = trk->cadence > 0 ? trk->cadence : 0xff; - p+=sizeof(char); - - *p = trk->wsensor_pres; - p+=sizeof(char); - } + *p = trk->wsensor_pres; + p+=sizeof(char); + } - *len = p-data; + *len = p-data; - return; + return; } /* @func GPS_D311_Send ************************************************** @@ -4484,14 +4695,14 @@ void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid) ************************************************************************/ void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len) { - UC *p; + UC *p; - p = data; - GPS_Util_Put_Short(p,strtoul(trk->trk_ident, NULL, 0)); - p += 2; - *len = p-data; + p = data; + GPS_Util_Put_Short(p,strtoul(trk->trk_ident, NULL, 0)); + p += 2; + *len = p-data; - return; + return; } /* @func GPS_D310_Send ************************************************** @@ -4506,20 +4717,20 @@ void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len) ************************************************************************/ void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len) { - UC *p; - UC *q; + UC *p; + UC *q; - p = data; + p = data; - *p++ = trk->dspl; - *p++ = trk->colour; + *p++ = trk->dspl; + *p++ = trk->colour; - q = (UC *) trk->trk_ident; - while((*p++ = *q++)); + q = (UC *) trk->trk_ident; + while ((*p++ = *q++)); - *len = p-data; + *len = p-data; - return; + return; } @@ -4534,27 +4745,28 @@ void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len) ************************************************************************/ static void GPS_A300_Translate(UC *s, GPS_PTrack *trk) { - UC *p; - uint32 t; + UC *p; + uint32 t; - p=s; + p=s; - (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*trk)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - t = GPS_Util_Get_Uint(p); - if(!t || t==0x7fffffff || t==0xffffffff) - (*trk)->Time=0; - else - (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + if (!t || t==0x7fffffff || t==0xffffffff) { + (*trk)->Time=0; + } else { + (*trk)->Time = GPS_Math_Gtime_To_Utime((time_t)t); + } + p+=sizeof(uint32); - (*trk)->tnew = *p; + (*trk)->tnew = *p; - return; + return; } @@ -4570,25 +4782,25 @@ static void GPS_A300_Translate(UC *s, GPS_PTrack *trk) ************************************************************************/ static void GPS_A300_Encode(UC *s, GPS_PTrack trk) { - UC *p; + UC *p; - p=s; + p=s; - /* Note: lat/lon == 0x7fffffff is only valid for D303/D304, but our - * caller shouldn't set no_latlon unless one of these protocols actually - * is in use */ - GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lat)); - p+=sizeof(int32); + /* Note: lat/lon == 0x7fffffff is only valid for D303/D304, but our + * caller shouldn't set no_latlon unless one of these protocols actually + * is in use */ + GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lat)); + p+=sizeof(int32); - GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,trk->no_latlon ? 0x7fffffff : GPS_Math_Deg_To_Semi(trk->lon)); + p+=sizeof(int32); - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(trk->Time)); - p+=sizeof(uint32); + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(trk->Time)); + p+=sizeof(uint32); - *p = (UC) trk->tnew; + *p = (UC) trk->tnew; - return; + return; } @@ -4604,153 +4816,161 @@ static void GPS_A300_Encode(UC *s, GPS_PTrack trk) ************************************************************************/ int32 GPS_A400_Get(const char *port, GPS_PWay **way) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 n; - int32 i; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Prx); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Device_Chars_Ready(fd)) - { - GPS_Warning("A400 (ppx) protocol not supported"); - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return GPS_UNSUPPORTED; - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - n = GPS_Util_Get_Short(rec->data); - - if(n) - if(!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) - { - GPS_Error("A400_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - - for(i=0;idata); - break; - case pD101: - GPS_D101_Get(&((*way)[i]),rec->data); - break; - case pD102: - GPS_D102_Get(&((*way)[i]),rec->data); - break; - case pD403: - GPS_D403_Get(&((*way)[i]),rec->data); - break; - case pD104: - GPS_D104_Get(&((*way)[i]),rec->data); - break; - case pD105: - GPS_D105_Get(&((*way)[i]),rec->data); - break; - case pD106: - GPS_D106_Get(&((*way)[i]),rec->data); - break; - case pD107: - GPS_D107_Get(&((*way)[i]),rec->data); - break; - case pD108: - GPS_D108_Get(&((*way)[i]),rec->data); - break; - case pD109: - GPS_D109_Get(&((*way)[i]),rec->data,109); - break; - case pD110: - GPS_D109_Get(&((*way)[i]),rec->data,110); - break; - case pD450: - GPS_D450_Get(&((*way)[i]),rec->data); - break; - case pD151: - GPS_D151_Get(&((*way)[i]),rec->data); - break; - case pD152: - GPS_D152_Get(&((*way)[i]),rec->data); - break; - case pD154: - GPS_D154_Get(&((*way)[i]),rec->data); - break; - case pD155: - GPS_D155_Get(&((*way)[i]),rec->data); - break; - default: - GPS_Error("A400_GET: Unknown prx waypoint protocol"); - return PROTOCOL_ERROR; - } - } - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) - { - GPS_Error("A400_GET: Error transferring prx waypoints"); - return FRAMING_ERROR; - } - - if(i != n) - { - GPS_Error("A400_GET: Prx waypoint entry number mismatch"); - return FRAMING_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 n; + int32 i; + + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Prx); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Device_Chars_Ready(fd)) { + GPS_Warning("A400 (ppx) protocol not supported"); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + if (!GPS_Device_Off(fd)) { + return gps_errno; } + return GPS_UNSUPPORTED; + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(rec->data); + + if (n) + if (!((*way)=(GPS_PWay *)malloc(n*sizeof(GPS_PWay)))) { + GPS_Error("A400_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + + for (i=0; idata); + break; + case pD101: + GPS_D101_Get(&((*way)[i]),rec->data); + break; + case pD102: + GPS_D102_Get(&((*way)[i]),rec->data); + break; + case pD403: + GPS_D403_Get(&((*way)[i]),rec->data); + break; + case pD104: + GPS_D104_Get(&((*way)[i]),rec->data); + break; + case pD105: + GPS_D105_Get(&((*way)[i]),rec->data); + break; + case pD106: + GPS_D106_Get(&((*way)[i]),rec->data); + break; + case pD107: + GPS_D107_Get(&((*way)[i]),rec->data); + break; + case pD108: + GPS_D108_Get(&((*way)[i]),rec->data); + break; + case pD109: + GPS_D109_Get(&((*way)[i]),rec->data,109); + break; + case pD110: + GPS_D109_Get(&((*way)[i]),rec->data,110); + break; + case pD450: + GPS_D450_Get(&((*way)[i]),rec->data); + break; + case pD151: + GPS_D151_Get(&((*way)[i]),rec->data); + break; + case pD152: + GPS_D152_Get(&((*way)[i]),rec->data); + break; + case pD154: + GPS_D154_Get(&((*way)[i]),rec->data); + break; + case pD155: + GPS_D155_Get(&((*way)[i]),rec->data); + break; + default: + GPS_Error("A400_GET: Unknown prx waypoint protocol"); + return PROTOCOL_ERROR; + } + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (rec->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A400_GET: Error transferring prx waypoints"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A400_GET: Prx waypoint entry number mismatch"); + return FRAMING_ERROR; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return n; + return n; } @@ -4767,117 +4987,119 @@ int32 GPS_A400_Get(const char *port, GPS_PWay **way) ************************************************************************/ int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A400_Send: Prx start data not acknowledgedn"); - return FRAMING_ERROR; - } - - - for(i=0;iprot = 400; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 400; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -4929,30 +5155,34 @@ static void GPS_D400_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D403_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 403; - for(i=0;i<6;++i) (*way)->ident[i] = *p++; + (*way)->prot = 403; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - p+=sizeof(int32); + p+=sizeof(int32); - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->smbl = *p++; - (*way)->dspl = *p++; + (*way)->smbl = *p++; + (*way)->dspl = *p++; - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -4967,37 +5197,49 @@ static void GPS_D403_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D450_Get(GPS_PWay *way, UC *s) { - UC *p; - int32 i; + UC *p; + int32 i; - p=s; + p=s; - (*way)->prot = 450; + (*way)->prot = 450; - (*way)->idx = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->idx = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<6;++i) (*way)->ident[i] = *p++; - for(i=0;i<2;++i) (*way)->cc[i] = *p++; - (*way)->wpt_class = *p++; + for (i=0; i<6; ++i) { + (*way)->ident[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->cc[i] = *p++; + } + (*way)->wpt_class = *p++; - (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*way)->lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*way)->alt = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*way)->alt = GPS_Util_Get_Short(p); + p+=sizeof(int16); - for(i=0;i<24;++i) (*way)->city[i] = *p++; - for(i=0;i<2;++i) (*way)->state[i] = *p++; - for(i=0;i<30;++i) (*way)->name[i] = *p++; - for(i=0;i<40;++i) (*way)->cmnt[i] = *p++; + for (i=0; i<24; ++i) { + (*way)->city[i] = *p++; + } + for (i=0; i<2; ++i) { + (*way)->state[i] = *p++; + } + for (i=0; i<30; ++i) { + (*way)->name[i] = *p++; + } + for (i=0; i<40; ++i) { + (*way)->cmnt[i] = *p++; + } - (*way)->dst=GPS_Util_Get_Float(p); + (*way)->dst=GPS_Util_Get_Float(p); - return; + return; } @@ -5013,25 +5255,29 @@ static void GPS_D450_Get(GPS_PWay *way, UC *s) ************************************************************************/ static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - for(i=0;i<6;++i) *p++ = way->ident[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 62; + *len = 62; - return; + return; } @@ -5047,28 +5293,32 @@ static void GPS_D400_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - for(i=0;i<6;++i) *p++ = way->ident[i]; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); - GPS_Util_Put_Uint(p,0); - p+=sizeof(int32); - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); + GPS_Util_Put_Uint(p,0); + p+=sizeof(int32); + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - *p++ = way->smbl; - *p = way->dspl; + *p++ = way->smbl; + *p = way->dspl; - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 64; + *len = 64; - return; + return; } @@ -5084,37 +5334,49 @@ static void GPS_D403_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) { - UC *p; - int32 i; + UC *p; + int32 i; - p = data; + p = data; - GPS_Util_Put_Short(p,(US) way->idx); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->idx); + p+=sizeof(int16); - for(i=0;i<6;++i) *p++ = way->ident[i]; - for(i=0;i<2;++i) *p++ = way->cc[i]; - *p++ = way->wpt_class; + for (i=0; i<6; ++i) { + *p++ = way->ident[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->cc[i]; + } + *p++ = way->wpt_class; - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,(int32)GPS_Math_Deg_To_Semi(way->lon)); + p+=sizeof(int32); - GPS_Util_Put_Short(p,(US) way->alt); - p+=sizeof(int16); + GPS_Util_Put_Short(p,(US) way->alt); + p+=sizeof(int16); - for(i=0;i<24;++i) *p++ = way->city[i]; - for(i=0;i<2;++i) *p++ = way->state[i]; - for(i=0;i<30;++i) *p++ = way->name[i]; - for(i=0;i<40;++i) *p++ = way->cmnt[i]; + for (i=0; i<24; ++i) { + *p++ = way->city[i]; + } + for (i=0; i<2; ++i) { + *p++ = way->state[i]; + } + for (i=0; i<30; ++i) { + *p++ = way->name[i]; + } + for (i=0; i<40; ++i) { + *p++ = way->cmnt[i]; + } - GPS_Util_Put_Float(p,way->dst); + GPS_Util_Put_Float(p,way->dst); - *len = 121; + *len = 121; - return; + return; } @@ -5130,100 +5392,110 @@ static void GPS_D450_Send(UC *data, GPS_PWay way, int32 *len) ************************************************************************/ int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - if(n) - if(!((*alm)=(GPS_PAlmanac *)malloc(n*sizeof(GPS_PAlmanac)))) - { - GPS_Error("A500_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata, &((*alm)[i])); - break; - case pD501: - GPS_A500_Translate(recpkt->data, &((*alm)[i])); - (*alm)[i]->hlth=recpkt->data[42]; - break; - case pD550: - (*alm)[i]->svid = recpkt->data[0]; - GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); - break; - case pD551: - (*alm)[i]->svid = recpkt->data[0]; - GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); - (*alm)[i]->hlth = recpkt->data[43]; - break; - default: - GPS_Error("A500_GET: Unknown almanac protocol"); - return PROTOCOL_ERROR; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + if (n) + if (!((*alm)=(GPS_PAlmanac *)malloc(n*sizeof(GPS_PAlmanac)))) { + GPS_Error("A500_Get: Insufficient memory"); + return MEMORY_ERROR; } - /* Cheat and don't _really_ pass the trkpt back */ -/* cb(n, NULL);*/ - } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A500_Get: Error transferring almanac"); - return FRAMING_ERROR; + for (i=0; idata, &((*alm)[i])); + break; + case pD501: + GPS_A500_Translate(recpkt->data, &((*alm)[i])); + (*alm)[i]->hlth=recpkt->data[42]; + break; + case pD550: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + break; + case pD551: + (*alm)[i]->svid = recpkt->data[0]; + GPS_A500_Translate(recpkt->data+1, &((*alm)[i])); + (*alm)[i]->hlth = recpkt->data[43]; + break; + default: + GPS_Error("A500_GET: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + /* Cheat and don't _really_ pass the trkpt back */ + /* cb(n, NULL);*/ + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A500_Get: Error transferring almanac"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A500_GET: Almanac entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return n; } @@ -5239,171 +5511,176 @@ int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm) ************************************************************************/ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) { - UC data[GPS_ARB_LEN]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - int32 timesent; - int32 posnsent; - int32 ret; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data,(US) n); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A500_Send: Almanac start data not acknowledged"); - return FRAMING_ERROR; - } - - - for(i=0;itype == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Time) - { - GPS_User("INFO: GPS time request. Sending...."); - ret = GPS_Rqst_Send_Time(fd,gps_save_time); - if(ret < 0) return ret; - timesent=1; - } + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Almanac_Data, + data, len); + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A500_Send: Almanac Pid_Almanac_Data not acknowledged"); + return FRAMING_ERROR; + } + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Transfer_Alm); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Xfer_Cmplt, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + GPS_Error("A500_Send: Almanac complete data not acknowledged"); + return FRAMING_ERROR; + } + + timesent=posnsent=0; + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the time. Note that the time sent is held in gps_save_time + * global + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Time) { + GPS_User("INFO: GPS time request. Sending...."); + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if (ret < 0) { + return ret; + } + timesent=1; + } + } - /* - * Allow GPS a little while to decide whether it wants to ask for - * the position. Note that the posn sent is held in gps_save_lat - * and gps_save_lon global! - */ - if(GPS_Device_Wait(fd)) - { - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Posn) - { - GPS_User("INFO: GPS position request. Sending...."); - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; - posnsent=1; - } + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon global! + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - if(!timesent) - { - ret = GPS_Rqst_Send_Time(fd,gps_save_time); - if(ret < 0) return ret; + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + posnsent=1; + } + } - if(!posnsent) - { - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; + if (!timesent) { + ret = GPS_Rqst_Send_Time(fd,gps_save_time); + if (ret < 0) { + return ret; } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + if (!posnsent) { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + } - if(!GPS_Device_Off(fd)) - return gps_errno; - return 1; + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } /* @funcstatic GPS_A500_Translate *************************************** @@ -5417,44 +5694,44 @@ int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n) ************************************************************************/ static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm) { - UC *p; + UC *p; - p=s; + p=s; - (*alm)->wn = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*alm)->wn = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*alm)->toa = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->toa = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->af0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->af0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->af1 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->af1 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->e = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->e = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->sqrta = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->sqrta = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->m0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->m0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->w = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->w = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->omg0 = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->omg0 = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->odot = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->odot = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*alm)->i = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*alm)->i = GPS_Util_Get_Float(p); + p+=sizeof(float); - return; + return; } @@ -5469,12 +5746,12 @@ static void GPS_A500_Translate(UC *s, GPS_PAlmanac *alm) ************************************************************************/ static void GPS_D500_Send(UC *data, GPS_PAlmanac alm) { - UC *p; + UC *p; - p = data; - GPS_A500_Encode(p,alm); + p = data; + GPS_A500_Encode(p,alm); - return; + return; } @@ -5490,13 +5767,13 @@ static void GPS_D500_Send(UC *data, GPS_PAlmanac alm) ************************************************************************/ static void GPS_D501_Send(UC *data, GPS_PAlmanac alm) { - UC *p; + UC *p; - p=data; - p[42] = alm->hlth; - GPS_A500_Encode(p,alm); + p=data; + p[42] = alm->hlth; + GPS_A500_Encode(p,alm); - return; + return; } @@ -5512,13 +5789,13 @@ static void GPS_D501_Send(UC *data, GPS_PAlmanac alm) ************************************************************************/ static void GPS_D550_Send(UC *data, GPS_PAlmanac alm) { - UC *p; + UC *p; - p = data; - *p = alm->svid; - GPS_A500_Encode(p+1,alm); + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); - return; + return; } @@ -5534,14 +5811,14 @@ static void GPS_D550_Send(UC *data, GPS_PAlmanac alm) ************************************************************************/ static void GPS_D551_Send(UC *data, GPS_PAlmanac alm) { - UC *p; + UC *p; - p = data; - *p = alm->svid; - GPS_A500_Encode(p+1,alm); - p[43] = alm->hlth; + p = data; + *p = alm->svid; + GPS_A500_Encode(p+1,alm); + p[43] = alm->hlth; - return; + return; } @@ -5557,43 +5834,43 @@ static void GPS_D551_Send(UC *data, GPS_PAlmanac alm) ************************************************************************/ static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) { - UC *p; + UC *p; - p=s; + p=s; - GPS_Util_Put_Short(p,alm->wn); - p+=sizeof(int16); + GPS_Util_Put_Short(p,alm->wn); + p+=sizeof(int16); - GPS_Util_Put_Float(p,alm->toa); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->toa); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->af0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->af0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->af1); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->af1); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->e); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->e); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->sqrta); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->sqrta); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->m0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->m0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->w); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->w); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->omg0); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->omg0); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->odot); - p+=sizeof(float); + GPS_Util_Put_Float(p,alm->odot); + p+=sizeof(float); - GPS_Util_Put_Float(p,alm->i); + GPS_Util_Put_Float(p,alm->i); - return; + return; } @@ -5607,49 +5884,55 @@ static void GPS_A500_Encode(UC *s, GPS_PAlmanac alm) ************************************************************************/ time_t GPS_A600_Get(const char *port) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - time_t ret; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - switch(gps_date_time_type) - { - case pD600: - ret = GPS_D600_Get(rec); - break; - default: - GPS_Error("A600_Get: Unknown data/time protocol"); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return ret; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + time_t ret; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Time); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + switch (gps_date_time_type) { + case pD600: + ret = GPS_D600_Get(rec); + break; + default: + GPS_Error("A600_Get: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return ret; } @@ -5667,73 +5950,80 @@ time_t GPS_A600_Get(const char *port) ************************************************************************/ int32 GPS_A600_Send(const char *port, time_t Time) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - int32 posnsent=0; - int32 ret=0; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - switch(gps_date_time_type) - { - case pD600: - GPS_D600_Send(&tra,Time); - break; - default: - GPS_Error("A600_Send: Unknown data/time protocol"); - return PROTOCOL_ERROR; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + int32 posnsent=0; + int32 ret=0; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + switch (gps_date_time_type) { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Send: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_error; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_error; + } + + + /* + * Allow GPS a little while to decide whether it wants to ask for + * the position. Note that the posn sent is held in gps_save_lat + * and gps_save_lon globals! + */ + if (GPS_Device_Wait(fd)) { + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; } - if(!GPS_Write_Packet(fd,tra)) - return gps_error; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_error; - + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } - /* - * Allow GPS a little while to decide whether it wants to ask for - * the position. Note that the posn sent is held in gps_save_lat - * and gps_save_lon globals! - */ - if(GPS_Device_Wait(fd)) - { - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - if(rec->type == LINK_ID[gps_link_type].Pid_Command_Data && - GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. - Cmnd_Transfer_Posn) - { - GPS_User("INFO: GPS position request. Sending...."); - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; - posnsent=1; - } + if (rec->type == LINK_ID[gps_link_type].Pid_Command_Data && + GPS_Util_Get_Short(rec->data) == COMMAND_ID[gps_device_command]. + Cmnd_Transfer_Posn) { + GPS_User("INFO: GPS position request. Sending...."); + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; + } + posnsent=1; } + } - if(!posnsent) - { - ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); - if(ret < 0) return ret; + if (!posnsent) { + ret = GPS_Rqst_Send_Position(fd,gps_save_lat,gps_save_lon); + if (ret < 0) { + return ret; } + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -5750,21 +6040,21 @@ int32 GPS_A600_Send(const char *port, time_t Time) ************************************************************************/ time_t GPS_D600_Get(GPS_PPacket packet) { - UC *p; - static struct tm ts; + UC *p; + static struct tm ts; - p = packet->data; + p = packet->data; - ts.tm_mon = *p++ - 1; - ts.tm_mday = *p++; - ts.tm_year = (int32) GPS_Util_Get_Short(p) - 1900; - p+=2; - ts.tm_hour = (int32) GPS_Util_Get_Short(p); - p+=2; - ts.tm_min = *p++; - ts.tm_sec = *p++; + ts.tm_mon = *p++ - 1; + ts.tm_mday = *p++; + ts.tm_year = (int32) GPS_Util_Get_Short(p) - 1900; + p+=2; + ts.tm_hour = (int32) GPS_Util_Get_Short(p); + p+=2; + ts.tm_min = *p++; + ts.tm_sec = *p++; - return mktime(&ts); + return mktime(&ts); } @@ -5779,28 +6069,28 @@ time_t GPS_D600_Get(GPS_PPacket packet) ************************************************************************/ void GPS_D600_Send(GPS_PPacket *packet, time_t Time) { - UC data[10]; - UC *p; - struct tm *ts; + UC data[10]; + UC *p; + struct tm *ts; - p = data; + p = data; - ts = localtime(&Time); - *p++ = ts->tm_mon+1; - *p++ = ts->tm_mday; + ts = localtime(&Time); + *p++ = ts->tm_mon+1; + *p++ = ts->tm_mday; - GPS_Util_Put_Short(p,(US) (ts->tm_year+1900)); - p+=2; - GPS_Util_Put_Short(p,(US) ts->tm_hour); - p+=2; + GPS_Util_Put_Short(p,(US)(ts->tm_year+1900)); + p+=2; + GPS_Util_Put_Short(p,(US) ts->tm_hour); + p+=2; - *p++ = ts->tm_min; - *p = ts->tm_sec; + *p++ = ts->tm_min; + *p = ts->tm_sec; - GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Date_Time_Data, - data,8); + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Date_Time_Data, + data,8); - return; + return; } @@ -5818,49 +6108,55 @@ void GPS_D600_Send(GPS_PPacket *packet, time_t Time) ************************************************************************/ int32 GPS_A700_Get(const char *port, double *lat, double *lon) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Posn); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - if(!GPS_Packet_Read(fd, &rec)) - return gps_errno; - if(!GPS_Send_Ack(fd, &tra, &rec)) - return gps_errno; - - switch(gps_position_type) - { - case pD700: - GPS_D700_Get(rec, lat, lon); - break; - default: - GPS_Error("A700_Get: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - if(!GPS_Device_Off(fd)) - return gps_errno; - - return 1; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Posn); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + if (!GPS_Packet_Read(fd, &rec)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + switch (gps_position_type) { + case pD700: + GPS_D700_Get(rec, lat, lon); + break; + default: + GPS_Error("A700_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + return 1; } @@ -5877,40 +6173,44 @@ int32 GPS_A700_Get(const char *port, double *lat, double *lon) ************************************************************************/ int32 GPS_A700_Send(const char *port, double lat, double lon) { - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; - if(!GPS_Device_On(port, &fd)) - return gps_errno; + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - switch(gps_position_type) - { - case pD700: - GPS_D700_Send(&tra,lat,lon); - break; - default: - GPS_Error("A700_Send: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_position_type) { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Send: Unknown position protocol"); + return PROTOCOL_ERROR; + } - if(!GPS_Write_Packet(fd,tra)) - return 0; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return 0; + if (!GPS_Write_Packet(fd,tra)) { + return 0; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return 0; + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -5927,21 +6227,21 @@ int32 GPS_A700_Send(const char *port, double lat, double lon) ************************************************************************/ void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon) { - UC *p; - double t; + UC *p; + double t; - p = packet->data; + p = packet->data; - t = GPS_Util_Get_Double(p); - *lat = GPS_Math_Rad_To_Deg(t); + t = GPS_Util_Get_Double(p); + *lat = GPS_Math_Rad_To_Deg(t); - p += sizeof(double); + p += sizeof(double); - t = GPS_Util_Get_Double(p); - *lon = GPS_Math_Rad_To_Deg(t); + t = GPS_Util_Get_Double(p); + *lon = GPS_Math_Rad_To_Deg(t); - return; + return; } @@ -5957,22 +6257,22 @@ void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon) ************************************************************************/ void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) { - UC data[16]; - UC *p; + UC data[16]; + UC *p; - lat = GPS_Math_Deg_To_Rad(lat); - lon = GPS_Math_Deg_To_Rad(lon); + lat = GPS_Math_Deg_To_Rad(lat); + lon = GPS_Math_Deg_To_Rad(lon); - p = data; + p = data; - GPS_Util_Put_Double(p,lat); - p+=sizeof(double); - GPS_Util_Put_Double(p,lon); + GPS_Util_Put_Double(p,lat); + p+=sizeof(double); + GPS_Util_Put_Double(p,lon); - GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Position_Data, - data,16); + GPS_Make_Packet(packet, LINK_ID[gps_link_type].Pid_Position_Data, + data,16); - return; + return; } @@ -5988,33 +6288,35 @@ void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon) ************************************************************************/ int32 GPS_A800_On(const char *port, gpsdevh **fd) { - static UC data[2]; - GPS_PPacket tra; - GPS_PPacket rec; - - if(!GPS_Device_On(port, fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Start_Pvt_Data); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(*fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(*fd, &tra, &rec)) - { - GPS_Error("A800_on: Pvt start data not acknowledged"); - return FRAMING_ERROR; - } - - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - - return 1; + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!GPS_Device_On(port, fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Start_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(*fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(*fd, &tra, &rec)) { + GPS_Error("A800_on: Pvt start data not acknowledged"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; } @@ -6030,34 +6332,35 @@ int32 GPS_A800_On(const char *port, gpsdevh **fd) ************************************************************************/ int32 GPS_A800_Off(const char *port, gpsdevh **fd) { - static UC data[2]; - GPS_PPacket tra; - GPS_PPacket rec; + static UC data[2]; + GPS_PPacket tra; + GPS_PPacket rec; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Stop_Pvt_Data); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(*fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(*fd, &tra, &rec)) - { - GPS_Error("A800_Off: Not acknowledged"); - return FRAMING_ERROR; - } + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Stop_Pvt_Data); + GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(*fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(*fd, &tra, &rec)) { + GPS_Error("A800_Off: Not acknowledged"); + return FRAMING_ERROR; + } - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); // if(!GPS_Device_Off(*fd)) // return gps_errno; - return 1; + return 1; } @@ -6072,47 +6375,47 @@ int32 GPS_A800_Off(const char *port, gpsdevh **fd) ************************************************************************/ int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) { - GPS_PPacket tra; - GPS_PPacket rec; + GPS_PPacket tra; + GPS_PPacket rec; - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } - if(!GPS_Packet_Read(*fd, &rec)) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return gps_errno; - } - - if(!GPS_Send_Ack(*fd, &tra, &rec)) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return gps_errno; - } - - if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return 0; - } + if (!GPS_Packet_Read(*fd, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } - switch(gps_pvt_type) - { - case pD800: - GPS_D800_Get(rec,packet); - break; - default: - GPS_Error("A800_GET: Unknown pvt protocol"); - GPS_Packet_Del(&rec); - GPS_Packet_Del(&tra); - return PROTOCOL_ERROR; - } + if (!GPS_Send_Ack(*fd, &tra, &rec)) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return gps_errno; + } + if (rec->type != LINK_ID[gps_link_type].Pid_Pvt_Data) { + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + return 0; + } + + switch (gps_pvt_type) { + case pD800: + GPS_D800_Get(rec,packet); + break; + default: + GPS_Error("A800_GET: Unknown pvt protocol"); GPS_Packet_Del(&rec); GPS_Packet_Del(&tra); + return PROTOCOL_ERROR; + } - return 1; + GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + + return 1; } @@ -6128,52 +6431,52 @@ int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet) ************************************************************************/ void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) { - UC *p; + UC *p; - p = packet->data; + p = packet->data; - (*pvt)->alt = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->alt = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->epe = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->epe = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->eph = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->eph = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->epv = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->epv = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->fix = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*pvt)->fix = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*pvt)->tow = GPS_Util_Get_Double(p); - p+=sizeof(double); + (*pvt)->tow = GPS_Util_Get_Double(p); + p+=sizeof(double); - (*pvt)->lat = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); - p+=sizeof(double); + (*pvt)->lat = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); - (*pvt)->lon = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); - p+=sizeof(double); + (*pvt)->lon = GPS_Math_Rad_To_Deg(GPS_Util_Get_Double(p)); + p+=sizeof(double); - (*pvt)->east = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->east = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->north = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->north = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->up = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->up = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->msl_hght = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*pvt)->msl_hght = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*pvt)->leap_scnds = GPS_Util_Get_Short(p); - p+=sizeof(int16); + (*pvt)->leap_scnds = GPS_Util_Get_Short(p); + p+=sizeof(int16); - (*pvt)->wn_days = GPS_Util_Get_Int(p); + (*pvt)->wn_days = GPS_Util_Get_Int(p); - return; + return; } /* @func GPS_A906_Get ****************************************************** @@ -6188,90 +6491,100 @@ void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt) int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_lap_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Laps); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - if(n) - if(!((*lap)=(GPS_PLap *)malloc(n*sizeof(GPS_PLap)))) - { - GPS_Error("A906_Get: Insufficient memory"); - return MEMORY_ERROR; - } + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Laps); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + if (n) + if (!((*lap)=(GPS_PLap *)malloc(n*sizeof(GPS_PLap)))) { + GPS_Error("A906_Get: Insufficient memory"); + return MEMORY_ERROR; + } + + for (i=0; idata); + break; + default: + GPS_Error("A906_Get: Unknown Lap protocol %d\n", gps_lap_type); + return PROTOCOL_ERROR; + } - for(i=0;idata); - break; - default: - GPS_Error("A906_Get: Unknown Lap protocol %d\n", gps_lap_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - cb(n, NULL); - } - - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A906_Get: Error transferring laps"); - return FRAMING_ERROR; - } - - if(i != n) { - GPS_Error("A906_GET: Lap entry number mismatch"); - return FRAMING_ERROR; - } - - GPS_Packet_Del(&trapkt); - GPS_Packet_Del(&recpkt); - - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + cb(n, NULL); + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A906_Get: Error transferring laps"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A906_GET: Lap entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } /* @func GPS_D1011b_Get ****************************************************** @@ -6285,93 +6598,93 @@ int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb) ************************************************************************/ void GPS_D1011b_Get(GPS_PLap *Lap, UC *p) { - uint32 t; - - /* Lap index (not in D906) */ - switch(gps_lap_type) { - case pD906: - (*Lap)->index = -1; - break; - case pD1001: - (*Lap)->index = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); - break; - case pD1011: - case pD1015: - (*Lap)->index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); /*unused*/ - break; - default: - break; - } - - t = GPS_Util_Get_Uint(p); - (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + uint32 t; + + /* Lap index (not in D906) */ + switch (gps_lap_type) { + case pD906: + (*Lap)->index = -1; + break; + case pD1001: + (*Lap)->index = GPS_Util_Get_Uint(p); p+=sizeof(uint32); - - (*Lap)->total_time = GPS_Util_Get_Int(p); - p+=sizeof(int32); - - (*Lap)->total_distance = GPS_Util_Get_Float(p); + break; + case pD1011: + case pD1015: + (*Lap)->index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); /*unused*/ + break; + default: + break; + } + + t = GPS_Util_Get_Uint(p); + (*Lap)->start_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); + + (*Lap)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(int32); + + (*Lap)->total_distance = GPS_Util_Get_Float(p); + p+=sizeof(float); + if (gps_lap_type != pD906) { + (*Lap)->max_speed = GPS_Util_Get_Float(p); p+=sizeof(float); - if(gps_lap_type != pD906){ - (*Lap)->max_speed = GPS_Util_Get_Float(p); - p+=sizeof(float); - } - - (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - - (*Lap)->calories = GPS_Util_Get_Short(p); - p+=sizeof(int16); - - /* Track index, only in D906*/ - if(gps_lap_type == pD906){ - (*Lap)->track_index = *p++; - p++; /*Unused*/ - - /*Last field, no more to do */ - return; - } else { - (*Lap)->track_index = -1; - } - - (*Lap)->avg_heart_rate = *p++; - (*Lap)->max_heart_rate = *p++; - (*Lap)->intensity = *p++; - - switch(gps_lap_type) { - case pD1001: - /*No more fields */ - return; - case pD1011: - case pD1015: - (*Lap)->avg_cadence = *p++; - (*Lap)->trigger_method = *p++; - break; - default: - /*pD906 already returned*/ - break; - } + } + + (*Lap)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*Lap)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + + (*Lap)->calories = GPS_Util_Get_Short(p); + p+=sizeof(int16); + + /* Track index, only in D906*/ + if (gps_lap_type == pD906) { + (*Lap)->track_index = *p++; + p++; /*Unused*/ + + /*Last field, no more to do */ + return; + } else { + (*Lap)->track_index = -1; + } - if (gps_lap_type==pD1015) { - /*some unknown fields like 04 dc 44 ff ff */ - /* (*Lap)->unk1015_1 = *p++; normally 4? - (*Lap)->unk1015_2 = GPS_Util_Get_Short(p);wkt related , ffff otherwise - p+=sizeof(int16); - (*Lap)->unk1015_3 = GPS_Util_Get_Short(p);ffff ? - p+=sizeof(int16); - */ - } + (*Lap)->avg_heart_rate = *p++; + (*Lap)->max_heart_rate = *p++; + (*Lap)->intensity = *p++; + switch (gps_lap_type) { + case pD1001: + /*No more fields */ return; + case pD1011: + case pD1015: + (*Lap)->avg_cadence = *p++; + (*Lap)->trigger_method = *p++; + break; + default: + /*pD906 already returned*/ + break; + } + + if (gps_lap_type==pD1015) { + /*some unknown fields like 04 dc 44 ff ff */ + /* (*Lap)->unk1015_1 = *p++; normally 4? + (*Lap)->unk1015_2 = GPS_Util_Get_Short(p);wkt related , ffff otherwise + p+=sizeof(int16); + (*Lap)->unk1015_3 = GPS_Util_Get_Short(p);ffff ? + p+=sizeof(int16); + */ + } + + return; } @@ -6394,96 +6707,106 @@ void GPS_D1011b_Get(GPS_PLap *Lap, UC *p) ************************************************************************/ int32 GPS_A1006_Get - (const char *port, - GPS_PCourse **crs, - pcb_fn cb) +(const char *port, + GPS_PCourse **crs, + pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Courses); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*crs)=(GPS_PCourse *)malloc(n*sizeof(GPS_PCourse)))) - { - GPS_Error("A1006_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1006_Get: Unknown Course protocol %d\n", - gps_course_type); - return PROTOCOL_ERROR; - } - - // Cheat and don't _really_ pass the crs back - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Courses); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*crs)=(GPS_PCourse *)malloc(n*sizeof(GPS_PCourse)))) { + GPS_Error("A1006_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1006_Get: Error transferring courses"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1006_Get: Unknown Course protocol %d\n", + gps_course_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + // Cheat and don't _really_ pass the crs back + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1006_Get: Error transferring courses"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1006_GET: Course entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -6507,66 +6830,66 @@ int32 GPS_A1006_Send(const char *port, int32 n_crs, gpsdevh *fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_crs); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A1006_Send: Course start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iindex = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); // unused - for(i=0;i<16;++i) - (*crs)->course_name[i] = *p++; - (*crs)->track_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + int i; + (*crs)->index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); // unused + for (i=0; i<16; ++i) { + (*crs)->course_name[i] = *p++; + } + (*crs)->track_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); } @@ -6604,24 +6928,26 @@ void GPS_D1006_Get(GPS_PCourse *crs, UC *p) ************************************************************************/ void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len) { - UC *p; - int j; - p = data; + UC *p; + int j; + p = data; - GPS_Util_Put_Short(p, (US) crs->index); - p += 2; + GPS_Util_Put_Short(p, (US) crs->index); + p += 2; - GPS_Util_Put_Uint(p,0); - p+=sizeof(uint16); + GPS_Util_Put_Uint(p,0); + p+=sizeof(uint16); - for(j=0;j<16;++j) *p++ = crs->course_name[j]; + for (j=0; j<16; ++j) { + *p++ = crs->course_name[j]; + } - GPS_Util_Put_Short(p, (US) crs->track_index); - p += 2; + GPS_Util_Put_Short(p, (US) crs->track_index); + p += 2; - *len = p-data; + *len = p-data; - return; + return; } @@ -6637,91 +6963,101 @@ void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len) int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_lap_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Laps); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*clp)=(GPS_PCourse_Lap *)malloc(n*sizeof(GPS_PCourse_Lap)))) - { - GPS_Error("A1007_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1007_Get: Unknown Course Lap protocol %d\n", - gps_course_lap_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Laps); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*clp)=(GPS_PCourse_Lap *)malloc(n*sizeof(GPS_PCourse_Lap)))) { + GPS_Error("A1007_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1007_Get: Error transferring course laps"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1007_Get: Unknown Course Lap protocol %d\n", + gps_course_lap_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1007_Get: Error transferring course laps"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1007_GET: Course Lap entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -6745,66 +7081,66 @@ int32 GPS_A1007_Send(const char *port, int32 n_clp, gpsdevh *fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_clp); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("A1007_Send: CourseLap start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;icourse_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + (*clp)->course_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); - (*clp)->lap_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); + (*clp)->lap_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); - (*clp)->total_time = GPS_Util_Get_Int(p); - p+=sizeof(uint32); + (*clp)->total_time = GPS_Util_Get_Int(p); + p+=sizeof(uint32); - (*clp)->total_dist = GPS_Util_Get_Float(p); - p+=sizeof(float); + (*clp)->total_dist = GPS_Util_Get_Float(p); + p+=sizeof(float); - (*clp)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); - (*clp)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); - p+=sizeof(int32); + (*clp)->begin_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->begin_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->end_lat = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); + (*clp)->end_lon = GPS_Math_Semi_To_Deg(GPS_Util_Get_Int(p)); + p+=sizeof(int32); - (*clp)->avg_heart_rate = *p++; - (*clp)->max_heart_rate = *p++; - (*clp)->intensity = *p++; - (*clp)->avg_cadence = *p++; + (*clp)->avg_heart_rate = *p++; + (*clp)->max_heart_rate = *p++; + (*clp)->intensity = *p++; + (*clp)->avg_cadence = *p++; - return; + return; } @@ -6861,42 +7197,42 @@ void GPS_D1007_Get(GPS_PCourse_Lap *clp, UC *p) ************************************************************************/ void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len) { - UC *p; - p = data; + UC *p; + p = data; - GPS_Util_Put_Short(p, (US) clp->course_index); - p += 2; + GPS_Util_Put_Short(p, (US) clp->course_index); + p += 2; - GPS_Util_Put_Short(p, (US) clp->lap_index); - p += 2; + GPS_Util_Put_Short(p, (US) clp->lap_index); + p += 2; - GPS_Util_Put_Uint(p, clp->total_time); - p+=sizeof(int32); + GPS_Util_Put_Uint(p, clp->total_time); + p+=sizeof(int32); - GPS_Util_Put_Float(p,clp->total_dist); - p+= sizeof(float); + GPS_Util_Put_Float(p,clp->total_dist); + p+= sizeof(float); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->begin_lon)); + p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lat)); - p+=sizeof(int32); - GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lon)); - p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lat)); + p+=sizeof(int32); + GPS_Util_Put_Int(p,GPS_Math_Deg_To_Semi(clp->end_lon)); + p+=sizeof(int32); - *p++ = clp->avg_heart_rate; + *p++ = clp->avg_heart_rate; - *p++ = clp->max_heart_rate; + *p++ = clp->max_heart_rate; - *p++ = clp->intensity; + *p++ = clp->intensity; - *p++ = clp->avg_cadence; + *p++ = clp->avg_cadence; - *len = p-data; + *len = p-data; - return; + return; } @@ -6912,91 +7248,101 @@ void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len) int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - int32 i, n; - - if (gps_course_point_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Points); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - n = GPS_Util_Get_Short(recpkt->data); - - - if(n) - if(!((*cpt)=(GPS_PCourse_Point *)malloc(n*sizeof(GPS_PCourse_Point)))) - { - GPS_Error("A1008_Get: Insufficient memory"); - return MEMORY_ERROR; - } - - for(i=0;idata); - break; - default: - GPS_Error("A1008_Get: Unknown Course Point protocol %d\n", - gps_course_point_type); - return PROTOCOL_ERROR; - } - - /* Cheat and don't _really_ pass the trkpt back */ - if (cb) { - cb(n, NULL); - } + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + int32 i, n; + + if (gps_course_point_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Points); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + n = GPS_Util_Get_Short(recpkt->data); + + + if (n) + if (!((*cpt)=(GPS_PCourse_Point *)malloc(n*sizeof(GPS_PCourse_Point)))) { + GPS_Error("A1008_Get: Insufficient memory"); + return MEMORY_ERROR; } - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { - GPS_Error("A1008_Get: Error transferring course points"); - return FRAMING_ERROR; + for (i=0; idata); + break; + default: + GPS_Error("A1008_Get: Unknown Course Point protocol %d\n", + gps_course_point_type); + return PROTOCOL_ERROR; + } - if (!GPS_Device_Off(fd)) - return gps_errno; - return n; + /* Cheat and don't _really_ pass the trkpt back */ + if (cb) { + cb(n, NULL); + } + } + + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (recpkt->type != LINK_ID[gps_link_type].Pid_Xfer_Cmplt) { + GPS_Error("A1008_Get: Error transferring course points"); + return FRAMING_ERROR; + } + + if (i != n) { + GPS_Error("A1008_GET: Course Point entry number mismatch"); + return FRAMING_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return n; } @@ -7021,66 +7367,66 @@ int32 GPS_A1008_Send(const char *port, int32 n_cpt, gpsdevh *fd) { - UC data[GPS_ARB_LEN]; - GPS_PPacket tra; - GPS_PPacket rec; - int32 i; - int32 len; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,(US) n_cpt); - GPS_Make_Packet(&tra, LINK_ID[gps_link_type].Pid_Records, - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - { - GPS_Error("GPS_A1008_Send: Coursepoint start data not acknowledged"); - return FRAMING_ERROR; - } - - for(i=0;iname[i] = *p++; - p++; //unused - (*cpt)->course_index = GPS_Util_Get_Short(p); - p+=sizeof(uint16); - p+=sizeof(uint16); // unused + for (i=0; i<11; ++i) { + (*cpt)->name[i] = *p++; + } + p++; //unused + (*cpt)->course_index = GPS_Util_Get_Short(p); + p+=sizeof(uint16); + p+=sizeof(uint16); // unused - t = GPS_Util_Get_Uint(p); - (*cpt)->track_point_time = GPS_Math_Gtime_To_Utime((time_t)t); - p+=sizeof(uint32); + t = GPS_Util_Get_Uint(p); + (*cpt)->track_point_time = GPS_Math_Gtime_To_Utime((time_t)t); + p+=sizeof(uint32); - (*cpt)->point_type = *p++; + (*cpt)->point_type = *p++; } @@ -7126,29 +7473,31 @@ void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p) ************************************************************************/ void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len) { - UC *p; - int j; - p = data; + UC *p; + int j; + p = data; - for(j=0;j<11;++j) *p++ = cpt->name[j]; + for (j=0; j<11; ++j) { + *p++ = cpt->name[j]; + } - GPS_Util_Put_Uint(p,0); - p++; + GPS_Util_Put_Uint(p,0); + p++; - GPS_Util_Put_Short(p, (US) cpt->course_index); - p += 2; + GPS_Util_Put_Short(p, (US) cpt->course_index); + p += 2; - GPS_Util_Put_Uint(p,0); - p+=sizeof(uint16); + GPS_Util_Put_Uint(p,0); + p+=sizeof(uint16); - GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(cpt->track_point_time)); - p+=sizeof(uint32); + GPS_Util_Put_Uint(p,GPS_Math_Utime_To_Gtime(cpt->track_point_time)); + p+=sizeof(uint32); - *p++ = cpt->point_type; + *p++ = cpt->point_type; - *len = p-data; + *len = p-data; - return; + return; } @@ -7164,49 +7513,57 @@ void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len) int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket trapkt; - GPS_PPacket recpkt; - - if (gps_course_limits_transfer == -1) - return GPS_UNSUPPORTED; - - if (!GPS_Device_On(port, &fd)) - return gps_errno; - - if (!(trapkt = GPS_Packet_New() ) || !(recpkt = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data, - COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Limits); - GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, - data,2); - if(!GPS_Write_Packet(fd,trapkt)) - return gps_errno; - if(!GPS_Get_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - if(!GPS_Packet_Read(fd, &recpkt)) - return gps_errno; - if(!GPS_Send_Ack(fd, &trapkt, &recpkt)) - return gps_errno; - - switch(gps_course_limits_type) { - case pD1013: - GPS_D1013_Get(limits,recpkt->data); - break; - default: - GPS_Error("A1009_Get: Unknown Course Limits protocol %d\n", - gps_course_limits_type); - return PROTOCOL_ERROR; - } - - GPS_Packet_Del(&trapkt); - GPS_Packet_Del(&recpkt); - - if (!GPS_Device_Off(fd)) - return gps_errno; - return 1; + static UC data[2]; + gpsdevh *fd; + GPS_PPacket trapkt; + GPS_PPacket recpkt; + + if (gps_course_limits_transfer == -1) { + return GPS_UNSUPPORTED; + } + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(trapkt = GPS_Packet_New()) || !(recpkt = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data, + COMMAND_ID[gps_device_command].Cmnd_Transfer_Course_Limits); + GPS_Make_Packet(&trapkt, LINK_ID[gps_link_type].Pid_Command_Data, + data,2); + if (!GPS_Write_Packet(fd,trapkt)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + if (!GPS_Packet_Read(fd, &recpkt)) { + return gps_errno; + } + if (!GPS_Send_Ack(fd, &trapkt, &recpkt)) { + return gps_errno; + } + + switch (gps_course_limits_type) { + case pD1013: + GPS_D1013_Get(limits,recpkt->data); + break; + default: + GPS_Error("A1009_Get: Unknown Course Limits protocol %d\n", + gps_course_limits_type); + return PROTOCOL_ERROR; + } + + GPS_Packet_Del(&trapkt); + GPS_Packet_Del(&recpkt); + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + return 1; } @@ -7221,17 +7578,17 @@ int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits) ************************************************************************/ void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p) { - limits->max_courses = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_courses = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_laps = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_laps = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_pnt = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); - limits->max_course_trk_pnt = GPS_Util_Get_Uint(p); - p+=sizeof(uint32); + limits->max_course_trk_pnt = GPS_Util_Get_Uint(p); + p+=sizeof(uint32); } @@ -7242,118 +7599,204 @@ void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p) const char * Get_Pkt_Type(US p, US d0, const char **xinfo) { - *xinfo = NULL; + *xinfo = NULL; #define LT LINK_ID[gps_link_type] - if (p == LT.Pid_Ack_Byte) - return "ACK"; - if (p == LT.Pid_Command_Data) { - switch (d0) { - case 0: *xinfo = "Abort"; break; - case 1: *xinfo = "Xfer Alm"; break; - case 2: *xinfo = "Xfer Posn"; break; - case 3: *xinfo = "Xfer Prx"; break; - case 4: *xinfo = "Xfer Rte"; break; - case 5: *xinfo = "Xfer Time"; break; - case 6: *xinfo = "Xfer Trk"; break; - case 7: *xinfo = "Xfer Wpt"; break; - case 8: *xinfo = "Power Down"; break; - case 49: *xinfo = "Xfer PVT Start"; break; - case 50: *xinfo = "Xfer PVT Stop"; break; - case 92: *xinfo = "Flight Records"; break; - case 117: *xinfo = "Xfer Laps"; break; - case 121: *xinfo = "Xfer Categories"; break; - case 450: *xinfo = "Xfer Runs"; break; - case 451: *xinfo = "Xfer Workouts"; break; - case 452: *xinfo = "Xfer Wkt Occurrences"; break; - case 453: *xinfo = "Xfer User Profile "; break; - case 454: *xinfo = "Xfer Wkt Limits"; break; - case 561: *xinfo = "Xfer Courses"; break; - case 562: *xinfo = "Xfer Course Laps"; break; - case 563: *xinfo = "Xfer Course Point"; break; - case 564: *xinfo = "Xfer Course Tracks"; break; - case 565: *xinfo = "Xfer Course Limits"; break; - - default: *xinfo = "Unknown"; - } - return "CMDDAT"; - } - if (p == LT.Pid_Protocol_Array) - return "PRTARR"; - if (p == LT.Pid_Product_Rqst) - return "PRDREQ"; - if (p == LT.Pid_Product_Data) - return "PRDDAT"; - if (p == LT.Pid_Ext_Product_Data) - return "PRDEDA"; - - if (p == LT.Pid_Xfer_Cmplt) - return "XFRCMP"; - if (p == LT.Pid_Date_Time_Data) - return "DATTIM"; - if (p == LT.Pid_Position_Data) - return "POS"; - if (p == LT.Pid_Prx_Wpt_Data) - return "WPT"; - if (p == LT.Pid_Nak_Byte) - return "NAK"; - if (p == LT.Pid_Records) - return "RECORD"; - if (p == LT.Pid_Rte_Hdr) - return "RTEHDR"; - if (p == LT.Pid_Rte_Wpt_Data) - return "RTEWPT"; - if (p == LT.Pid_Almanac_Data) - return "RALMAN"; - if (p == LT.Pid_Trk_Data) - return "TRKDAT"; - if (p == LT.Pid_Wpt_Data) - return "WPTDAT"; - if (p == LT.Pid_Pvt_Data) - return "PVTDAT"; - if (p == LT.Pid_Rte_Link_Data) - return "LNKDAT"; - if (p == LT.Pid_Trk_Hdr) - return "TRKHDR"; - - if (p == LT.Pid_FlightBook_Record) - return "FLIBOO"; - if (p == LT.Pid_Lap) - return "LAPDAT"; - if (p == LT.Pid_Wpt_Cat) - return "WPTCAT"; - if (p == LT.Pid_Run) - return "RUNDAT"; - if (p == LT.Pid_Workout) - return "WKTDAT"; - if (p == LT.Pid_Workout_Occurrence) - return "WKTOCC"; - if (p == LT.Pid_Fitness_User_Profile) - return "UPROFI"; - if (p == LT.Pid_Workout_Limits) - return "WKTLIM"; - if (p == LT.Pid_Course) - return "CRSDAT"; - if (p == LT.Pid_Course_Lap) - return "CRSLAP"; - if (p == LT.Pid_Course_Point) - return "CRSPOI"; - if (p == LT.Pid_Course_Trk_Hdr) - return "CRSTHD"; - if (p == LT.Pid_Course_Trk_Data) - return "CRSTDA"; - if (p == LT.Pid_Course_Limits) - return "CRSLIM"; - if (p == LT.Pid_Trk2_Hdr) - return "TRKHD2"; - - if (p == GUSB_REQUEST_BULK) - return "REQBLK"; - if (p == GUSB_SESSION_START) - return "SESREQ"; - if (p == GUSB_SESSION_ACK) - return "SESACK"; - - return "UNKNOWN"; + if (p == LT.Pid_Ack_Byte) { + return "ACK"; + } + if (p == LT.Pid_Command_Data) { + switch (d0) { + case 0: + *xinfo = "Abort"; + break; + case 1: + *xinfo = "Xfer Alm"; + break; + case 2: + *xinfo = "Xfer Posn"; + break; + case 3: + *xinfo = "Xfer Prx"; + break; + case 4: + *xinfo = "Xfer Rte"; + break; + case 5: + *xinfo = "Xfer Time"; + break; + case 6: + *xinfo = "Xfer Trk"; + break; + case 7: + *xinfo = "Xfer Wpt"; + break; + case 8: + *xinfo = "Power Down"; + break; + case 49: + *xinfo = "Xfer PVT Start"; + break; + case 50: + *xinfo = "Xfer PVT Stop"; + break; + case 92: + *xinfo = "Flight Records"; + break; + case 117: + *xinfo = "Xfer Laps"; + break; + case 121: + *xinfo = "Xfer Categories"; + break; + case 450: + *xinfo = "Xfer Runs"; + break; + case 451: + *xinfo = "Xfer Workouts"; + break; + case 452: + *xinfo = "Xfer Wkt Occurrences"; + break; + case 453: + *xinfo = "Xfer User Profile "; + break; + case 454: + *xinfo = "Xfer Wkt Limits"; + break; + case 561: + *xinfo = "Xfer Courses"; + break; + case 562: + *xinfo = "Xfer Course Laps"; + break; + case 563: + *xinfo = "Xfer Course Point"; + break; + case 564: + *xinfo = "Xfer Course Tracks"; + break; + case 565: + *xinfo = "Xfer Course Limits"; + break; + + default: + *xinfo = "Unknown"; + } + return "CMDDAT"; + } + if (p == LT.Pid_Protocol_Array) { + return "PRTARR"; + } + if (p == LT.Pid_Product_Rqst) { + return "PRDREQ"; + } + if (p == LT.Pid_Product_Data) { + return "PRDDAT"; + } + if (p == LT.Pid_Ext_Product_Data) { + return "PRDEDA"; + } + + if (p == LT.Pid_Xfer_Cmplt) { + return "XFRCMP"; + } + if (p == LT.Pid_Date_Time_Data) { + return "DATTIM"; + } + if (p == LT.Pid_Position_Data) { + return "POS"; + } + if (p == LT.Pid_Prx_Wpt_Data) { + return "WPT"; + } + if (p == LT.Pid_Nak_Byte) { + return "NAK"; + } + if (p == LT.Pid_Records) { + return "RECORD"; + } + if (p == LT.Pid_Rte_Hdr) { + return "RTEHDR"; + } + if (p == LT.Pid_Rte_Wpt_Data) { + return "RTEWPT"; + } + if (p == LT.Pid_Almanac_Data) { + return "RALMAN"; + } + if (p == LT.Pid_Trk_Data) { + return "TRKDAT"; + } + if (p == LT.Pid_Wpt_Data) { + return "WPTDAT"; + } + if (p == LT.Pid_Pvt_Data) { + return "PVTDAT"; + } + if (p == LT.Pid_Rte_Link_Data) { + return "LNKDAT"; + } + if (p == LT.Pid_Trk_Hdr) { + return "TRKHDR"; + } + + if (p == LT.Pid_FlightBook_Record) { + return "FLIBOO"; + } + if (p == LT.Pid_Lap) { + return "LAPDAT"; + } + if (p == LT.Pid_Wpt_Cat) { + return "WPTCAT"; + } + if (p == LT.Pid_Run) { + return "RUNDAT"; + } + if (p == LT.Pid_Workout) { + return "WKTDAT"; + } + if (p == LT.Pid_Workout_Occurrence) { + return "WKTOCC"; + } + if (p == LT.Pid_Fitness_User_Profile) { + return "UPROFI"; + } + if (p == LT.Pid_Workout_Limits) { + return "WKTLIM"; + } + if (p == LT.Pid_Course) { + return "CRSDAT"; + } + if (p == LT.Pid_Course_Lap) { + return "CRSLAP"; + } + if (p == LT.Pid_Course_Point) { + return "CRSPOI"; + } + if (p == LT.Pid_Course_Trk_Hdr) { + return "CRSTHD"; + } + if (p == LT.Pid_Course_Trk_Data) { + return "CRSTDA"; + } + if (p == LT.Pid_Course_Limits) { + return "CRSLIM"; + } + if (p == LT.Pid_Trk2_Hdr) { + return "TRKHD2"; + } + + if (p == GUSB_REQUEST_BULK) { + return "REQBLK"; + } + if (p == GUSB_SESSION_START) { + return "SESREQ"; + } + if (p == GUSB_SESSION_ACK) { + return "SESACK"; + } + + return "UNKNOWN"; } @@ -7370,13 +7813,13 @@ Get_Pkt_Type(US p, US d0, const char **xinfo) ************************************************************************/ static UC Is_Trackpoint_Invalid(GPS_PTrack trk) { - /* FIXME: We should have more *_is_unknown fields instead of - * checking for special values here (e.g. cadence = 0 would be - * perfectly valid, but GPS_D303b_Get() chose to use it to mark - * nonexistent cadence data. - */ - return trk->no_latlon && trk->distance > 1e24 && - !trk->heartrate && !trk->cadence; + /* FIXME: We should have more *_is_unknown fields instead of + * checking for special values here (e.g. cadence = 0 would be + * perfectly valid, but GPS_D303b_Get() chose to use it to mark + * nonexistent cadence data. + */ + return trk->no_latlon && trk->distance > 1e24 && + !trk->heartrate && !trk->cadence; } @@ -7389,43 +7832,38 @@ static UC Is_Trackpoint_Invalid(GPS_PTrack trk) ************************************************************************/ void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n) { - int32 i, j; - - /* D303/304 marks track segments with two consecutive invalid track - * points instead of the tnew flag. Create them unless we're at the - * beginning of a track or there are already invalid track points - * (because the track was downloaded using D303/304). This needs to be - * done here because it will change the number of track points. - */ - if (gps_trk_type == pD303 || gps_trk_type == pD304) - { - for(i=0;i<*n;++i) - { - if ((*trk)[i]->tnew && i>0 && !(*trk)[i]->ishdr && !(*trk)[i-1]->ishdr) - { - /* Create invalid points based on the data from the point - * marked with tnew and the one before it. - */ - for (j=i-1; j<=i; j++) - { - if (!Is_Trackpoint_Invalid((*trk)[j])) - { - GPS_PTrack trkpt = GPS_Track_New(); - *trkpt = *((*trk)[j]); - trkpt->no_latlon = 1; - trkpt->alt = (float) 1e25; - trkpt->distance_populated = 0; - trkpt->heartrate = 0; - trkpt->cadence = 0xff; - *trk = xrealloc(*trk, (*n+1) * sizeof(GPS_PTrack)); - memmove(&(*trk)[i+1], &(*trk)[i], (*n-i) * sizeof(GPS_PTrack)); - (*trk)[i] = trkpt; - i++; - j++; - (*n)++; - } - } - } - } + int32 i, j; + + /* D303/304 marks track segments with two consecutive invalid track + * points instead of the tnew flag. Create them unless we're at the + * beginning of a track or there are already invalid track points + * (because the track was downloaded using D303/304). This needs to be + * done here because it will change the number of track points. + */ + if (gps_trk_type == pD303 || gps_trk_type == pD304) { + for (i=0; i<*n; ++i) { + if ((*trk)[i]->tnew && i>0 && !(*trk)[i]->ishdr && !(*trk)[i-1]->ishdr) { + /* Create invalid points based on the data from the point + * marked with tnew and the one before it. + */ + for (j=i-1; j<=i; j++) { + if (!Is_Trackpoint_Invalid((*trk)[j])) { + GPS_PTrack trkpt = GPS_Track_New(); + *trkpt = *((*trk)[j]); + trkpt->no_latlon = 1; + trkpt->alt = (float) 1e25; + trkpt->distance_populated = 0; + trkpt->heartrate = 0; + trkpt->cadence = 0xff; + *trk = xrealloc(*trk, (*n+1) * sizeof(GPS_PTrack)); + memmove(&(*trk)[i+1], &(*trk)[i], (*n-i) * sizeof(GPS_PTrack)); + (*trk)[i] = trkpt; + i++; + j++; + (*n)++; + } + } + } } + } } diff --git a/gpsbabel/jeeps/gpsapp.h b/gpsbabel/jeeps/gpsapp.h index 6d1ee33cc..9df0700ae 100644 --- a/gpsbabel/jeeps/gpsapp.h +++ b/gpsbabel/jeeps/gpsapp.h @@ -9,112 +9,112 @@ extern "C" #include "gps.h" -int32 GPS_Init(const char *port); - -int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int ct, GPS_PWay *)); -int32 GPS_A101_Get(const char *port); -int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)); - -int32 GPS_A200_Get(const char *port, GPS_PWay **way); -int32 GPS_A201_Get(const char *port, GPS_PWay **way); -int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n); -int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n); - -int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); -int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid); -int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n); -int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, - gpsdevh *fd); - -int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *h); -void GPS_D300b_Get(GPS_PTrack *trk, UC *data); -void GPS_D301b_Get(GPS_PTrack *trk, UC *data); -void GPS_D302b_Get(GPS_PTrack *trk, UC *data); -void GPS_D303b_Get(GPS_PTrack *trk, UC *data); /*D304*/ -void GPS_D310_Get(GPS_PTrack *trk, UC *s); -void GPS_D311_Get(GPS_PTrack *trk, UC *s); -void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len); -void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type); -void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid); -void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len); -void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len); - -int32 GPS_A400_Get(const char *port, GPS_PWay **way); -int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n); - -int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm); -int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n); - -time_t GPS_A600_Get(const char *port); -time_t GPS_D600_Get(GPS_PPacket packet); -int32 GPS_A600_Send(const char *port, time_t Time); -void GPS_D600_Send(GPS_PPacket *packet, time_t Time); - -int32 GPS_A700_Get(const char *port, double *lat, double *lon); -int32 GPS_A700_Send(const char *port, double lat, double lon); -void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon); -void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon); - -int32 GPS_A800_On(const char *port, gpsdevh **fd); -int32 GPS_A800_Off(const char *port, gpsdevh **fd); -int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet); -void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt); - -int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb); -void GPS_D1011b_Get(GPS_PLap *Lap,UC *data); /*D906 D1001 D1015*/ - -int32 GPS_A1006_Get(const char *port, GPS_PCourse **crs, pcb_fn cb); -int32 GPS_A1006_Send(const char *port, GPS_PCourse *crs, int32 n_crs, - gpsdevh *fd); -void GPS_D1006_Get(GPS_PCourse *crs, UC *p); -void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len); - -int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb); -int32 GPS_A1007_Send(const char *port, GPS_PCourse_Lap *clp, int32 n_clp, - gpsdevh *fd); -void GPS_D1007_Get(GPS_PCourse_Lap *clp, UC *p); -void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len); - -int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb); -int32 GPS_A1008_Send(const char *port, GPS_PCourse_Point *cpt, int32 n_cpt, - gpsdevh *fd); -void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p); -void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len); - -int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits); -void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p); - -/* Unhandled documented protocols, as of: - Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C -A650 FlightBook Transfer Protocol -A1000 Run Transfer Protocol - Capability A1000: D1009 - D1000 D1010 -A1002 Workout Transfer Protocol - Capability A1002: D1008 - D1002 - Capability A1003: D1003 -A1004 Fitness User Profile Transfer Protocol - Capability A1004: D1004 -A1005 Workout Limits Transfer Protocol - Capability A1005: D1005 -*/ -/* Unimplemted and Undocumented, as listed from the following device/sw: - GF305 3.70 - -Capability A601: D601 -Capability A801: D801 - -Capability A902: -Capability A903: -Capability A907: D907 D908 D909 D910 -Capability A918: D918 -Capability A1013: D1014 -*/ - -const char * Get_Pkt_Type(US p, US d0, const char **xinfo); - -void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n); + int32 GPS_Init(const char *port); + + int32 GPS_A100_Get(const char *port, GPS_PWay **way, int (*cb)(int ct, GPS_PWay *)); + int32 GPS_A101_Get(const char *port); + int32 GPS_A100_Send(const char *port, GPS_PWay *way, int32 n, int (*cb)(GPS_PWay *)); + + int32 GPS_A200_Get(const char *port, GPS_PWay **way); + int32 GPS_A201_Get(const char *port, GPS_PWay **way); + int32 GPS_A200_Send(const char *port, GPS_PWay *way, int32 n); + int32 GPS_A201_Send(const char *port, GPS_PWay *way, int32 n); + + int32 GPS_A300_Get(const char *port, GPS_PTrack **trk, pcb_fn cb); + int32 GPS_A301_Get(const char *port, GPS_PTrack **trk, pcb_fn cb, int protoid); + int32 GPS_A300_Send(const char *port, GPS_PTrack *trk, int32 n); + int32 GPS_A301_Send(const char *port, GPS_PTrack *trk, int32 n, int protoid, + gpsdevh *fd); + + int32 GPS_D300_Get(GPS_PTrack *trk, int32 entries, gpsdevh *h); + void GPS_D300b_Get(GPS_PTrack *trk, UC *data); + void GPS_D301b_Get(GPS_PTrack *trk, UC *data); + void GPS_D302b_Get(GPS_PTrack *trk, UC *data); + void GPS_D303b_Get(GPS_PTrack *trk, UC *data); /*D304*/ + void GPS_D310_Get(GPS_PTrack *trk, UC *s); + void GPS_D311_Get(GPS_PTrack *trk, UC *s); + void GPS_D300_Send(UC *data, GPS_PTrack trk, int32 *len); + void GPS_D301_Send(UC *data, GPS_PTrack trk, int32 *len, int type); + void GPS_D303_Send(UC *data, GPS_PTrack trk, int32 *len, int protoid); + void GPS_D310_Send(UC *data, GPS_PTrack trk, int32 *len); + void GPS_D311_Send(UC *data, GPS_PTrack trk, int32 *len); + + int32 GPS_A400_Get(const char *port, GPS_PWay **way); + int32 GPS_A400_Send(const char *port, GPS_PWay *way, int32 n); + + int32 GPS_A500_Get(const char *port, GPS_PAlmanac **alm); + int32 GPS_A500_Send(const char *port, GPS_PAlmanac *alm, int32 n); + + time_t GPS_A600_Get(const char *port); + time_t GPS_D600_Get(GPS_PPacket packet); + int32 GPS_A600_Send(const char *port, time_t Time); + void GPS_D600_Send(GPS_PPacket *packet, time_t Time); + + int32 GPS_A700_Get(const char *port, double *lat, double *lon); + int32 GPS_A700_Send(const char *port, double lat, double lon); + void GPS_D700_Get(GPS_PPacket packet, double *lat, double *lon); + void GPS_D700_Send(GPS_PPacket *packet, double lat, double lon); + + int32 GPS_A800_On(const char *port, gpsdevh **fd); + int32 GPS_A800_Off(const char *port, gpsdevh **fd); + int32 GPS_A800_Get(gpsdevh **fd, GPS_PPvt_Data *packet); + void GPS_D800_Get(GPS_PPacket packet, GPS_PPvt_Data *pvt); + + int32 GPS_A906_Get(const char *port, GPS_PLap **lap, pcb_fn cb); + void GPS_D1011b_Get(GPS_PLap *Lap,UC *data); /*D906 D1001 D1015*/ + + int32 GPS_A1006_Get(const char *port, GPS_PCourse **crs, pcb_fn cb); + int32 GPS_A1006_Send(const char *port, GPS_PCourse *crs, int32 n_crs, + gpsdevh *fd); + void GPS_D1006_Get(GPS_PCourse *crs, UC *p); + void GPS_D1006_Send(UC *data, GPS_PCourse crs, int32 *len); + + int32 GPS_A1007_Get(const char *port, GPS_PCourse_Lap **clp, pcb_fn cb); + int32 GPS_A1007_Send(const char *port, GPS_PCourse_Lap *clp, int32 n_clp, + gpsdevh *fd); + void GPS_D1007_Get(GPS_PCourse_Lap *clp, UC *p); + void GPS_D1007_Send(UC *data, GPS_PCourse_Lap clp, int32 *len); + + int32 GPS_A1008_Get(const char *port, GPS_PCourse_Point **cpt, pcb_fn cb); + int32 GPS_A1008_Send(const char *port, GPS_PCourse_Point *cpt, int32 n_cpt, + gpsdevh *fd); + void GPS_D1012_Get(GPS_PCourse_Point *cpt, UC *p); + void GPS_D1012_Send(UC *data, GPS_PCourse_Point cpt, int32 *len); + + int32 GPS_A1009_Get(const char *port, GPS_PCourse_Limits limits); + void GPS_D1013_Get(GPS_PCourse_Limits limits, UC *p); + + /* Unhandled documented protocols, as of: + Garmin Device Interface Specification, May 19, 2006, Drawing Number: 001-00063-00 Rev. C + A650 FlightBook Transfer Protocol + A1000 Run Transfer Protocol + Capability A1000: D1009 + D1000 D1010 + A1002 Workout Transfer Protocol + Capability A1002: D1008 + D1002 + Capability A1003: D1003 + A1004 Fitness User Profile Transfer Protocol + Capability A1004: D1004 + A1005 Workout Limits Transfer Protocol + Capability A1005: D1005 + */ + /* Unimplemted and Undocumented, as listed from the following device/sw: + GF305 3.70 + + Capability A601: D601 + Capability A801: D801 + + Capability A902: + Capability A903: + Capability A907: D907 D908 D909 D910 + Capability A918: D918 + Capability A1013: D1014 + */ + + const char * Get_Pkt_Type(US p, US d0, const char **xinfo); + + void GPS_Prepare_Track_For_Device(GPS_PTrack **trk, int32 *n); #endif diff --git a/gpsbabel/jeeps/gpscom.c b/gpsbabel/jeeps/gpscom.c index 1e9f0eaeb..06ce93a9e 100644 --- a/gpsbabel/jeeps/gpscom.c +++ b/gpsbabel/jeeps/gpscom.c @@ -2,23 +2,23 @@ ** @source JEEPS command functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2005, 2006 Robert Lipe ** @modified Copyright (C) 2007 Achim Schumacher ** @modified Copyright (C) 2010 Martin Buck ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -38,41 +38,45 @@ int32 GPS_Command_Off(const char *port) { - static UC data[2]; - gpsdevh *fd; - GPS_PPacket tra; - GPS_PPacket rec; - - GPS_Util_Little(); - - if(!GPS_Device_On(port, &fd)) - return gps_errno; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Turn_Off_Pwr); - - /* robertl - LINK_ID isn't set yet. Hardcode it to Garmin spec value */ - GPS_Make_Packet(&tra, 10, /* LINK_ID[gps_link_type].Pid_Command_Data, */ - data,2); - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Device_Chars_Ready(fd)) - { - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - GPS_User("Power off command acknowledged"); + static UC data[2]; + gpsdevh *fd; + GPS_PPacket tra; + GPS_PPacket rec; + + GPS_Util_Little(); + + if (!GPS_Device_On(port, &fd)) { + return gps_errno; + } + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + GPS_Util_Put_Short(data,COMMAND_ID[gps_device_command].Cmnd_Turn_Off_Pwr); + + /* robertl - LINK_ID isn't set yet. Hardcode it to Garmin spec value */ + GPS_Make_Packet(&tra, 10, /* LINK_ID[gps_link_type].Pid_Command_Data, */ + data,2); + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Device_Chars_Ready(fd)) { + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; } + GPS_User("Power off command acknowledged"); + } - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - if(!GPS_Device_Off(fd)) - return gps_errno; + if (!GPS_Device_Off(fd)) { + return gps_errno; + } - return 1; + return 1; } @@ -88,33 +92,32 @@ int32 GPS_Command_Off(const char *port) int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way, pcb_fn cb) { - int32 ret=0; - - /* - * It's a bit tacky to do this up front without ticking the - * progress meter, but this come in pretty quickly... - */ - if (gps_category_transfer) { - ret = GPS_A101_Get(port); - if (!ret) { -fatal("blah"); - return PROTOCOL_ERROR; - } - + int32 ret=0; + + /* + * It's a bit tacky to do this up front without ticking the + * progress meter, but this come in pretty quickly... + */ + if (gps_category_transfer) { + ret = GPS_A101_Get(port); + if (!ret) { + fatal("blah"); + return PROTOCOL_ERROR; } - switch(gps_waypt_transfer) - { - case pA100: - ret = GPS_A100_Get(port,way, cb); - break; - default: - GPS_Error("Get_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } + } + + switch (gps_waypt_transfer) { + case pA100: + ret = GPS_A100_Get(port,way, cb); + break; + default: + GPS_Error("Get_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} @@ -131,20 +134,19 @@ fatal("blah"); int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)) { - int32 ret=0; - - switch(gps_waypt_transfer) - { - case pA100: - ret = GPS_A100_Send(port, way, n, cb); - break; - default: - GPS_Error("Send_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_waypt_transfer) { + case pA100: + ret = GPS_A100_Send(port, way, n, cb); + break; + default: + GPS_Error("Send_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Route ************************************** @@ -159,23 +161,22 @@ int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (* int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way) { - int32 ret=0; - - switch(gps_route_transfer) - { - case pA200: - ret = GPS_A200_Get(port,way); - break; - case pA201: - ret = GPS_A201_Get(port,way); - break; - default: - GPS_Error("Get_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_route_transfer) { + case pA200: + ret = GPS_A200_Get(port,way); + break; + case pA201: + ret = GPS_A201_Get(port,way); + break; + default: + GPS_Error("Get_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -192,24 +193,23 @@ int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way) int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) { - int32 ret=0; - - - switch(gps_route_transfer) - { - case pA200: - ret = GPS_A200_Send(port, way, n); - break; - case pA201: - ret = GPS_A201_Send(port, way, n); - break; - default: - GPS_Error("Send_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + + switch (gps_route_transfer) { + case pA200: + ret = GPS_A200_Send(port, way, n); + break; + case pA201: + ret = GPS_A201_Send(port, way, n); + break; + default: + GPS_Error("Send_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Track *************************************** @@ -224,27 +224,27 @@ int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n) int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) { - int32 ret=0; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_trk_transfer) - { - case pA300: - ret = GPS_A300_Get(port,trk,cb); - break; - case pA301: - case pA302: - ret = GPS_A301_Get(port,trk,cb,301); - break; - default: - GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_trk_transfer) { + case pA300: + ret = GPS_A300_Get(port,trk,cb); + break; + case pA301: + case pA302: + ret = GPS_A301_Get(port,trk,cb,301); + break; + default: + GPS_Error("Get_Track: Unknown track protocol %d\n", gps_trk_transfer); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -261,32 +261,32 @@ int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, pcb_fn cb) int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int eraset) { - int32 ret=0; - - if(gps_trk_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_trk_transfer) - { - case pA300: - ret = GPS_A300_Send(port, trk, n); - break; - case pA301: - ret = GPS_A301_Send(port, trk, n, 301, NULL); - break; - case pA302: - /* Units with A302 don't support track upload, so we convert the - * track to a course on the fly and send that instead - */ - ret = GPS_Command_Send_Track_As_Course(port, trk, n, NULL, 0, eraset); - break; - default: - GPS_Error("Send_Track: Unknown track protocol %d.", gps_trk_transfer); - break; - } - - return ret; -} + int32 ret=0; + + if (gps_trk_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_trk_transfer) { + case pA300: + ret = GPS_A300_Send(port, trk, n); + break; + case pA301: + ret = GPS_A301_Send(port, trk, n, 301, NULL); + break; + case pA302: + /* Units with A302 don't support track upload, so we convert the + * track to a course on the fly and send that instead + */ + ret = GPS_Command_Send_Track_As_Course(port, trk, n, NULL, 0, eraset); + break; + default: + GPS_Error("Send_Track: Unknown track protocol %d.", gps_trk_transfer); + break; + } + + return ret; +} /* @func GPS_Command_Get_Proximity ************************************** @@ -301,23 +301,23 @@ int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int era int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way) { - int32 ret=0; - - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_prx_waypt_transfer) - { - case pA400: - ret = GPS_A400_Get(port,way); - break; - default: - GPS_Error("Get_Proximity: Unknown proximity protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_prx_waypt_transfer) { + case pA400: + ret = GPS_A400_Get(port,way); + break; + default: + GPS_Error("Get_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -334,25 +334,25 @@ int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way) int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n) { - int32 ret=0; + int32 ret=0; - if(gps_prx_waypt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_prx_waypt_transfer == -1) { + return GPS_UNSUPPORTED; + } - switch(gps_prx_waypt_transfer) - { - case pA400: - ret = GPS_A400_Send(port, way, n); - break; - default: - GPS_Error("Send_Proximity: Unknown proximity protocol"); - break; - } + switch (gps_prx_waypt_transfer) { + case pA400: + ret = GPS_A400_Send(port, way, n); + break; + default: + GPS_Error("Send_Proximity: Unknown proximity protocol"); + break; + } - return ret; -} + return ret; +} @@ -368,23 +368,23 @@ int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n) int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm) { - int32 ret=0; - - if(gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_almanac_transfer) - { - case pA500: - ret = GPS_A500_Get(port,alm); - break; - default: - GPS_Error("Get_Almanac: Unknown almanac protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_almanac_transfer) { + case pA500: + ret = GPS_A500_Get(port,alm); + break; + default: + GPS_Error("Get_Almanac: Unknown almanac protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -401,23 +401,23 @@ int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm) int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n) { - int32 ret=0; - - if(gps_almanac_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_almanac_transfer) - { - case pA500: - ret = GPS_A500_Send(port, alm, n); - break; - default: - GPS_Error("Send_Almanac: Unknown almanac protocol"); - break; - } - - return ret; -} + int32 ret=0; + + if (gps_almanac_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_almanac_transfer) { + case pA500: + ret = GPS_A500_Send(port, alm, n); + break; + default: + GPS_Error("Send_Almanac: Unknown almanac protocol"); + break; + } + + return ret; +} @@ -432,26 +432,25 @@ int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n) time_t GPS_Command_Get_Time(const char *port) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Get(port); - break; - /* - * If the unit doesn't support it (i.e. a C320 in charging mode), + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Get(port); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), * but don't treat as error; return as zero. */ - case -1: - return 0; - default: - GPS_Error("Get_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + case -1: + return 0; + default: + GPS_Error("Get_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -467,20 +466,19 @@ time_t GPS_Command_Get_Time(const char *port) int32 GPS_Command_Send_Time(const char *port, time_t Time) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Send(port, Time); - break; - default: - GPS_Error("Send_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Send(port, Time); + break; + default: + GPS_Error("Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -498,27 +496,26 @@ int32 GPS_Command_Send_Time(const char *port, time_t Time) int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Get(port,lat,lon); - break; - /* - * If the unit doesn't support it (i.e. a C320 in charging mode), - * zero lat/lon, but don't treat as error. + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Get(port,lat,lon); + break; + /* + * If the unit doesn't support it (i.e. a C320 in charging mode), + * zero lat/lon, but don't treat as error. */ - case -1: - *lat = *lon = 0.0; - break; - default: - GPS_Error("Get_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + case -1: + *lat = *lon = 0.0; + break; + default: + GPS_Error("Get_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -535,21 +532,20 @@ int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon) int32 GPS_Command_Send_Position(const char *port, double lat, double lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Send(port, lat, lon); - break; - default: - GPS_Error("Send_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Send(port, lat, lon); + break; + default: + GPS_Error("Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} - return ret; -} - /* @func GPS_Command_Pvt_On ******************************************** ** @@ -563,26 +559,26 @@ int32 GPS_Command_Send_Position(const char *port, double lat, double lon) int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) { - int32 ret=0; + int32 ret=0; - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_On(port,fd); - break; - default: - GPS_Error("Pvt_On: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_On(port,fd); + break; + default: + GPS_Error("Pvt_On: Unknown position protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} @@ -598,24 +594,24 @@ int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd) int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) { - int32 ret=0; - - - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_Off(port,fd); - break; - default: - GPS_Error("Pvt_Off: Unknown position protocol"); - return PROTOCOL_ERROR; - } + int32 ret=0; - return ret; -} + + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_Off(port,fd); + break; + default: + GPS_Error("Pvt_Off: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -631,25 +627,25 @@ int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd) int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) { - int32 ret=0; + int32 ret=0; - if(gps_pvt_transfer == -1) - return GPS_UNSUPPORTED; + if (gps_pvt_transfer == -1) { + return GPS_UNSUPPORTED; + } - (*pvt)->fix = 0; + (*pvt)->fix = 0; - switch(gps_pvt_transfer) - { - case pA800: - ret = GPS_A800_Get(fd,pvt); - break; - default: - GPS_Error("Pvt_Get: Unknown position protocol"); - return PROTOCOL_ERROR; - } + switch (gps_pvt_transfer) { + case pA800: + ret = GPS_A800_Get(fd,pvt); + break; + default: + GPS_Error("Pvt_Get: Unknown position protocol"); + return PROTOCOL_ERROR; + } - return ret; -} + return ret; +} /* @func GPS_Command_Get_Lap *************************************** ** @@ -663,23 +659,23 @@ int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt) int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, pcb_fn cb) { - int32 ret=0; - - if(gps_lap_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_lap_transfer) - { - case pA906: - ret = GPS_A906_Get(port,lap, cb); - break; - default: - GPS_Error("Get_Lap: Unknown lap protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + if (gps_lap_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_lap_transfer) { + case pA906: + ret = GPS_A906_Get(port,lap, cb); + break; + default: + GPS_Error("Get_Lap: Unknown lap protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} /* @func GPS_Command_Get_Course *************************************** ** @@ -699,67 +695,64 @@ int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, pcb_fn cb) ** @return [int32] number of course entries ************************************************************************/ int32 GPS_Command_Get_Course - (const char *port, - GPS_PCourse **crs, - GPS_PCourse_Lap **clp, - GPS_PTrack **trk, - GPS_PCourse_Point **cpt, - int32 *n_clp, - int32 *n_trk, - int32 *n_cpt, - pcb_fn cb) +(const char *port, + GPS_PCourse **crs, + GPS_PCourse_Lap **clp, + GPS_PTrack **trk, + GPS_PCourse_Point **cpt, + int32 *n_clp, + int32 *n_trk, + int32 *n_cpt, + pcb_fn cb) { - int32 ret=0; - - if(gps_course_transfer == -1) - return GPS_UNSUPPORTED; - - switch(gps_course_transfer) - { - case pA1006: - ret = GPS_A1006_Get(port,crs,cb); - break; - default: - GPS_Error("Get_Course: Unknown course protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_lap_transfer) - { - case pA1007: - *n_clp = GPS_A1007_Get(port,clp, 0); - break; - default: - GPS_Error("Get_Course: Unknown course lap protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_trk_transfer) - { - case pA1012: - GPS_Error("Get_Course: Not implemented track protocol %d\n", - gps_trk_transfer); - break; - case pA302: - *n_trk = GPS_A301_Get(port,trk,cb,302); - break; - default: - GPS_Error("Get_Course: Unknown course track protocol %d\n", - gps_trk_transfer); - return PROTOCOL_ERROR; - } - - switch(gps_course_point_transfer) - { - case pA1008: - *n_cpt = GPS_A1008_Get(port,cpt, 0); - break; - default: - GPS_Error("Get_Course: Unknown course point protocol"); - return PROTOCOL_ERROR; - } - - return ret; + int32 ret=0; + + if (gps_course_transfer == -1) { + return GPS_UNSUPPORTED; + } + + switch (gps_course_transfer) { + case pA1006: + ret = GPS_A1006_Get(port,crs,cb); + break; + default: + GPS_Error("Get_Course: Unknown course protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_lap_transfer) { + case pA1007: + *n_clp = GPS_A1007_Get(port,clp, 0); + break; + default: + GPS_Error("Get_Course: Unknown course lap protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_trk_transfer) { + case pA1012: + GPS_Error("Get_Course: Not implemented track protocol %d\n", + gps_trk_transfer); + break; + case pA302: + *n_trk = GPS_A301_Get(port,trk,cb,302); + break; + default: + GPS_Error("Get_Course: Unknown course track protocol %d\n", + gps_trk_transfer); + return PROTOCOL_ERROR; + } + + switch (gps_course_point_transfer) { + case pA1008: + *n_cpt = GPS_A1008_Get(port,cpt, 0); + break; + default: + GPS_Error("Get_Course: Unknown course point protocol"); + return PROTOCOL_ERROR; + } + + return ret; } @@ -782,113 +775,110 @@ int32 GPS_Command_Get_Course ** @return [int32] Success ************************************************************************/ int32 GPS_Command_Send_Course - (const char *port, - GPS_PCourse *crs, - GPS_PCourse_Lap *clp, - GPS_PTrack *trk, - GPS_PCourse_Point *cpt, - int32 n_crs, - int32 n_clp, - int32 n_trk, - int32 n_cpt) +(const char *port, + GPS_PCourse *crs, + GPS_PCourse_Lap *clp, + GPS_PTrack *trk, + GPS_PCourse_Point *cpt, + int32 n_crs, + int32 n_clp, + int32 n_trk, + int32 n_cpt) { - gpsdevh *fd; - GPS_OCourse_Limits limits; - int32 ret; - int32 ret_crs=0; - int32 ret_clp=0; - int32 ret_trk=0; - int32 ret_cpt=0; - - if(gps_course_transfer == -1 || gps_course_limits_transfer == -1) - return GPS_UNSUPPORTED; - - /* Check course limits to make sure we're not exceeding the device's - * capacity. - */ - switch(gps_course_limits_transfer) - { - case pA1009: - ret = GPS_A1009_Get(port,&limits); - break; - default: - GPS_Error("Send_Course: Unknown course limitsprotocol"); - return PROTOCOL_ERROR; - } - - if (n_crs > limits.max_courses - || n_clp > limits.max_course_laps - || n_trk > limits.max_course_trk_pnt - || n_cpt > limits.max_course_pnt) - { - GPS_Error("Course upload would exceed device capacity:"); - GPS_Error("# of courses: %d, max: %d", n_crs, limits.max_courses); - GPS_Error("# of laps: %d, max: %d", n_clp, limits.max_course_laps); - GPS_Error("# of track points: %d, max: %d", n_trk, limits.max_course_trk_pnt); - GPS_Error("# of course points: %d, max: %d", n_cpt, limits.max_course_pnt); - return GPS_UNSUPPORTED; - } - - /* Initialize device communication: - * In contrast to other transfer protocols, this has to be handled here; - * shutting off communication in between the different parts - * could lead to data corruption on the device because all the courses - * and their associated lap and track data have to be sent in one - * transaction. - */ - if(!GPS_Device_On(port,&fd)) - return gps_errno; - - switch(gps_course_transfer) - { - case pA1006: - ret_crs = GPS_A1006_Send(port,crs,n_crs,fd); - break; - default: - GPS_Error("Send_Course: Unknown course protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_lap_transfer) - { - case pA1007: - ret_clp = GPS_A1007_Send(port,clp,n_clp,fd); - break; - default: - GPS_Error("Send_Course: Unknown course lap protocol"); - return PROTOCOL_ERROR; - } - - switch(gps_course_trk_transfer) - { - case pA1012: - GPS_Error("Send_Course: Not implemented track protocol %d\n", - gps_trk_transfer); - break; - case pA302: - ret_trk = GPS_A301_Send(port,trk,n_trk,302,fd); - break; - default: - GPS_Error("Send_Course: Unknown course track protocol %d\n", - gps_trk_transfer); - return PROTOCOL_ERROR; - } - - switch(gps_course_point_transfer) - { - case pA1008: - ret_cpt = GPS_A1008_Send(port,cpt,n_cpt,fd); - break; - default: - GPS_Error("Send_Course: Unknown course point protocol"); - return PROTOCOL_ERROR; - } - - if(!GPS_Device_Off(fd)) - return gps_errno; - - - return ret_crs * ret_clp * ret_trk * ret_cpt; + gpsdevh *fd; + GPS_OCourse_Limits limits; + int32 ret; + int32 ret_crs=0; + int32 ret_clp=0; + int32 ret_trk=0; + int32 ret_cpt=0; + + if (gps_course_transfer == -1 || gps_course_limits_transfer == -1) { + return GPS_UNSUPPORTED; + } + + /* Check course limits to make sure we're not exceeding the device's + * capacity. + */ + switch (gps_course_limits_transfer) { + case pA1009: + ret = GPS_A1009_Get(port,&limits); + break; + default: + GPS_Error("Send_Course: Unknown course limitsprotocol"); + return PROTOCOL_ERROR; + } + + if (n_crs > limits.max_courses + || n_clp > limits.max_course_laps + || n_trk > limits.max_course_trk_pnt + || n_cpt > limits.max_course_pnt) { + GPS_Error("Course upload would exceed device capacity:"); + GPS_Error("# of courses: %d, max: %d", n_crs, limits.max_courses); + GPS_Error("# of laps: %d, max: %d", n_clp, limits.max_course_laps); + GPS_Error("# of track points: %d, max: %d", n_trk, limits.max_course_trk_pnt); + GPS_Error("# of course points: %d, max: %d", n_cpt, limits.max_course_pnt); + return GPS_UNSUPPORTED; + } + + /* Initialize device communication: + * In contrast to other transfer protocols, this has to be handled here; + * shutting off communication in between the different parts + * could lead to data corruption on the device because all the courses + * and their associated lap and track data have to be sent in one + * transaction. + */ + if (!GPS_Device_On(port,&fd)) { + return gps_errno; + } + + switch (gps_course_transfer) { + case pA1006: + ret_crs = GPS_A1006_Send(port,crs,n_crs,fd); + break; + default: + GPS_Error("Send_Course: Unknown course protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_lap_transfer) { + case pA1007: + ret_clp = GPS_A1007_Send(port,clp,n_clp,fd); + break; + default: + GPS_Error("Send_Course: Unknown course lap protocol"); + return PROTOCOL_ERROR; + } + + switch (gps_course_trk_transfer) { + case pA1012: + GPS_Error("Send_Course: Not implemented track protocol %d\n", + gps_trk_transfer); + break; + case pA302: + ret_trk = GPS_A301_Send(port,trk,n_trk,302,fd); + break; + default: + GPS_Error("Send_Course: Unknown course track protocol %d\n", + gps_trk_transfer); + return PROTOCOL_ERROR; + } + + switch (gps_course_point_transfer) { + case pA1008: + ret_cpt = GPS_A1008_Send(port,cpt,n_cpt,fd); + break; + default: + GPS_Error("Send_Course: Unknown course point protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Device_Off(fd)) { + return gps_errno; + } + + + return ret_crs * ret_clp * ret_trk * ret_cpt; } @@ -903,17 +893,18 @@ int32 GPS_Command_Send_Course ************************************************************************/ static uint32 Unique_Course_Index(GPS_PCourse *crs, int n_crs) { - uint32 idx; - int i; - - for (idx=0; ; idx++) - { - for (i=0; iindex==idx) - break; /* Already have this index */ - if (i>=n_crs) - return idx; /* Found unused index */ + uint32 idx; + int i; + + for (idx=0; ; idx++) { + for (i=0; iindex==idx) { + break; /* Already have this index */ + } + if (i>=n_crs) { + return idx; /* Found unused index */ } + } } @@ -929,17 +920,18 @@ static uint32 Unique_Course_Index(GPS_PCourse *crs, int n_crs) ************************************************************************/ static uint32 Unique_Track_Index(GPS_PCourse *crs, int n_crs) { - uint32 idx; - int i; - - for (idx=0; ; idx++) - { - for (i=0; itrack_index==idx) - break; /* Already have this index */ - if (i>=n_crs) - return idx; /* Found unused index */ + uint32 idx; + int i; + + for (idx=0; ; idx++) { + for (i=0; itrack_index==idx) { + break; /* Already have this index */ + } + if (i>=n_crs) { + return idx; /* Found unused index */ } + } } @@ -962,73 +954,72 @@ static void Calculate_Course_Lap_Data(GPS_PCourse_Lap clp, GPS_PTrack *ctk, int ctk_start, int ctk_end) { - int i; - double heartrate_sum = 0, cadence_sum = 0; - int heartrate_sum_time = 0, cadence_sum_time = 0; - double time_synth_speed = 10.0 * 1000 / 3600; /* speed in m/s */ - - if (ctk_start && ctk_end && !ctk[ctk_start]->Time) - ctk[ctk_start]->Time = GPS_Time_Now(); - else - time_synth_speed = 0; - - clp->total_dist = 0; - clp->avg_heart_rate = 0; - clp->max_heart_rate = 0; - clp->intensity = 0; - clp->avg_cadence = 0xff; - for (i=ctk_start; i <= ctk_end; i++) - { - if (ctk[i]->heartrate && ctk[i]->heartrate > clp->max_heart_rate) - clp->max_heart_rate = ctk[i]->heartrate; - if (i < ctk_end) - { - double dist = 0; - int seg_time; - - if (!ctk[i]->no_latlon && !ctk[i+1]->no_latlon) - dist = gcgeodist(ctk[i]->lat, ctk[i]->lon, - ctk[i+1]->lat, ctk[i+1]->lon); - clp->total_dist += dist; - - if (time_synth_speed) - ctk[i+1]->Time = ctk[i]->Time + (dist / time_synth_speed + 0.5); - - seg_time = ctk[i+1]->Time - ctk[i]->Time; - - if (ctk[i]->heartrate) - { - heartrate_sum += ctk[i]->heartrate * seg_time; - heartrate_sum_time += seg_time; - } - if (ctk[i]->cadence) - { - cadence_sum += ctk[i]->cadence * seg_time; - cadence_sum_time += seg_time; - } - } + int i; + double heartrate_sum = 0, cadence_sum = 0; + int heartrate_sum_time = 0, cadence_sum_time = 0; + double time_synth_speed = 10.0 * 1000 / 3600; /* speed in m/s */ + + if (ctk_start && ctk_end && !ctk[ctk_start]->Time) { + ctk[ctk_start]->Time = GPS_Time_Now(); + } else { + time_synth_speed = 0; + } + + clp->total_dist = 0; + clp->avg_heart_rate = 0; + clp->max_heart_rate = 0; + clp->intensity = 0; + clp->avg_cadence = 0xff; + for (i=ctk_start; i <= ctk_end; i++) { + if (ctk[i]->heartrate && ctk[i]->heartrate > clp->max_heart_rate) { + clp->max_heart_rate = ctk[i]->heartrate; } - - clp->total_time = 0; - clp->begin_lat = 0x7fffffff; - clp->begin_lon = 0x7fffffff; - clp->end_lat = 0x7fffffff; - clp->end_lon = 0x7fffffff; - if (ctk_start && ctk_end) - { - clp->total_time = (ctk[ctk_end]->Time - ctk[ctk_start]->Time) * 100; - if (!ctk[ctk_start]->no_latlon && !ctk[ctk_end]->no_latlon) - { - clp->begin_lat = ctk[ctk_start]->lat; - clp->begin_lon = ctk[ctk_start]->lon; - clp->end_lat = ctk[ctk_end]->lat; - clp->end_lon = ctk[ctk_end]->lon; - } + if (i < ctk_end) { + double dist = 0; + int seg_time; + + if (!ctk[i]->no_latlon && !ctk[i+1]->no_latlon) + dist = gcgeodist(ctk[i]->lat, ctk[i]->lon, + ctk[i+1]->lat, ctk[i+1]->lon); + clp->total_dist += dist; + + if (time_synth_speed) { + ctk[i+1]->Time = ctk[i]->Time + (dist / time_synth_speed + 0.5); + } + + seg_time = ctk[i+1]->Time - ctk[i]->Time; + + if (ctk[i]->heartrate) { + heartrate_sum += ctk[i]->heartrate * seg_time; + heartrate_sum_time += seg_time; + } + if (ctk[i]->cadence) { + cadence_sum += ctk[i]->cadence * seg_time; + cadence_sum_time += seg_time; + } + } + } + + clp->total_time = 0; + clp->begin_lat = 0x7fffffff; + clp->begin_lon = 0x7fffffff; + clp->end_lat = 0x7fffffff; + clp->end_lon = 0x7fffffff; + if (ctk_start && ctk_end) { + clp->total_time = (ctk[ctk_end]->Time - ctk[ctk_start]->Time) * 100; + if (!ctk[ctk_start]->no_latlon && !ctk[ctk_end]->no_latlon) { + clp->begin_lat = ctk[ctk_start]->lat; + clp->begin_lon = ctk[ctk_start]->lon; + clp->end_lat = ctk[ctk_end]->lat; + clp->end_lon = ctk[ctk_end]->lon; } - if (heartrate_sum_time) - clp->avg_heart_rate = heartrate_sum / heartrate_sum_time; - if (cadence_sum_time) - clp->avg_cadence = cadence_sum / cadence_sum_time; + } + if (heartrate_sum_time) { + clp->avg_heart_rate = heartrate_sum / heartrate_sum_time; + } + if (cadence_sum_time) { + clp->avg_cadence = cadence_sum / cadence_sum_time; + } } @@ -1054,100 +1045,97 @@ Course_Garbage_Collect(GPS_PCourse *crs, int *n_crs, GPS_PTrack *ctk, int *n_ctk, GPS_PCourse_Point *cpt, int *n_cpt) { - int i, j; - - /* Remove courses with duplicate names, keeping newest. - * This is actually pretty important: Sending two courses with the same - * name to the device will result in internal data corruption on the - * device (e.g. "inventing" laps with weird course IDs that nobody ever - * transferred to it, that change with every upload of unrelated data - * and that can't be deleted except with a master reset by holding the - * Mode button during power on). - */ + int i, j; + + /* Remove courses with duplicate names, keeping newest. + * This is actually pretty important: Sending two courses with the same + * name to the device will result in internal data corruption on the + * device (e.g. "inventing" laps with weird course IDs that nobody ever + * transferred to it, that change with every upload of unrelated data + * and that can't be deleted except with a master reset by holding the + * Mode button during power on). + */ restart_courses: - for (i=*n_crs-1; i>0; i--) - { - for (j=i-1; j>=0; j--) - { - if (!strcmp(crs[i]->course_name, crs[j]->course_name)) - { - /* Remove course */ - GPS_Course_Del(&crs[j]); - memmove(&crs[j], &crs[j+1], (*n_crs-j-1)*sizeof(*crs)); - (*n_crs)--; - goto restart_courses; - } - } + for (i=*n_crs-1; i>0; i--) { + for (j=i-1; j>=0; j--) { + if (!strcmp(crs[i]->course_name, crs[j]->course_name)) { + /* Remove course */ + GPS_Course_Del(&crs[j]); + memmove(&crs[j], &crs[j+1], (*n_crs-j-1)*sizeof(*crs)); + (*n_crs)--; + goto restart_courses; + } } + } /* Remove unreferenced laps */ restart_laps: - for (i=0; i<*n_clp; i++) - { - for (j=0; j<*n_crs; j++) - if (crs[j]->index == clp[i]->course_index) - break; - if (j>=*n_crs) - { - /* Remove lap */ - GPS_Course_Lap_Del(&clp[i]); - memmove(&clp[i], &clp[i+1], (*n_clp-i-1)*sizeof(*clp)); - (*n_clp)--; - goto restart_laps; - } + for (i=0; i<*n_clp; i++) { + for (j=0; j<*n_crs; j++) + if (crs[j]->index == clp[i]->course_index) { + break; + } + if (j>=*n_crs) { + /* Remove lap */ + GPS_Course_Lap_Del(&clp[i]); + memmove(&clp[i], &clp[i+1], (*n_clp-i-1)*sizeof(*clp)); + (*n_clp)--; + goto restart_laps; } + } - /* Remove unreferenced tracks */ + /* Remove unreferenced tracks */ restart_tracks: - for (i=0; i<*n_ctk; i++) - { - uint32 trk_idx; - - if (!ctk[i]->ishdr) - continue; - trk_idx = strtoul(ctk[i]->trk_ident, NULL, 0); - for (j=0; j<*n_crs; j++) - if (crs[j]->track_index == trk_idx) - break; - if (j>=*n_crs) - { - /* Remove track */ - for (j=i; j<*n_ctk; j++) - { - if (j!=i && ctk[j]->ishdr) - break; - GPS_Track_Del(&ctk[j]); - } - memmove(&ctk[i], &ctk[j], (*n_ctk-j)*sizeof(*ctk)); - *(n_ctk) -= j-i; - goto restart_tracks; + for (i=0; i<*n_ctk; i++) { + uint32 trk_idx; + + if (!ctk[i]->ishdr) { + continue; + } + trk_idx = strtoul(ctk[i]->trk_ident, NULL, 0); + for (j=0; j<*n_crs; j++) + if (crs[j]->track_index == trk_idx) { + break; + } + if (j>=*n_crs) { + /* Remove track */ + for (j=i; j<*n_ctk; j++) { + if (j!=i && ctk[j]->ishdr) { + break; } + GPS_Track_Del(&ctk[j]); + } + memmove(&ctk[i], &ctk[j], (*n_ctk-j)*sizeof(*ctk)); + *(n_ctk) -= j-i; + goto restart_tracks; } + } - /* Remove unreferenced/duplicate course points */ + /* Remove unreferenced/duplicate course points */ restart_course_points: - for (i=0; i<*n_cpt; i++) - { - /* Check for unreferenced point */ - for (j=0; j<*n_crs; j++) - if (crs[j]->index == cpt[i]->course_index) - break; - if (j<*n_crs) - { - /* Check for duplicate point */ - for (j=0; jcourse_index == cpt[j]->course_index && - cpt[i]->track_point_time == cpt[j]->track_point_time) - break; - if (j>=i) - continue; /* Referenced & unique */ + for (i=0; i<*n_cpt; i++) { + /* Check for unreferenced point */ + for (j=0; j<*n_crs; j++) + if (crs[j]->index == cpt[i]->course_index) { + break; + } + if (j<*n_crs) { + /* Check for duplicate point */ + for (j=0; jcourse_index == cpt[j]->course_index && + cpt[i]->track_point_time == cpt[j]->track_point_time) { + break; } - /* Remove course point */ - GPS_Course_Point_Del(&cpt[i]); - memmove(&cpt[i], &cpt[i+1], (*n_cpt-i-1)*sizeof(*cpt)); - (*n_cpt)--; - goto restart_course_points; + if (j>=i) { + continue; /* Referenced & unique */ + } } + /* Remove course point */ + GPS_Course_Point_Del(&cpt[i]); + memmove(&cpt[i], &cpt[i+1], (*n_cpt-i-1)*sizeof(*cpt)); + (*n_cpt)--; + goto restart_course_points; + } } @@ -1170,165 +1158,174 @@ restart_course_points: int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 n_trk, GPS_PWay *wpt, int32 n_wpt, int eraset) { - GPS_PCourse *crs = NULL; - GPS_PCourse_Lap *clp = NULL; - GPS_PTrack *ctk = NULL; - GPS_PCourse_Point *cpt = NULL; - int n_crs, n_clp=0, n_ctk=0, n_cpt=0; - int i, j, trk_end, new_crs, first_new_ctk; - int32 ret; - - /* Read existing courses from device */ - if (eraset) - n_crs = 0; - else { - n_crs = GPS_Command_Get_Course(port, &crs, &clp, &ctk, &cpt, &n_clp, &n_ctk, &n_cpt, NULL); - if (n_crs < 0) return n_crs; + GPS_PCourse *crs = NULL; + GPS_PCourse_Lap *clp = NULL; + GPS_PTrack *ctk = NULL; + GPS_PCourse_Point *cpt = NULL; + int n_crs, n_clp=0, n_ctk=0, n_cpt=0; + int i, j, trk_end, new_crs, first_new_ctk; + int32 ret; + + /* Read existing courses from device */ + if (eraset) { + n_crs = 0; + } else { + n_crs = GPS_Command_Get_Course(port, &crs, &clp, &ctk, &cpt, &n_clp, &n_ctk, &n_cpt, NULL); + if (n_crs < 0) { + return n_crs; } + } - /* Create new course+lap+track points for each track */ - new_crs = n_crs; - for (i=0;iishdr) - continue; - - /* Find end of track */ - for (trk_end=i; trk_endishdr) - break; - if (trk_end==i) - continue; /* Skip empty track */ - - /* Create & append course */ - crs = xrealloc(crs, (n_crs+1) * sizeof(GPS_PCourse)); - crs[n_crs] = GPS_Course_New(); - if (!crs[n_crs]) return MEMORY_ERROR; - - crs[n_crs]->index = Unique_Course_Index(crs, n_crs); - strncpy(crs[n_crs]->course_name, trk[i]->trk_ident, - sizeof(crs[n_crs]->course_name)-1); - - crs[n_crs]->track_index = Unique_Track_Index(crs, n_crs); - - /* Create & append new lap */ - clp = xrealloc(clp, (n_clp+1) * sizeof(GPS_PCourse_Lap)); - clp[n_clp] = GPS_Course_Lap_New(); - if (!clp[n_clp]) return MEMORY_ERROR; - - clp[n_clp]->course_index = crs[n_crs]->index; /* Index of associated course */ - clp[n_clp]->lap_index = 0; /* Lap index, unique per course */ - Calculate_Course_Lap_Data(clp[n_clp], trk, i+1, trk_end); - n_crs++; - n_clp++; + /* Create new course+lap+track points for each track */ + new_crs = n_crs; + for (i=0; iishdr) { + continue; } - /* Append new track points */ - ctk = xrealloc(ctk, (n_ctk+n_trk) * sizeof(GPS_PTrack)); - first_new_ctk = n_ctk; - for (i=0;iishdr && (i>=n_trk || trk[i+1]->ishdr)) - continue; - - ctk[n_ctk] = GPS_Track_New(); - if (!ctk[n_ctk]) return MEMORY_ERROR; - *ctk[n_ctk] = *trk[i]; - - if (trk[i]->ishdr) - { - /* Index of new track, must match the track index in associated course */ - memset(ctk[n_ctk]->trk_ident, 0, sizeof(ctk[n_ctk]->trk_ident)); - sprintf(ctk[n_ctk]->trk_ident, "%d", crs[new_crs]->track_index); - new_crs++; - } - n_ctk++; + /* Find end of track */ + for (trk_end=i; trk_endishdr) { + break; + } + if (trk_end==i) { + continue; /* Skip empty track */ } - /* Convert waypoints to course points by searching closest track point & - * append - */ - cpt = xrealloc(cpt, (n_cpt+n_wpt) * sizeof(GPS_PCourse_Point)); - for (i=0; iishdr) { - trk_idx = strtoul(ctk[j]->trk_ident, NULL, 0); - continue; - } - - dist = gcgeodist(wpt[i]->lat, wpt[i]->lon, ctk[j]->lat, ctk[j]->lon); - if (dist < min_dist) { - min_dist = dist; - min_dist_idx = j; - min_dist_trk_idx = trk_idx; - } - } - - cpt[i+n_cpt] = GPS_Course_Point_New(); - strncpy(cpt[i+n_cpt]->name, wpt[i]->cmnt, - sizeof(cpt[i+n_cpt]->name) - 1); - for (j=0; jtrack_index == min_dist_trk_idx) - { - cpt[i+n_cpt]->course_index = crs[j]->index; - break; - } - cpt[i+n_cpt]->track_point_time = ctk[min_dist_idx]->Time; - cpt[i+n_cpt]->point_type = 0; + /* Create & append course */ + crs = xrealloc(crs, (n_crs+1) * sizeof(GPS_PCourse)); + crs[n_crs] = GPS_Course_New(); + if (!crs[n_crs]) { + return MEMORY_ERROR; } - n_cpt += n_wpt; - /* Remove course data that's no longer needed */ - Course_Garbage_Collect(crs, &n_crs, clp, &n_clp, ctk, &n_ctk, cpt, &n_cpt); + crs[n_crs]->index = Unique_Course_Index(crs, n_crs); + strncpy(crs[n_crs]->course_name, trk[i]->trk_ident, + sizeof(crs[n_crs]->course_name)-1); - /* Finally send courses including new ones to device */ - ret = GPS_Command_Send_Course(port, crs, clp, ctk, cpt, - n_crs, n_clp, n_ctk, n_cpt); + crs[n_crs]->track_index = Unique_Track_Index(crs, n_crs); - for (i=0;icourse_index = crs[n_crs]->index; /* Index of associated course */ + clp[n_clp]->lap_index = 0; /* Lap index, unique per course */ + Calculate_Course_Lap_Data(clp[n_clp], trk, i+1, trk_end); + n_crs++; + n_clp++; + } + + /* Append new track points */ + ctk = xrealloc(ctk, (n_ctk+n_trk) * sizeof(GPS_PTrack)); + first_new_ctk = n_ctk; + for (i=0; iishdr && (i>=n_trk || trk[i+1]->ishdr)) { + continue; } - free(clp); - for (i=0;iishdr) { + /* Index of new track, must match the track index in associated course */ + memset(ctk[n_ctk]->trk_ident, 0, sizeof(ctk[n_ctk]->trk_ident)); + sprintf(ctk[n_ctk]->trk_ident, "%d", crs[new_crs]->track_index); + new_crs++; + } + n_ctk++; + } + + /* Convert waypoints to course points by searching closest track point & + * append + */ + cpt = xrealloc(cpt, (n_cpt+n_wpt) * sizeof(GPS_PCourse_Point)); + for (i=0; iishdr) { + trk_idx = strtoul(ctk[j]->trk_ident, NULL, 0); + continue; + } + + dist = gcgeodist(wpt[i]->lat, wpt[i]->lon, ctk[j]->lat, ctk[j]->lon); + if (dist < min_dist) { + min_dist = dist; + min_dist_idx = j; + min_dist_trk_idx = trk_idx; + } } - free(cpt); - return ret; + cpt[i+n_cpt] = GPS_Course_Point_New(); + strncpy(cpt[i+n_cpt]->name, wpt[i]->cmnt, + sizeof(cpt[i+n_cpt]->name) - 1); + for (j=0; jtrack_index == min_dist_trk_idx) { + cpt[i+n_cpt]->course_index = crs[j]->index; + break; + } + cpt[i+n_cpt]->track_point_time = ctk[min_dist_idx]->Time; + cpt[i+n_cpt]->point_type = 0; + } + n_cpt += n_wpt; + + /* Remove course data that's no longer needed */ + Course_Garbage_Collect(crs, &n_crs, clp, &n_clp, ctk, &n_ctk, cpt, &n_cpt); + + /* Finally send courses including new ones to device */ + ret = GPS_Command_Send_Course(port, crs, clp, ctk, cpt, + n_crs, n_clp, n_ctk, n_cpt); + + for (i=0; i -int32 GPS_Command_Off(const char *port); + int32 GPS_Command_Off(const char *port); -time_t GPS_Command_Get_Time(const char *port); -int32 GPS_Command_Send_Time(const char *port, time_t Time); + time_t GPS_Command_Get_Time(const char *port); + int32 GPS_Command_Send_Time(const char *port, time_t Time); -int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon); -int32 GPS_Command_Send_Position(const char *port, double lat, double lon); + int32 GPS_Command_Get_Position(const char *port, double *lat, double *lon); + int32 GPS_Command_Send_Position(const char *port, double lat, double lon); -int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd); -int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd); -int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt); + int32 GPS_Command_Pvt_On(const char *port, gpsdevh **fd); + int32 GPS_Command_Pvt_Off(const char *port, gpsdevh **fd); + int32 GPS_Command_Pvt_Get(gpsdevh **fd, GPS_PPvt_Data *pvt); -int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm); -int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n); + int32 GPS_Command_Get_Almanac(const char *port, GPS_PAlmanac **alm); + int32 GPS_Command_Send_Almanac(const char *port, GPS_PAlmanac *alm, int32 n); -int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int eraset); + int32 GPS_Command_Get_Track(const char *port, GPS_PTrack **trk, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Send_Track(const char *port, GPS_PTrack *trk, int32 n, int eraset); -int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)); + int32 GPS_Command_Get_Waypoint(const char *port, GPS_PWay **way,int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Send_Waypoint(const char *port, GPS_PWay *way, int32 n, int (*cb)(struct GPS_SWay **)); -int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way); -int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n); + int32 GPS_Command_Get_Proximity(const char *port, GPS_PWay **way); + int32 GPS_Command_Send_Proximity(const char *port, GPS_PWay *way, int32 n); -int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way); -int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n); + int32 GPS_Command_Get_Route(const char *port, GPS_PWay **way); + int32 GPS_Command_Send_Route(const char *port, GPS_PWay *way, int32 n); -int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Lap(const char *port, GPS_PLap **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Send_Course(const char *port, GPS_PCourse *crs, GPS_PCourse_Lap *clp, - GPS_PTrack *trk, GPS_PCourse_Point *cpt, - int32 n_crs, int32 n_clp, int32 n_trk, int32 n_cpt); -int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 n_trk, - GPS_PWay *wpt, int32 n_wpt, int eraset); + int32 GPS_Command_Send_Course(const char *port, GPS_PCourse *crs, GPS_PCourse_Lap *clp, + GPS_PTrack *trk, GPS_PCourse_Point *cpt, + int32 n_crs, int32 n_clp, int32 n_trk, int32 n_cpt); + int32 GPS_Command_Send_Track_As_Course(const char *port, GPS_PTrack *trk, int32 n_trk, + GPS_PWay *wpt, int32 n_wpt, int eraset); -int32 GPS_Command_Get_Workout(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Fitness_User_Profile(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Workout_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); -int32 GPS_Command_Get_Course_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Workout(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Fitness_User_Profile(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Workout_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); + int32 GPS_Command_Get_Course_Limits(const char *port, void **lap, int (*cb)(int, struct GPS_SWay **)); #endif #ifdef __cplusplus diff --git a/gpsbabel/jeeps/gpsdatum.h b/gpsbabel/jeeps/gpsdatum.h index b0e1bf696..34a54f15e 100644 --- a/gpsbabel/jeeps/gpsdatum.h +++ b/gpsbabel/jeeps/gpsdatum.h @@ -8,15 +8,13 @@ extern "C" -typedef struct GPS_SEllipse -{ + typedef struct GPS_SEllipse { char *name; double a; double invf; -} GPS_OEllipse, *GPS_PEllipse; + } GPS_OEllipse, *GPS_PEllipse; -GPS_OEllipse GPS_Ellipse[]= -{ + GPS_OEllipse GPS_Ellipse[]= { { "Airy 1830", 6377563.396, 299.3249646 }, { "Airy 1830 Modified", 6377340.189, 299.3249646 }, { "Australian National", 6378160.000, 298.25 }, @@ -45,159 +43,155 @@ GPS_OEllipse GPS_Ellipse[]= { "WGS72", 6378135.000, 298.26 }, { "WGS84", 6378137.000, 298.257223563 }, { "Clarke 1880 (Benoit)", 6378300.789, 293.466 }, -}; + }; -typedef struct GPS_SDatum -{ + typedef struct GPS_SDatum { char *name; int ellipse; double dx; double dy; double dz; -} GPS_ODatum, *GPS_PDatum; - -GPS_ODatum GPS_Datum[]= -{ -/* 000 */ { "Adindan", 6, -166, -15, 204 }, -/* 001 */ { "AFG", 18, -43, -163, 45 }, -/* 002 */ { "Ain-El-Abd", 17, -150, -251, -2 }, -/* 003 */ { "Alaska-NAD27", 5, -5, 135, 172 }, -/* 004 */ { "Alaska-Canada", 6, -9, 151, 185 }, -/* 005 */ { "Anna-1-Astro", 2, -491, -22, 435 }, -/* 006 */ { "ARC 1950 Mean", 6, -143, -90, -294 }, -/* 007 */ { "ARC 1960 Mean", 6, -160, -8, -300 }, -/* 008 */ { "Asc Island 58", 17, -207, 107, 52 }, -/* 009 */ { "Astro B4", 17, 114, -116, -333 }, -/* 010 */ { "Astro Beacon E", 17, 145, 75, -272 }, -/* 011 */ { "Astro pos 71/4", 17, -320, 550, -494 }, -/* 012 */ { "Astro stn 52", 17, 124, -234, -25 }, -/* 013 */ { "Australia Geo 1984", 2, -134, -48, 149 }, -/* 014 */ { "Bahamas NAD27", 6, -4, 154, 178 }, -/* 015 */ { "Bellevue IGN", 17, -127, -769, 472 }, -/* 016 */ { "Bermuda 1957", 6, -73, 213, 296 }, -/* 017 */ { "Bukit Rimpah", 4, -384, 664, -48 }, -/* 018 */ { "Camp_Area_Astro", 17, -104, -129, 239 }, -/* 019 */ { "Campo_Inchauspe", 17, -148, 136, 90 }, -/* 020 */ { "Canada_Mean(NAD27)", 5, -10, 158, 187 }, -/* 021 */ { "Canal_Zone_(NAD27)", 5, 0, 125, 201 }, -/* 022 */ { "Canton_Island_1966", 17, 298, -304, -375 }, -/* 023 */ { "Cape", 6, -136, -108, -292 }, -/* 024 */ { "Cape_Canaveral_mean", 5, -2, 150, 181 }, -/* 025 */ { "Carribean NAD27", 5, -7, 152, 178 }, -/* 026 */ { "Carthage", 6, -263, 6, 431 }, -/* 027 */ { "Cent America NAD27", 5 , 0, 125, 194 }, -/* 028 */ { "Chatham 1971", 17, 175, -38, 113 }, -/* 029 */ { "Chua Astro", 17, -134, 229, -29 }, -/* 030 */ { "Corrego Alegre", 17, -206, 172, -6 }, -/* 031 */ { "Cuba NAD27", 5, -9, 152, 178 }, -/* 032 */ { "Cyprus", 17, -104, -101, -140 }, -/* 033 */ { "Djakarta(Batavia)", 4, -377, 681, -50 }, -/* 034 */ { "DOS 1968", 17, 230, -199, -752 }, -/* 035 */ { "Easter lsland 1967", 17, 211, 147, 111 }, -/* 036 */ { "Egypt", 17, -130, -117, -151 }, -/* 037 */ { "European 1950", 17, -87, -96, -120 }, -/* 038 */ { "European 1950 mean", 17, -87, -98, -121 }, -/* 039 */ { "European 1979 mean", 17, -86, -98, -119 }, -/* 040 */ { "Finnish Nautical", 17, -78, -231, -97 }, -/* 041 */ { "Gandajika Base", 17, -133, -321, 50 }, -/* 042 */ { "Geodetic Datum 49", 17, 84, -22, 209 }, -/* 043 */ { "Ghana", 26, 0, 0, 0 }, -/* 044 */ { "Greenland NAD27", 5, 11, 114, 195 }, -/* 045 */ { "Guam 1963", 5, -100, -248, 259 }, -/* 046 */ { "Gunung Segara", 4, -403, 684, 41 }, -/* 047 */ { "Gunung Serindung 1962", 26, 0, 0, 0 }, -/* 048 */ { "GUX1 Astro", 17, 252, -209, -751 }, -/* 049 */ { "Herat North", 17, -333, -222, 114 }, -/* 050 */ { "Hjorsey 1955", 17, -73, 46, 86 }, -/* 051 */ { "Hong Kong 1963", 17, -156, -271, -189 }, -/* 052 */ { "Hu-Tzu-Shan", 17, -634, -549, -201 }, -/* 053 */ { "Indian", 9, 289, 734, 257 }, -/* 054 */ { "Iran", 17, -117, -132, -164 }, -/* 055 */ { "Ireland 1965", 1, 506, -122, 611 }, -/* 056 */ { "ISTS 073 Astro 69", 17, 208, -435, -229 }, -/* 057 */ { "Johnston Island 61", 17, 191, -77, -204 }, -/* 058 */ { "Kandawala", 7, -97, 787, 86 }, -/* 059 */ { "Kerguelen Island", 17, 145, -187, 103 }, -/* 060 */ { "Kertau 48", 11, -11, 851, 5 }, -/* 061 */ { "L.C. 5 Astro", 5, 42, 124, 147 }, -/* 062 */ { "La Reunion", 17, 94, -948, -1262 }, -/* 063 */ { "Liberia 1964", 6, -90, 40, 88 }, -/* 064 */ { "Luzon", 5, -133, -77, -51 }, -/* 065 */ { "Mahe 1971", 6, 41, -220, -134 }, -/* 066 */ { "Marco Astro", 17, -289, -124, 60 }, -/* 067 */ { "Masirah Is. Nahrwan", 6, -247, -148, 369 }, -/* 068 */ { "Massawa", 4, 639, 405, 60 }, -/* 069 */ { "Merchich", 6, 31, 146, 47 }, -/* 070 */ { "Mexico NAD27", 5, -12, 130, 190 }, -/* 071 */ { "Midway Astro 61", 17, 912, -58, 1227 }, -/* 072 */ { "Mindanao", 5, -133, -79, -72 }, -/* 073 */ { "Minna", 6, -92, -93, 122 }, -/* 074 */ { "Montjong Lowe", 26, 0, 0, 0 }, -/* 075 */ { "Nahrwan", 6, -231, -196, 482 }, -/* 076 */ { "Naparima BWI", 17, -2, 374, 172 }, -/* 077 */ { "North America 83", 21, 0, 0, 0 }, -/* 078 */ { "N. America 1927 mean", 5, -8, 160, 176 }, -/* 079 */ { "Observatorio 1966", 17, -425, -169, 81 }, -/* 080 */ { "Old Egyptian", 14, -130, 110, -13 }, -/* 081 */ { "Old Hawaiian_mean", 5, 89, -279, -183 }, -/* 082 */ { "Old Hawaiian Kauai", 5, 45, -290, -172 }, -/* 083 */ { "Old Hawaiian Maui", 5, 65, -290, -190 }, -/* 084 */ { "Old Hawaiian Oahu", 5, 56, -284, -181 }, -/* 085 */ { "Oman", 6, -346, -1, 224 }, -/* 086 */ { "OSGB36", 0, 375, -111, 431 }, -/* 087 */ { "Pico De Las Nieves", 17, -307, -92, 127 }, -/* 088 */ { "Pitcairn Astro 67", 17, 185, 165, 42 }, -/* 089 */ { "S. Am. 1956 mean(P)", 17, -288, 175, -376 }, -/* 090 */ { "S. Chilean 1963 (P)", 17, 16, 196, 93 }, -/* 091 */ { "Puerto Rico", 5, 11, 72, -101 }, -/* 092 */ { "Pulkovo 1942", 18, 28, -130, -95 }, -/* 093 */ { "Qornoq", 17, 164, 138, -189 }, -/* 094 */ { "Quatar National", 17, -128, -283, 22 }, -/* 095 */ { "Rome 1940", 17, -225, -65, 9 }, -/* 096 */ { "S-42(Pulkovo1942)", 18, 28, -121, -77 }, -/* 097 */ { "S.E.Asia_(Indian)", 7, 173, 750, 264 }, -/* 098 */ { "SAD-69/Brazil", 22, -60, -2, -41 }, -/* 099 */ { "Santa Braz", 17, -203, 141, 53 }, -/* 100 */ { "Santo (DOS)", 17, 170, 42, 84 }, -/* 101 */ { "Sapper Hill 43", 17, -355, 16, 74 }, -/* 102 */ { "Schwarzeck", 3, 616, 97, -251 }, -/* 103 */ { "Sicily", 17, -97, -88, -135 }, -/* 104 */ { "Sierra Leone 1960", 26, 0, 0, 0 }, -/* 105 */ { "S. Am. 1969 mean", 22, -57, 1, -41 }, -/* 106 */ { "South Asia", 13, 7, -10, -26 }, -/* 107 */ { "Southeast Base", 17, -499, -249, 314 }, -/* 108 */ { "Southwest Base", 17, -104, 167, -38 }, -/* 109 */ { "Tananarive Obs 25", 17, -189, -242, -91 }, -/* 110 */ { "Thai/Viet (Indian)", 7, 214, 836, 303 }, -/* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, -/* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, -/* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, -/* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, -/* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, -/* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, -/* 117 */ { "WGS 72", 25, 0, 0, 5 }, -/* 118 */ { "WGS 84", 26, 0, 0, 0 }, -/* 119 */ { "Yacare", 17, -155, 171, 37 }, -/* 120 */ { "Zanderij", 17, -265, 120, -358 }, -/* 121 */ { "Sweden", 4, 424.3, -80.5, 613.1 }, -/* 122 */ { "GDA 94", 21, 0, 0, 0 }, -/* 123 */ { "CH-1903", 4, 674, 15, 405 }, -/* 124 */ { "Palestine 1923", 27, -235, -85, 264 }, -/* 125 */ { "ITM (Israeli New)", 21, -48, 55, -52 }, - { NULL, 0, 0, 0, 0 } -}; - - -typedef struct GPS_SDatum_Alias -{ + } GPS_ODatum, *GPS_PDatum; + + GPS_ODatum GPS_Datum[]= { + /* 000 */ { "Adindan", 6, -166, -15, 204 }, + /* 001 */ { "AFG", 18, -43, -163, 45 }, + /* 002 */ { "Ain-El-Abd", 17, -150, -251, -2 }, + /* 003 */ { "Alaska-NAD27", 5, -5, 135, 172 }, + /* 004 */ { "Alaska-Canada", 6, -9, 151, 185 }, + /* 005 */ { "Anna-1-Astro", 2, -491, -22, 435 }, + /* 006 */ { "ARC 1950 Mean", 6, -143, -90, -294 }, + /* 007 */ { "ARC 1960 Mean", 6, -160, -8, -300 }, + /* 008 */ { "Asc Island 58", 17, -207, 107, 52 }, + /* 009 */ { "Astro B4", 17, 114, -116, -333 }, + /* 010 */ { "Astro Beacon E", 17, 145, 75, -272 }, + /* 011 */ { "Astro pos 71/4", 17, -320, 550, -494 }, + /* 012 */ { "Astro stn 52", 17, 124, -234, -25 }, + /* 013 */ { "Australia Geo 1984", 2, -134, -48, 149 }, + /* 014 */ { "Bahamas NAD27", 6, -4, 154, 178 }, + /* 015 */ { "Bellevue IGN", 17, -127, -769, 472 }, + /* 016 */ { "Bermuda 1957", 6, -73, 213, 296 }, + /* 017 */ { "Bukit Rimpah", 4, -384, 664, -48 }, + /* 018 */ { "Camp_Area_Astro", 17, -104, -129, 239 }, + /* 019 */ { "Campo_Inchauspe", 17, -148, 136, 90 }, + /* 020 */ { "Canada_Mean(NAD27)", 5, -10, 158, 187 }, + /* 021 */ { "Canal_Zone_(NAD27)", 5, 0, 125, 201 }, + /* 022 */ { "Canton_Island_1966", 17, 298, -304, -375 }, + /* 023 */ { "Cape", 6, -136, -108, -292 }, + /* 024 */ { "Cape_Canaveral_mean", 5, -2, 150, 181 }, + /* 025 */ { "Carribean NAD27", 5, -7, 152, 178 }, + /* 026 */ { "Carthage", 6, -263, 6, 431 }, + /* 027 */ { "Cent America NAD27", 5 , 0, 125, 194 }, + /* 028 */ { "Chatham 1971", 17, 175, -38, 113 }, + /* 029 */ { "Chua Astro", 17, -134, 229, -29 }, + /* 030 */ { "Corrego Alegre", 17, -206, 172, -6 }, + /* 031 */ { "Cuba NAD27", 5, -9, 152, 178 }, + /* 032 */ { "Cyprus", 17, -104, -101, -140 }, + /* 033 */ { "Djakarta(Batavia)", 4, -377, 681, -50 }, + /* 034 */ { "DOS 1968", 17, 230, -199, -752 }, + /* 035 */ { "Easter lsland 1967", 17, 211, 147, 111 }, + /* 036 */ { "Egypt", 17, -130, -117, -151 }, + /* 037 */ { "European 1950", 17, -87, -96, -120 }, + /* 038 */ { "European 1950 mean", 17, -87, -98, -121 }, + /* 039 */ { "European 1979 mean", 17, -86, -98, -119 }, + /* 040 */ { "Finnish Nautical", 17, -78, -231, -97 }, + /* 041 */ { "Gandajika Base", 17, -133, -321, 50 }, + /* 042 */ { "Geodetic Datum 49", 17, 84, -22, 209 }, + /* 043 */ { "Ghana", 26, 0, 0, 0 }, + /* 044 */ { "Greenland NAD27", 5, 11, 114, 195 }, + /* 045 */ { "Guam 1963", 5, -100, -248, 259 }, + /* 046 */ { "Gunung Segara", 4, -403, 684, 41 }, + /* 047 */ { "Gunung Serindung 1962", 26, 0, 0, 0 }, + /* 048 */ { "GUX1 Astro", 17, 252, -209, -751 }, + /* 049 */ { "Herat North", 17, -333, -222, 114 }, + /* 050 */ { "Hjorsey 1955", 17, -73, 46, 86 }, + /* 051 */ { "Hong Kong 1963", 17, -156, -271, -189 }, + /* 052 */ { "Hu-Tzu-Shan", 17, -634, -549, -201 }, + /* 053 */ { "Indian", 9, 289, 734, 257 }, + /* 054 */ { "Iran", 17, -117, -132, -164 }, + /* 055 */ { "Ireland 1965", 1, 506, -122, 611 }, + /* 056 */ { "ISTS 073 Astro 69", 17, 208, -435, -229 }, + /* 057 */ { "Johnston Island 61", 17, 191, -77, -204 }, + /* 058 */ { "Kandawala", 7, -97, 787, 86 }, + /* 059 */ { "Kerguelen Island", 17, 145, -187, 103 }, + /* 060 */ { "Kertau 48", 11, -11, 851, 5 }, + /* 061 */ { "L.C. 5 Astro", 5, 42, 124, 147 }, + /* 062 */ { "La Reunion", 17, 94, -948, -1262 }, + /* 063 */ { "Liberia 1964", 6, -90, 40, 88 }, + /* 064 */ { "Luzon", 5, -133, -77, -51 }, + /* 065 */ { "Mahe 1971", 6, 41, -220, -134 }, + /* 066 */ { "Marco Astro", 17, -289, -124, 60 }, + /* 067 */ { "Masirah Is. Nahrwan", 6, -247, -148, 369 }, + /* 068 */ { "Massawa", 4, 639, 405, 60 }, + /* 069 */ { "Merchich", 6, 31, 146, 47 }, + /* 070 */ { "Mexico NAD27", 5, -12, 130, 190 }, + /* 071 */ { "Midway Astro 61", 17, 912, -58, 1227 }, + /* 072 */ { "Mindanao", 5, -133, -79, -72 }, + /* 073 */ { "Minna", 6, -92, -93, 122 }, + /* 074 */ { "Montjong Lowe", 26, 0, 0, 0 }, + /* 075 */ { "Nahrwan", 6, -231, -196, 482 }, + /* 076 */ { "Naparima BWI", 17, -2, 374, 172 }, + /* 077 */ { "North America 83", 21, 0, 0, 0 }, + /* 078 */ { "N. America 1927 mean", 5, -8, 160, 176 }, + /* 079 */ { "Observatorio 1966", 17, -425, -169, 81 }, + /* 080 */ { "Old Egyptian", 14, -130, 110, -13 }, + /* 081 */ { "Old Hawaiian_mean", 5, 89, -279, -183 }, + /* 082 */ { "Old Hawaiian Kauai", 5, 45, -290, -172 }, + /* 083 */ { "Old Hawaiian Maui", 5, 65, -290, -190 }, + /* 084 */ { "Old Hawaiian Oahu", 5, 56, -284, -181 }, + /* 085 */ { "Oman", 6, -346, -1, 224 }, + /* 086 */ { "OSGB36", 0, 375, -111, 431 }, + /* 087 */ { "Pico De Las Nieves", 17, -307, -92, 127 }, + /* 088 */ { "Pitcairn Astro 67", 17, 185, 165, 42 }, + /* 089 */ { "S. Am. 1956 mean(P)", 17, -288, 175, -376 }, + /* 090 */ { "S. Chilean 1963 (P)", 17, 16, 196, 93 }, + /* 091 */ { "Puerto Rico", 5, 11, 72, -101 }, + /* 092 */ { "Pulkovo 1942", 18, 28, -130, -95 }, + /* 093 */ { "Qornoq", 17, 164, 138, -189 }, + /* 094 */ { "Quatar National", 17, -128, -283, 22 }, + /* 095 */ { "Rome 1940", 17, -225, -65, 9 }, + /* 096 */ { "S-42(Pulkovo1942)", 18, 28, -121, -77 }, + /* 097 */ { "S.E.Asia_(Indian)", 7, 173, 750, 264 }, + /* 098 */ { "SAD-69/Brazil", 22, -60, -2, -41 }, + /* 099 */ { "Santa Braz", 17, -203, 141, 53 }, + /* 100 */ { "Santo (DOS)", 17, 170, 42, 84 }, + /* 101 */ { "Sapper Hill 43", 17, -355, 16, 74 }, + /* 102 */ { "Schwarzeck", 3, 616, 97, -251 }, + /* 103 */ { "Sicily", 17, -97, -88, -135 }, + /* 104 */ { "Sierra Leone 1960", 26, 0, 0, 0 }, + /* 105 */ { "S. Am. 1969 mean", 22, -57, 1, -41 }, + /* 106 */ { "South Asia", 13, 7, -10, -26 }, + /* 107 */ { "Southeast Base", 17, -499, -249, 314 }, + /* 108 */ { "Southwest Base", 17, -104, 167, -38 }, + /* 109 */ { "Tananarive Obs 25", 17, -189, -242, -91 }, + /* 110 */ { "Thai/Viet (Indian)", 7, 214, 836, 303 }, + /* 111 */ { "Timbalai 1948", 7, -689, 691, -45 }, + /* 112 */ { "Tokyo mean", 4, -128, 481, 664 }, + /* 113 */ { "Tristan Astro 1968", 17, -632, 438, -609 }, + /* 114 */ { "United Arab Emirates", 6, -249, -156, 381 }, + /* 115 */ { "Viti Levu 1916", 6, 51, 391, -36 }, + /* 116 */ { "Wake Eniwetok 60", 15, 101, 52, -39 }, + /* 117 */ { "WGS 72", 25, 0, 0, 5 }, + /* 118 */ { "WGS 84", 26, 0, 0, 0 }, + /* 119 */ { "Yacare", 17, -155, 171, 37 }, + /* 120 */ { "Zanderij", 17, -265, 120, -358 }, + /* 121 */ { "Sweden", 4, 424.3, -80.5, 613.1 }, + /* 122 */ { "GDA 94", 21, 0, 0, 0 }, + /* 123 */ { "CH-1903", 4, 674, 15, 405 }, + /* 124 */ { "Palestine 1923", 27, -235, -85, 264 }, + /* 125 */ { "ITM (Israeli New)", 21, -48, 55, -52 }, + { NULL, 0, 0, 0, 0 } + }; + + + typedef struct GPS_SDatum_Alias { char *alias; const int datum; -} GPS_ODatum_Alias, *GPS_PDatum_Alias; + } GPS_ODatum_Alias, *GPS_PDatum_Alias; -GPS_ODatum_Alias GPS_DatumAlias[] = -{ + GPS_ODatum_Alias GPS_DatumAlias[] = { { "Australian GDA94", 122 }, { "Australian Geocentric 1994 (GDA94)", 122}, /* Observed in Ozi */ { "GDA94", 122 }, @@ -229,12 +223,11 @@ GPS_ODatum_Alias GPS_DatumAlias[] = { "Israeli", 124 }, { "D_Israel_new", 125 }, { NULL, -1 } -}; + }; -/* UK Ordnance Survey Nation Grid Map Codes */ -static char *UKNG[]= -{ + /* UK Ordnance Survey Nation Grid Map Codes */ + static char *UKNG[]= { "SV","SW","SX","SY","SZ","TV","TW","SQ","SR","SS","ST","SU","TQ","TR", "SL","SM","SN","SO","SP","TL","TM","SF","SG","SH","SJ","SK","TF","TG", "SA","SB","SC","SD","SE","TA","TB","NV","NW","NX","NY","NZ","OV","OW", @@ -242,7 +235,7 @@ static char *UKNG[]= "NF","NG","NH","NJ","NK","OF","OG","NA","NB","NC","ND","NE","OA","OB", "HV","HW","HX","HY","HZ","JV","JW","HQ","HR","HS","HT","HU","JQ","JR", "HL","HM","HN","HO","HP","JL","JM","" -}; + }; diff --git a/gpsbabel/jeeps/gpsdevice.c b/gpsbabel/jeeps/gpsdevice.c index 8c68bd6a0..669735c5b 100644 --- a/gpsbabel/jeeps/gpsdevice.c +++ b/gpsbabel/jeeps/gpsdevice.c @@ -29,60 +29,60 @@ gps_device_ops *ops = NULL; int32 GPS_Device_On(const char *port, gpsdevh **fd) { - gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); + gps_is_usb = (0 == case_ignore_strncmp(port, "usb:", 4)); - if (gps_is_usb) { - ops = &gps_usb_ops; - } else { - ops = &gps_serial_ops; - } + if (gps_is_usb) { + ops = &gps_usb_ops; + } else { + ops = &gps_serial_ops; + } - return (ops->Device_On)(port, fd); + return (ops->Device_On)(port, fd); } int32 GPS_Device_Off(gpsdevh * fd) { - return (ops->Device_Off)(fd); + return (ops->Device_Off)(fd); } int32 GPS_Device_Wait(gpsdevh * fd) { - return (ops->Device_Wait)(fd); + return (ops->Device_Wait)(fd); } int32 GPS_Device_Chars_Ready(gpsdevh * fd) { - return (ops->Device_Chars_Ready)(fd); + return (ops->Device_Chars_Ready)(fd); } int32 GPS_Device_Flush(gpsdevh * fd) { - return (ops->Device_Flush)(fd); + return (ops->Device_Flush)(fd); } int32 GPS_Write_Packet(gpsdevh * fd, GPS_PPacket packet) { - return (ops->Write_Packet)(fd, packet); + return (ops->Write_Packet)(fd, packet); } int32 GPS_Packet_Read(gpsdevh * fd, GPS_PPacket *packet) { - return (ops->Read_Packet)(fd, packet); + return (ops->Read_Packet)(fd, packet); } int32 GPS_Send_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) { - return (ops->Send_Ack)(fd, tra, rec); + return (ops->Send_Ack)(fd, tra, rec); } int32 GPS_Get_Ack(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec) { - return (ops->Get_Ack)(fd, tra, rec); + return (ops->Get_Ack)(fd, tra, rec); } void GPS_Make_Packet(GPS_PPacket *packet, US type, UC *data, uint32 n) { - (*packet)->type = type; - memcpy((*packet)->data, data, n); - (*packet)->n = n; + (*packet)->type = type; + memcpy((*packet)->data, data, n); + (*packet)->n = n; } diff --git a/gpsbabel/jeeps/gpsdevice.h b/gpsbabel/jeeps/gpsdevice.h index c428ea158..f32192ccc 100644 --- a/gpsbabel/jeeps/gpsdevice.h +++ b/gpsbabel/jeeps/gpsdevice.h @@ -27,42 +27,42 @@ extern "C" #ifndef gpsdevice_h #define gpsdevice_h -typedef struct gpsdevh gpsdevh; + typedef struct gpsdevh gpsdevh; #include "gps.h" #define usecDELAY 180000 /* Microseconds before GPS sends A001 */ -int32 GPS_Device_Chars_Ready(gpsdevh *fd); -int32 GPS_Device_On(const char *port, gpsdevh **fd); -int32 GPS_Device_Off(gpsdevh *fd); -int32 GPS_Device_Wait(gpsdevh * fd); -int32 GPS_Device_Flush(gpsdevh * fd); -int32 GPS_Device_Read(int32 ignored, void *ibuf, int size); -int32 GPS_Device_Write(int32 ignored, const void *obuf, int size); -void GPS_Device_Error(char *hdr, ...); -int32 GPS_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -int32 GPS_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); -int32 GPS_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + int32 GPS_Device_Chars_Ready(gpsdevh *fd); + int32 GPS_Device_On(const char *port, gpsdevh **fd); + int32 GPS_Device_Off(gpsdevh *fd); + int32 GPS_Device_Wait(gpsdevh * fd); + int32 GPS_Device_Flush(gpsdevh * fd); + int32 GPS_Device_Read(int32 ignored, void *ibuf, int size); + int32 GPS_Device_Write(int32 ignored, const void *obuf, int size); + void GPS_Device_Error(char *hdr, ...); + int32 GPS_Write_Packet(gpsdevh *fd, GPS_PPacket packet); + int32 GPS_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + int32 GPS_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); + int32 GPS_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -typedef int32 (*gps_device_op)(gpsdevh *); -typedef int32 (*gps_device_op5)(const char *, gpsdevh **fd); -typedef int32 (*gps_device_op10)(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec); -typedef int32 (*gps_device_op12)(gpsdevh * fd, GPS_PPacket packet); -typedef int32 (*gps_device_op13)(gpsdevh * fd, GPS_PPacket *packet); -typedef struct { - gps_device_op5 Device_On; - gps_device_op Device_Off; - gps_device_op Device_Chars_Ready; - gps_device_op Device_Wait; - gps_device_op Device_Flush; - gps_device_op10 Send_Ack; - gps_device_op10 Get_Ack; - gps_device_op13 Read_Packet; - gps_device_op12 Write_Packet; -} gps_device_ops; + typedef int32(*gps_device_op)(gpsdevh *); + typedef int32(*gps_device_op5)(const char *, gpsdevh **fd); + typedef int32(*gps_device_op10)(gpsdevh * fd, GPS_PPacket *tra, GPS_PPacket *rec); + typedef int32(*gps_device_op12)(gpsdevh * fd, GPS_PPacket packet); + typedef int32(*gps_device_op13)(gpsdevh * fd, GPS_PPacket *packet); + typedef struct { + gps_device_op5 Device_On; + gps_device_op Device_Off; + gps_device_op Device_Chars_Ready; + gps_device_op Device_Wait; + gps_device_op Device_Flush; + gps_device_op10 Send_Ack; + gps_device_op10 Get_Ack; + gps_device_op13 Read_Packet; + gps_device_op12 Write_Packet; + } gps_device_ops; #endif /* gpsdevice.h */ diff --git a/gpsbabel/jeeps/gpsdevice_ser.c b/gpsbabel/jeeps/gpsdevice_ser.c index ae6c3cd17..bea30926d 100644 --- a/gpsbabel/jeeps/gpsdevice_ser.c +++ b/gpsbabel/jeeps/gpsdevice_ser.c @@ -24,13 +24,13 @@ #include "gpsread.h" gps_device_ops gps_serial_ops = { - GPS_Serial_On, - GPS_Serial_Off, - GPS_Serial_Chars_Ready, - GPS_Serial_Wait, - GPS_Serial_Flush, - GPS_Serial_Send_Ack, - GPS_Serial_Get_Ack, - GPS_Serial_Packet_Read, - GPS_Serial_Write_Packet, + GPS_Serial_On, + GPS_Serial_Off, + GPS_Serial_Chars_Ready, + GPS_Serial_Wait, + GPS_Serial_Flush, + GPS_Serial_Send_Ack, + GPS_Serial_Get_Ack, + GPS_Serial_Packet_Read, + GPS_Serial_Write_Packet, }; diff --git a/gpsbabel/jeeps/gpsdevice_usb.c b/gpsbabel/jeeps/gpsdevice_usb.c index 32cb0ef73..73a4b23d5 100644 --- a/gpsbabel/jeeps/gpsdevice_usb.c +++ b/gpsbabel/jeeps/gpsdevice_usb.c @@ -26,33 +26,33 @@ static int32 success_stub(void) { - return 1; + return 1; } static int32 gdu_on(const char *port, gpsdevh **fd) { - return gusb_init(port, fd); + return gusb_init(port, fd); } static int32 gdu_off(gpsdevh *dh) { - return gusb_close(dh); + return gusb_close(dh); } static int32 gdu_read(gpsdevh *fd, GPS_PPacket *packet) { - /* Default is to eat bulk request packets. */ - return GPS_Packet_Read_usb(fd, packet, 1); + /* Default is to eat bulk request packets. */ + return GPS_Packet_Read_usb(fd, packet, 1); } gps_device_ops gps_usb_ops = { - gdu_on, - gdu_off, - (gps_device_op) success_stub, - (gps_device_op) success_stub, - (gps_device_op) success_stub, - (gps_device_op10) success_stub, - (gps_device_op10) success_stub, - gdu_read, - GPS_Write_Packet_usb + gdu_on, + gdu_off, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op) success_stub, + (gps_device_op10) success_stub, + (gps_device_op10) success_stub, + gdu_read, + GPS_Write_Packet_usb }; diff --git a/gpsbabel/jeeps/gpsfmt.c b/gpsbabel/jeeps/gpsfmt.c index f4919a092..6d383d0a2 100644 --- a/gpsbabel/jeeps/gpsfmt.c +++ b/gpsbabel/jeeps/gpsfmt.c @@ -2,20 +2,20 @@ ** @source JEEPS output functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -49,66 +49,62 @@ static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf); static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf); -char *gps_marine_sym[]= -{ - "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar", - "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull", - "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob", - - "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red", - "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht", - "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn", - - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","","","","","","","","","", - "","", - - "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone", - "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing", - "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball", - "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head", - "Lorry_stop","User_exit","Flag","Circle-x" +char *gps_marine_sym[]= { + "Anchor","Bell","Diamond-grn","Diamond_red","Dive1","Dive2","Dollar", + "Fish","Fuel","Horn","House","Knife","Light","Mug","Skull", + "Square_grn","Square_red","Wbuoy","Wpt_dot","Wreck","Null","Mob", + + "Buoy_amber","Buoy_blck","Buoy_blue","Buoy_grn","Buoy_grn_red", + "Buoy_grn_wht","Buoy_orng","Buoy_red","Buoy_red_grn","Buoy_red_wht", + "Buoy_violet","Buoy_wht","Buoy_wht_grn","Buoy_wht_red","Dot","Rbcn", + + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","","","","","","","","","", + "","", + + "Boat_ramp","Camp","Toilets","Showers","Drinking_wtr","Phone", + "1st_aid","Info","Parking","Park","Picnic","Scenic","Skiing", + "Swimming","Dam","Controlled","Danger","Restricted","Null_2","Ball", + "Car","Deer","Shpng_trolley","Lodging","Mine","Trail_head", + "Lorry_stop","User_exit","Flag","Circle-x" }; -char *gps_land_sym[]= -{ - "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty", - "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk", - "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film", - "Museum","Chemist","Pizza","Post_ofc","Rv_park","School", - "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int", - "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc", - "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building", - "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment", - "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit", - "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling", - "Snow_ski","Ice_ski","Tow_truck","Border" +char *gps_land_sym[]= { + "Is_hwy","Us_hwy","St_hwy","Mi_mrkr","Trcbck","Golf","Sml_cty", + "Med_cty","Lrg_cty","Freeway","Ntl_hwy","Cap_cty","Amuse_pk", + "Bowling","Car_rental","Car_repair","Fastfood","Fitness","Film", + "Museum","Chemist","Pizza","Post_ofc","Rv_park","School", + "Stadium","Shop","Zoo","Petrol_plus","Theatre","Ramp_int", + "St_int","","","Weigh_stn","Toll_booth","Elev_pt","Ex_no_srvc", + "Geo_place_mm","Geo_place_wtr","Geo_place_lnd","Bridge","Building", + "Cemetery","Church","Civil_loc","Crossing","Hist_town","River_Embankment", + "Military_loc","Oil_field","Tunnel","Beach","Forest","Summit", + "Lrg_ramp_int","Lrg_exit_no_srvc","Official_badge","Gambling", + "Snow_ski","Ice_ski","Tow_truck","Border" }; -char *gps_aviation_sym[]= -{ - "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld", - "Tall_tower","Short_tower","Glider","Ultralight","Parachute", - "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane" +char *gps_aviation_sym[]= { + "Airport","Int","Ndb","Vor","Heliport","Private","Soft_fld", + "Tall_tower","Short_tower","Glider","Ultralight","Parachute", + "Vortac","Vordme","Faf","Lom","Map","Tacan","Seaplane" }; -char *gps_16_sym[]= -{ - "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck", - "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track" +char *gps_16_sym[]= { + "Dot","House","Fuel","Car","Fish","Boat","Anchor","Wreck", + "Exit","Skull","Flag","Camp","Circle-x","Deer","1st_aid","Back_track" }; @@ -127,10 +123,10 @@ char *gps_16_sym[]= void GPS_Fmt_Print_Time(time_t Time, FILE *outf) { - (void) fprintf(outf,"%s",ctime(&Time)); - fflush(outf); + (void) fprintf(outf,"%s",ctime(&Time)); + fflush(outf); - return; + return; } @@ -148,10 +144,10 @@ void GPS_Fmt_Print_Time(time_t Time, FILE *outf) void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf) { - (void) fprintf(outf,"Latitude: %f Longitude %f\n",lat,lon); - fflush(outf); + (void) fprintf(outf,"Latitude: %f Longitude %f\n",lat,lon); + fflush(outf); - return; + return; } @@ -169,49 +165,48 @@ void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf) void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf) { - (void) fprintf(outf,"Fix: "); - switch(pvt->fix) - { - case 0: - (void) fprintf(outf,"UNUSABLE\n\n"); - break; - case 1: - (void) fprintf(outf,"INVALID \n\n"); - break; - case 2: - (void) fprintf(outf,"2D \n\n"); - break; - case 3: - (void) fprintf(outf,"3D \n\n"); - break; - case 4: - (void) fprintf(outf,"2D-diff \n\n"); - break; - case 5: - (void) fprintf(outf,"2D-diff \n\n"); - break; - default: - (void) fprintf(stderr,"PVT: Unsupported Fix type\n"); - break; - } - - (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt); - (void) fprintf(outf,"EPE: %-20f \n",pvt->epe); - (void) fprintf(outf,"EPE (hor only): %-20f \n",pvt->eph); - (void) fprintf(outf,"EPE (ver only): %-20f \n",pvt->epv); - (void) fprintf(outf,"Time of week: %-20d \n",(int)pvt->tow); - (void) fprintf(outf,"Latitude: %-20f \n",pvt->lat); - (void) fprintf(outf,"Longitude: %-20f \n",pvt->lon); - (void) fprintf(outf,"East velocity: %-20f \n",pvt->east); - (void) fprintf(outf,"North velocity: %-20f \n",pvt->north); - (void) fprintf(outf,"Upward velocity %-20f \n",pvt->up); - (void) fprintf(outf,"Height above MSL: %-20f \n",pvt->msl_hght+pvt->alt); - (void) fprintf(outf,"Leap seconds: %-20d \n",pvt->leap_scnds); - (void) fprintf(outf,"Week number days: %-20d \n",(int)pvt->wn_days); - - fflush(outf); - - return; + (void) fprintf(outf,"Fix: "); + switch (pvt->fix) { + case 0: + (void) fprintf(outf,"UNUSABLE\n\n"); + break; + case 1: + (void) fprintf(outf,"INVALID \n\n"); + break; + case 2: + (void) fprintf(outf,"2D \n\n"); + break; + case 3: + (void) fprintf(outf,"3D \n\n"); + break; + case 4: + (void) fprintf(outf,"2D-diff \n\n"); + break; + case 5: + (void) fprintf(outf,"2D-diff \n\n"); + break; + default: + (void) fprintf(stderr,"PVT: Unsupported Fix type\n"); + break; + } + + (void) fprintf(outf,"Altitude (WGS 84): %-20f \n",pvt->alt); + (void) fprintf(outf,"EPE: %-20f \n",pvt->epe); + (void) fprintf(outf,"EPE (hor only): %-20f \n",pvt->eph); + (void) fprintf(outf,"EPE (ver only): %-20f \n",pvt->epv); + (void) fprintf(outf,"Time of week: %-20d \n",(int)pvt->tow); + (void) fprintf(outf,"Latitude: %-20f \n",pvt->lat); + (void) fprintf(outf,"Longitude: %-20f \n",pvt->lon); + (void) fprintf(outf,"East velocity: %-20f \n",pvt->east); + (void) fprintf(outf,"North velocity: %-20f \n",pvt->north); + (void) fprintf(outf,"Upward velocity %-20f \n",pvt->up); + (void) fprintf(outf,"Height above MSL: %-20f \n",pvt->msl_hght+pvt->alt); + (void) fprintf(outf,"Leap seconds: %-20d \n",pvt->leap_scnds); + (void) fprintf(outf,"Week number days: %-20d \n",(int)pvt->wn_days); + + fflush(outf); + + return; } @@ -229,60 +224,61 @@ void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf) void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf) { - int32 i; - int32 t; - int32 s; - - /* Type 0 models require all 32 satellites to be sent */ - t=32; - s=0; - if(n && alm[0]->svid!=0xff) - { - s=1; - t=n; + int32 i; + int32 t; + int32 s; + + /* Type 0 models require all 32 satellites to be sent */ + t=32; + s=0; + if (n && alm[0]->svid!=0xff) { + s=1; + t=n; + } + (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s); + + + for (i=0; iwn<0) { + continue; } - (void) fprintf(outf,"Almanac %d %d\n",(int)t,(int)s); - - - for(i=0;iwn<0) continue; - - if(alm[i]->svid == 0xff) - alm[i]->svid = i; - (void) fprintf(outf,"#\n#\n"); - (void) fprintf(outf,"\tID: %d\n", - alm[i]->svid+1); - (void) fprintf(outf,"\tWeek number: %d\n", - alm[i]->wn); - (void) fprintf(outf,"\tAlmanac Data Reference Time: %f\n", - alm[i]->toa); - (void) fprintf(outf,"\tClock Correction Coeff (s): %f\n", - alm[i]->af0); - (void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n", - alm[i]->af1); - (void) fprintf(outf,"\tEccentricity: %f\n", - alm[i]->e); - (void) fprintf(outf,"\tSqrt of semi-major axis: %f\n", - alm[i]->sqrta); - (void) fprintf(outf,"\tMean Anomaly at Ref. Time: %f\n", - alm[i]->m0); - (void) fprintf(outf,"\tArgument of perigee: %f\n", - alm[i]->w); - (void) fprintf(outf,"\tRight ascension: %f\n", - alm[i]->omg0); - (void) fprintf(outf,"\tRate of right ascension: %f\n", - alm[i]->odot); - (void) fprintf(outf,"\tInclination angle: %f\n", - alm[i]->i); - (void) fprintf(outf,"\tHealth: %d\n", - alm[i]->hlth); - } - - fflush(outf); - - return; + if (alm[i]->svid == 0xff) { + alm[i]->svid = i; + } + (void) fprintf(outf,"#\n#\n"); + (void) fprintf(outf,"\tID: %d\n", + alm[i]->svid+1); + (void) fprintf(outf,"\tWeek number: %d\n", + alm[i]->wn); + (void) fprintf(outf,"\tAlmanac Data Reference Time: %f\n", + alm[i]->toa); + (void) fprintf(outf,"\tClock Correction Coeff (s): %f\n", + alm[i]->af0); + (void) fprintf(outf,"\tClock Correction Coeff (s/s): %f\n", + alm[i]->af1); + (void) fprintf(outf,"\tEccentricity: %f\n", + alm[i]->e); + (void) fprintf(outf,"\tSqrt of semi-major axis: %f\n", + alm[i]->sqrta); + (void) fprintf(outf,"\tMean Anomaly at Ref. Time: %f\n", + alm[i]->m0); + (void) fprintf(outf,"\tArgument of perigee: %f\n", + alm[i]->w); + (void) fprintf(outf,"\tRight ascension: %f\n", + alm[i]->omg0); + (void) fprintf(outf,"\tRate of right ascension: %f\n", + alm[i]->odot); + (void) fprintf(outf,"\tInclination angle: %f\n", + alm[i]->i); + (void) fprintf(outf,"\tHealth: %d\n", + alm[i]->hlth); + } + + + fflush(outf); + + return; } @@ -300,47 +296,45 @@ void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf) void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf) { - int32 i; + int32 i; - switch(gps_trk_transfer) - { - case pA300: - break; - case pA301: - GPS_Fmt_Print_Track301(trk,n,outf); - return; - default: - GPS_Error("GPS_Fmt_Print_Track: Unknown protocol"); - return; - } + switch (gps_trk_transfer) { + case pA300: + break; + case pA301: + GPS_Fmt_Print_Track301(trk,n,outf); + return; + default: + GPS_Error("GPS_Fmt_Print_Track: Unknown protocol"); + return; + } + + (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); + + for (i=0; itnew) { + (void) fprintf(outf,"#\nNew track\n#\n"); + } - (void) fprintf(outf,"Track log 300 %d\n#\n",(int)gps_trk_type); - (void) fprintf(outf,"Start\n#\n"); - - for(i=0;itnew) - (void) fprintf(outf,"#\nNew track\n#\n"); - - switch(gps_trk_type) - { - case pD300: - GPS_Fmt_Print_D300(trk[i],outf); - break; - case pD301: - GPS_Fmt_Print_D301(trk[i],outf); - break; - default: - break; - } + switch (gps_trk_type) { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; } + } - (void) fprintf(outf,"End\n#\n"); - fflush(outf); + (void) fprintf(outf,"End\n#\n"); + fflush(outf); - return; + return; } @@ -358,46 +352,45 @@ void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf) static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf) { - int32 i; - - if(!n) - return; - - (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type); - (void) fprintf(outf,"Start\n#\n"); - - for(i=0;iishdr) - { - (void) fprintf(outf,"Header\n"); - (void) fprintf(outf,"\tIdent: %s\n",trk[i]->trk_ident); - (void) fprintf(outf,"\tDisplay: %d\n",(int)trk[i]->dspl); - (void) fprintf(outf,"\tColour: %d\n#\n", - (int)trk[i]->colour); - continue; - } - - if(trk[i]->tnew) - (void) fprintf(outf,"#\nNew track\n#\n"); - - switch(gps_trk_type) - { - case pD300: - GPS_Fmt_Print_D300(trk[i],outf); - break; - case pD301: - GPS_Fmt_Print_D301(trk[i],outf); - break; - default: - break; - } + int32 i; + + if (!n) { + return; + } + + (void) fprintf(outf,"Track log 301 %d\n#\n",(int)gps_trk_type); + (void) fprintf(outf,"Start\n#\n"); + + for (i=0; iishdr) { + (void) fprintf(outf,"Header\n"); + (void) fprintf(outf,"\tIdent: %s\n",trk[i]->trk_ident); + (void) fprintf(outf,"\tDisplay: %d\n",(int)trk[i]->dspl); + (void) fprintf(outf,"\tColour: %d\n#\n", + (int)trk[i]->colour); + continue; } - (void) fprintf(outf,"End\n#\n"); - fflush(outf); + if (trk[i]->tnew) { + (void) fprintf(outf,"#\nNew track\n#\n"); + } - return; + switch (gps_trk_type) { + case pD300: + GPS_Fmt_Print_D300(trk[i],outf); + break; + case pD301: + GPS_Fmt_Print_D301(trk[i],outf); + break; + default: + break; + } + } + + (void) fprintf(outf,"End\n#\n"); + fflush(outf); + + return; } @@ -413,14 +406,15 @@ static void GPS_Fmt_Print_Track301(GPS_PTrack *trk, int32 n, FILE *outf) static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf) { - (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); - (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); - if(trk->Time) - (void) fprintf(outf,"\tTime: %s\n",ctime(&trk->Time)); - else - (void) fprintf(outf,"\tTime: Computer\n\n"); - - return; + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if (trk->Time) { + (void) fprintf(outf,"\tTime: %s\n",ctime(&trk->Time)); + } else { + (void) fprintf(outf,"\tTime: Computer\n\n"); + } + + return; } @@ -437,16 +431,17 @@ static void GPS_Fmt_Print_D300(GPS_PTrack trk, FILE *outf) static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf) { - (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); - (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); - if(trk->Time) - (void) fprintf(outf,"\tTime: %s",ctime(&trk->Time)); - else - (void) fprintf(outf,"\tTime: Computer\n"); - (void) fprintf(outf,"\tAltitude: %f\n",trk->alt); - (void) fprintf(outf,"\tDepth: %f\n\n",trk->dpth); - - return; + (void) fprintf(outf,"\tLatitude: %f\n",trk->lat); + (void) fprintf(outf,"\tLongitude: %f\n",trk->lon); + if (trk->Time) { + (void) fprintf(outf,"\tTime: %s",ctime(&trk->Time)); + } else { + (void) fprintf(outf,"\tTime: Computer\n"); + } + (void) fprintf(outf,"\tAltitude: %f\n",trk->alt); + (void) fprintf(outf,"\tDepth: %f\n\n",trk->dpth); + + return; } @@ -465,74 +460,73 @@ static void GPS_Fmt_Print_D301(GPS_PTrack trk, FILE *outf) int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf) { - int32 i; - - - if(!n) - return 1; - - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", - (int)way[0]->prot); - - - for(i=0;iprot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Waypoint: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n#\n"); + int32 i; + + if (!n) { return 1; + } + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for (i=0; iprot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Waypoint: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; } @@ -550,76 +544,75 @@ int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf) int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf) { - int32 i; - - - if(!n) - return 1; - - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", - (int)way[0]->prot); - - - for(i=0;iprot) - { - case 400: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 403: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 450: - GPS_Fmt_Print_Way150(way[i],outf); - (void) fprintf(outf,"\tPindex: %d\n",(int)way[i]->idx); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Proximity: Unknown proximity protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\tDistance: %f\n",way[i]->dst); - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n#\n"); + int32 i; + + if (!n) { return 1; + } + + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n", + (int)way[0]->prot); + + + for (i=0; iprot) { + case 400: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 403: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 450: + GPS_Fmt_Print_Way150(way[i],outf); + (void) fprintf(outf,"\tPindex: %d\n",(int)way[i]->idx); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Proximity: Unknown proximity protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\tDistance: %f\n",way[i]->dst); + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); + + return 1; } @@ -638,12 +631,12 @@ int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf) static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - return; + return; } @@ -660,16 +653,18 @@ static void GPS_Fmt_Print_Way100(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf) { - if(way->smbl > 176) way->smbl=36; - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, - gps_marine_sym[way->smbl]); + if (way->smbl > 176) { + way->smbl=36; + } - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + gps_marine_sym[way->smbl]); + + return; } @@ -685,34 +680,29 @@ static void GPS_Fmt_Print_Way101(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - - return; + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + + return; } @@ -728,21 +718,20 @@ static void GPS_Fmt_Print_Way102(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf) { - static char *dspl[]= - { - "SW","S","SC" - }; - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - gps_16_sym[way->smbl]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - - return; + static char *dspl[]= { + "SW","S","SC" + }; + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; } @@ -758,39 +747,33 @@ static void GPS_Fmt_Print_Way103(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf) { - static char *dspl[]= - { - "S","S","","SW","","SC" - }; - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - - return; + static char *dspl[]= { + "S","S","","SW","","SC" + }; + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + + return; } @@ -806,32 +789,27 @@ static void GPS_Fmt_Print_Way104(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); - - return; + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + + return; } @@ -847,48 +825,40 @@ static void GPS_Fmt_Print_Way105(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - if(!way->wpt_class) - { - (void) fprintf(outf,"\tClass: %d [User]\n",way->wpt_class); - (void) fprintf(outf,"\tSubclass: %d [%-13.13s]\n", - way->wpt_class,way->subclass); - (void) fprintf(outf,"\tSubclass:\n"); - } - else - { - (void) fprintf(outf,"\tClass: %d [Non-user]\n", - way->wpt_class); - (void) fprintf(outf,"\tSubclass: %d [%13.13s]\n", - way->wpt_class, - way->subclass); - } - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); - (void) fprintf(outf,"\tLnk_ident %s\n",way->lnk_ident); - - return; + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + if (!way->wpt_class) { + (void) fprintf(outf,"\tClass: %d [User]\n",way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%-13.13s]\n", + way->wpt_class,way->subclass); + (void) fprintf(outf,"\tSubclass:\n"); + } else { + (void) fprintf(outf,"\tClass: %d [Non-user]\n", + way->wpt_class); + (void) fprintf(outf,"\tSubclass: %d [%13.13s]\n", + way->wpt_class, + way->subclass); + } + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tWpt_ident %s\n",way->wpt_ident); + (void) fprintf(outf,"\tLnk_ident %s\n",way->lnk_ident); + + return; } @@ -904,28 +874,26 @@ static void GPS_Fmt_Print_Way106(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf) { - static char *dspl[]= - { - "SW","S","SC" - }; - static char *col[]= - { - "Default","Red","Green","Blue" - }; - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - gps_16_sym[way->smbl]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); - - return; + static char *dspl[]= { + "SW","S","SC" + }; + static char *col[]= { + "Default","Red","Green","Blue" + }; + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + gps_16_sym[way->smbl]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + + return; } @@ -942,71 +910,67 @@ static void GPS_Fmt_Print_Way107(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - static char *dspl[]= - { - "SW","S","SC" - }; - - static char *col[]= - { - "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", - "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", - "Yellow","Blue","Magenta","Cyan","White" - }; - - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - if(way->colour==0xff) - (void) fprintf(outf,"\tColour: 255 [Default]\n"); - else - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - (void) fprintf(outf,"\tDepth: %f\n",way->dpth); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class>=0x80 && way->wpt_class<=0x85) - (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); - if(!way->wpt_class) - (void) fprintf(outf,"\tComment: %s\n",way->cmnt); - if(way->wpt_class>=0x40 && way->wpt_class<=0x46) - { - (void) fprintf(outf,"\tFacility: %s\n",way->facility); - (void) fprintf(outf,"\tCity: %s\n",way->city); - } - if(way->wpt_class==0x83) - (void) fprintf(outf,"\tAddress: %s\n",way->addr); - if(way->wpt_class==0x82) - (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); - - - return; + char **p; + int32 x; + + static char *dspl[]= { + "SW","S","SC" + }; + + static char *col[]= { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if (way->colour==0xff) { + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + } else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class>=0x80 && way->wpt_class<=0x85) { + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + } + if (way->wpt_class>=0x40 && way->wpt_class<=0x46) { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if (way->wpt_class==0x83) { + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + } + if (way->wpt_class==0x82) { + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + } + + + return; } /* @funcstatic GPS_Fmt_Print_Way109 ************************************ @@ -1021,74 +985,70 @@ static void GPS_Fmt_Print_Way108(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - static char *dspl[]= - { - "SW","S","SC" - }; - - static char *col[]= - { - "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", - "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", - "Yellow","Blue","Magenta","Cyan","White" - }; - - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - (void) fprintf(outf,"\tIdent: %s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - if(way->colour==0xff) - (void) fprintf(outf,"\tColour: 255 [Default]\n"); - else - (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, - col[way->colour]); + char **p; + int32 x; + + static char *dspl[]= { + "SW","S","SC" + }; + + static char *col[]= { + "Black","Dark_Red","Dark_Green","Dark_Yellow","Dark_Blue", + "Dark_Magenta","Dark_Cyan","Light_Grey","Dark_Grey","Red","Green", + "Yellow","Blue","Magenta","Cyan","White" + }; + + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + (void) fprintf(outf,"\tIdent: %s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + if (way->colour==0xff) { + (void) fprintf(outf,"\tColour: 255 [Default]\n"); + } else + (void) fprintf(outf,"\tColour: %-6d [%s]\n",(int)way->colour, + col[way->colour]); #if 0 - /* avoid bounds violation in D109. Probably masking a bug elswhere...*/ - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); + /* avoid bounds violation in D109. Probably masking a bug elswhere...*/ + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); #endif - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - (void) fprintf(outf,"\tDepth: %f\n",way->dpth); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class>=0x80 && way->wpt_class<=0x85) - (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); - if(!way->wpt_class) - (void) fprintf(outf,"\tComment: %s\n",way->cmnt); - if(way->wpt_class>=0x40 && way->wpt_class<=0x46) - { - (void) fprintf(outf,"\tFacility: %s\n",way->facility); - (void) fprintf(outf,"\tCity: %s\n",way->city); - } - if(way->wpt_class==0x83) - (void) fprintf(outf,"\tAddress: %s\n",way->addr); - if(way->wpt_class==0x82) - (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); - - - return; + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + (void) fprintf(outf,"\tDepth: %f\n",way->dpth); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class>=0x80 && way->wpt_class<=0x85) { + (void) fprintf(outf,"\tSubclass: %18.18s\n",way->subclass); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tComment: %s\n",way->cmnt); + } + if (way->wpt_class>=0x40 && way->wpt_class<=0x46) { + (void) fprintf(outf,"\tFacility: %s\n",way->facility); + (void) fprintf(outf,"\tCity: %s\n",way->city); + } + if (way->wpt_class==0x83) { + (void) fprintf(outf,"\tAddress: %s\n",way->addr); + } + if (way->wpt_class==0x82) { + (void) fprintf(outf,"\tCross Road: %s\n",way->cross_road); + } + + + return; } /* @funcstatic GPS_Fmt_Print_Way150 ************************************* @@ -1104,22 +1064,22 @@ static void GPS_Fmt_Print_Way109(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1136,22 +1096,22 @@ static void GPS_Fmt_Print_Way150(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=2) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=2) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1169,22 +1129,22 @@ static void GPS_Fmt_Print_Way151(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf) { - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1200,44 +1160,39 @@ static void GPS_Fmt_Print_Way152(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf) { - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4 && way->wpt_class!=8) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4 && way->wpt_class!=8) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1253,51 +1208,45 @@ static void GPS_Fmt_Print_Way154(GPS_PWay way, FILE *outf) static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf) { - static char *dspl[]= - { - "","S","","SW","","SC" - }; - - char **p; - int32 x; - - if(way->smbl < 8192) - { - p = gps_marine_sym; - x = 0; - } - else if(way->smbl < 16384) - { - p = gps_land_sym; - x = 8192; - } - else - { - p = gps_aviation_sym; - x = 16384; - } - - - (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); - (void) fprintf(outf,"\tLatitude: %f\n",way->lat); - (void) fprintf(outf,"\tLongitude: %f\n",way->lon); - (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); - (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, - p[way->smbl-x]); - (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, - dspl[way->dspl]); - (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); - if(way->wpt_class!=4 && way->wpt_class!=8) - { - (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); - (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); - (void) fprintf(outf,"\tState: %-2.2s\n",way->state); - (void) fprintf(outf,"\tName: %-30.30s\n",way->name); - } - if(!way->wpt_class) - (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); - - return; + static char *dspl[]= { + "","S","","SW","","SC" + }; + + char **p; + int32 x; + + if (way->smbl < 8192) { + p = gps_marine_sym; + x = 0; + } else if (way->smbl < 16384) { + p = gps_land_sym; + x = 8192; + } else { + p = gps_aviation_sym; + x = 16384; + } + + + (void) fprintf(outf,"\tIdent: %-6.6s\n",way->ident); + (void) fprintf(outf,"\tLatitude: %f\n",way->lat); + (void) fprintf(outf,"\tLongitude: %f\n",way->lon); + (void) fprintf(outf,"\tComment: %-40.40s\n",way->cmnt); + (void) fprintf(outf,"\tSymbol: %-6d [%s]\n",(int)way->smbl, + p[way->smbl-x]); + (void) fprintf(outf,"\tDisplay: %-6d [%s]\n",(int)way->dspl, + dspl[way->dspl]); + (void) fprintf(outf,"\tClass: %d\n",way->wpt_class); + if (way->wpt_class!=4 && way->wpt_class!=8) { + (void) fprintf(outf,"\tCountry: %-2.2s\n",way->cc); + (void) fprintf(outf,"\tCity: %-24.24s\n",way->city); + (void) fprintf(outf,"\tState: %-2.2s\n",way->state); + (void) fprintf(outf,"\tName: %-30.30s\n",way->name); + } + if (!way->wpt_class) { + (void) fprintf(outf,"\tAltitude: %d\n",(int)way->alt); + } + + return; } @@ -1315,119 +1264,116 @@ static void GPS_Fmt_Print_Way155(GPS_PWay way, FILE *outf) int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf) { - int32 i; - int32 first; - - if(!n) - return 1; - - - switch(gps_route_transfer) - { - case pA200: - break; - case pA201: - return GPS_Fmt_Print_Route201(way,n,outf); - default: - GPS_Error("GPS_Fmt_Print_Route: Unknown protocol"); - return PROTOCOL_ERROR; - } + int32 i; + int32 first; + if (!n) { + return 1; + } + + + switch (gps_route_transfer) { + case pA200: + break; + case pA201: + return GPS_Fmt_Print_Route201(way,n,outf); + default: + GPS_Error("GPS_Fmt_Print_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type); + (void) fprintf(outf,"Start\n#\n"); + + + + first = 1; + + for (i=0; iisrte) { + if (!first) { + (void) fprintf(outf,"End\n#\n"); + } + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch (way[i]->rte_prot) { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n" + ,(int)way[i]->prot); + continue; + } - (void) fprintf(outf,"Route log 200 %d\n#\n",(int)gps_rte_type); - (void) fprintf(outf,"Start\n#\n"); - - - - first = 1; - - for(i=0;iisrte) - { - if(!first) - (void) fprintf(outf,"End\n#\n"); - (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); - first=0; - - switch(way[i]->rte_prot) - { - case 200: - (void) fprintf(outf,"Number: %d",way[i]->rte_num); - break; - case 201: - (void) fprintf(outf,"Number: %d Comment: %-20.20s", - way[i]->rte_num,way[i]->rte_cmnt); - break; - case 202: - (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); - break; - default: - GPS_Error("Print_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\n#\n"); - (void) fprintf(outf,"Waypoints Type: %d\n#\nStart\n#\n" - ,(int)way[i]->prot); - continue; - } - - switch(way[i]->prot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Route: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); + switch (way[i]->prot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; } - (void) fprintf(outf,"End\n#\n"); + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n#\n"); - return 1; + return 1; } @@ -1445,118 +1391,115 @@ int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf) static int32 GPS_Fmt_Print_Route201(GPS_PWay *way, int32 n, FILE *outf) { - int32 i; - int32 first; - - if(!n) - return 1; - - - (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type); - (void) fprintf(outf,"Start\n#\n"); - - - first = 1; - - for(i=0;iisrte) - { - if(!first) - (void) fprintf(outf,"End\n#\n"); - (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); - first=0; - - switch(way[i]->rte_prot) - { - case 200: - (void) fprintf(outf,"Number: %d",way[i]->rte_num); - break; - case 201: - (void) fprintf(outf,"Number: %d Comment: %-20.20s", - way[i]->rte_num,way[i]->rte_cmnt); - break; - case 202: - (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); - break; - default: - GPS_Error("Print_Route: Unknown route protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"\n#\n"); - (void) fprintf(outf,"Waypoints Type: %d\n#\n" - ,(int)way[i]->prot); - continue; - } - - - if(way[i]->islink) - { - (void) fprintf(outf,"\tLink Class: %d\n", - (int)way[i]->rte_link_class); - if(!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff)) - (void) fprintf(outf,"\tLink Subclass: %-18.18s\n", - way[i]->rte_link_subclass); - (void) fprintf(outf,"\tLink Ident: %s\n#\n", - way[i]->rte_link_ident); - continue; - } - - - switch(way[i]->prot) - { - case 100: - GPS_Fmt_Print_Way100(way[i],outf); - break; - case 101: - GPS_Fmt_Print_Way101(way[i],outf); - break; - case 102: - GPS_Fmt_Print_Way102(way[i],outf); - break; - case 103: - GPS_Fmt_Print_Way103(way[i],outf); - break; - case 104: - GPS_Fmt_Print_Way104(way[i],outf); - break; - case 105: - GPS_Fmt_Print_Way105(way[i],outf); - break; - case 106: - GPS_Fmt_Print_Way106(way[i],outf); - break; - case 107: - GPS_Fmt_Print_Way107(way[i],outf); - break; - case 108: - GPS_Fmt_Print_Way108(way[i],outf); - break; - case 109: - GPS_Fmt_Print_Way109(way[i],outf); - break; - case 150: - GPS_Fmt_Print_Way150(way[i],outf); - break; - case 151: - GPS_Fmt_Print_Way151(way[i],outf); - break; - case 152: - GPS_Fmt_Print_Way152(way[i],outf); - break; - case 154: - GPS_Fmt_Print_Way154(way[i],outf); - break; - case 155: - GPS_Fmt_Print_Way155(way[i],outf); - break; - default: - GPS_Error("Print_Route: Unknown waypoint protocol"); - return PROTOCOL_ERROR; - } - (void) fprintf(outf,"#\n"); - } - (void) fprintf(outf,"End\n"); + int32 i; + int32 first; + if (!n) { return 1; + } + + + (void) fprintf(outf,"Route log 201 %d\n#\n",(int)gps_rte_link_type); + (void) fprintf(outf,"Start\n#\n"); + + + first = 1; + + for (i=0; iisrte) { + if (!first) { + (void) fprintf(outf,"End\n#\n"); + } + (void) fprintf(outf,"Route Type: %d ",(int)way[i]->rte_prot); + first=0; + + switch (way[i]->rte_prot) { + case 200: + (void) fprintf(outf,"Number: %d",way[i]->rte_num); + break; + case 201: + (void) fprintf(outf,"Number: %d Comment: %-20.20s", + way[i]->rte_num,way[i]->rte_cmnt); + break; + case 202: + (void) fprintf(outf,"Comment: %s",way[i]->rte_ident); + break; + default: + GPS_Error("Print_Route: Unknown route protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"\n#\n"); + (void) fprintf(outf,"Waypoints Type: %d\n#\n" + ,(int)way[i]->prot); + continue; + } + + + if (way[i]->islink) { + (void) fprintf(outf,"\tLink Class: %d\n", + (int)way[i]->rte_link_class); + if (!(way[i]->rte_link_class==3 || way[i]->rte_link_class==0xff)) + (void) fprintf(outf,"\tLink Subclass: %-18.18s\n", + way[i]->rte_link_subclass); + (void) fprintf(outf,"\tLink Ident: %s\n#\n", + way[i]->rte_link_ident); + continue; + } + + + switch (way[i]->prot) { + case 100: + GPS_Fmt_Print_Way100(way[i],outf); + break; + case 101: + GPS_Fmt_Print_Way101(way[i],outf); + break; + case 102: + GPS_Fmt_Print_Way102(way[i],outf); + break; + case 103: + GPS_Fmt_Print_Way103(way[i],outf); + break; + case 104: + GPS_Fmt_Print_Way104(way[i],outf); + break; + case 105: + GPS_Fmt_Print_Way105(way[i],outf); + break; + case 106: + GPS_Fmt_Print_Way106(way[i],outf); + break; + case 107: + GPS_Fmt_Print_Way107(way[i],outf); + break; + case 108: + GPS_Fmt_Print_Way108(way[i],outf); + break; + case 109: + GPS_Fmt_Print_Way109(way[i],outf); + break; + case 150: + GPS_Fmt_Print_Way150(way[i],outf); + break; + case 151: + GPS_Fmt_Print_Way151(way[i],outf); + break; + case 152: + GPS_Fmt_Print_Way152(way[i],outf); + break; + case 154: + GPS_Fmt_Print_Way154(way[i],outf); + break; + case 155: + GPS_Fmt_Print_Way155(way[i],outf); + break; + default: + GPS_Error("Print_Route: Unknown waypoint protocol"); + return PROTOCOL_ERROR; + } + (void) fprintf(outf,"#\n"); + } + (void) fprintf(outf,"End\n"); + + return 1; } diff --git a/gpsbabel/jeeps/gpsfmt.h b/gpsbabel/jeeps/gpsfmt.h index f9eaae32c..3db8e02a5 100644 --- a/gpsbabel/jeeps/gpsfmt.h +++ b/gpsbabel/jeeps/gpsfmt.h @@ -11,14 +11,14 @@ extern "C" #include #include -void GPS_Fmt_Print_Time(time_t Time, FILE *outf); -void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf); -void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf); -void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf); -void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf); -int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf); + void GPS_Fmt_Print_Time(time_t Time, FILE *outf); + void GPS_Fmt_Print_Position(double lat, double lon, FILE *outf); + void GPS_Fmt_Print_Pvt(GPS_PPvt_Data pvt, FILE *outf); + void GPS_Fmt_Print_Almanac(GPS_PAlmanac *alm, int32 n, FILE *outf); + void GPS_Fmt_Print_Track(GPS_PTrack *trk, int32 n, FILE *outf); + int32 GPS_Fmt_Print_Waypoint(GPS_PWay *way, int32 n, FILE *outf); + int32 GPS_Fmt_Print_Proximity(GPS_PWay *way, int32 n, FILE *outf); + int32 GPS_Fmt_Print_Route(GPS_PWay *way, int32 n, FILE *outf); #endif diff --git a/gpsbabel/jeeps/gpsinput.c b/gpsbabel/jeeps/gpsinput.c index 9cdf84741..eea2d8c2c 100644 --- a/gpsbabel/jeeps/gpsinput.c +++ b/gpsbabel/jeeps/gpsinput.c @@ -2,20 +2,20 @@ ** @source JEEPS input functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -49,7 +49,7 @@ static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf); static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf); static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, - int32 n); + int32 n); static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s); static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s); @@ -69,35 +69,42 @@ static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf); ************************************************************************/ static int32 GPS_Input_Load_String(char *t, int32 n, char *s) { - char *p; - char *q; - - int32 len; - int32 i; - - gps_errno = INPUT_ERROR; - - p=s; - if(!(p=strchr(p,':'))) - return gps_errno; + char *p; + char *q; + + int32 len; + int32 i; + + gps_errno = INPUT_ERROR; + + p=s; + if (!(p=strchr(p,':'))) { + return gps_errno; + } + ++p; + while (*p && (*p==' ' || *p=='\t')) { ++p; - while(*p && (*p==' ' || *p=='\t')) ++p; - if(!*p) - return 0; - - len = strlen(p); - q = p+len-1; - while(*q==' ' || *q=='\t') --q; - len = q-p+1; - - if(q-p+1 > n) - { - len = n; - p[n]='\0'; - } - for(i=0;i n) { + len = n; + p[n]='\0'; + } + for (i=0; isvid = i; - (*alm)[i]->wn = -1; - } - } - else - { - if(!(*alm = (GPS_PAlmanac *) malloc(n*sizeof(GPS_PAlmanac *)))) - return MEMORY_ERROR; - for(i=0;i<32;++i) - if(!((*alm)[i] = GPS_Almanac_New())) - return MEMORY_ERROR; - } - - for(i=0;isvid!=d) ++i; - (*alm)[i]->svid=d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*alm)[i]->wn = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->toa = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->af0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->af1 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->e = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->sqrta = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->m0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->w = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->omg0 = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->odot = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%f",&f)!=1) - return gps_errno; - (*alm)[i]->i = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*alm)[i]->hlth=d; - } - - if(!type) - n = 32; - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 i; + int32 d; + float f; + char *p; + + gps_errno = INPUT_ERROR; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + if (sscanf(s,"Almanac %d%d",(int *)&n,(int *)&type)!=2) { + return gps_errno; + } + + if (!type) { + if (!(*alm = (GPS_PAlmanac *) malloc(32*sizeof(GPS_PAlmanac *)))) { + return MEMORY_ERROR; + } + for (i=0; i<32; ++i) { + if (!((*alm)[i] = GPS_Almanac_New())) { + return MEMORY_ERROR; + } + + (*alm)[i]->svid = i; + (*alm)[i]->wn = -1; + } + } else { + if (!(*alm = (GPS_PAlmanac *) malloc(n*sizeof(GPS_PAlmanac *)))) { + return MEMORY_ERROR; + } + for (i=0; i<32; ++i) + if (!((*alm)[i] = GPS_Almanac_New())) { + return MEMORY_ERROR; + } + } + + for (i=0; isvid!=d) { + ++i; + } + (*alm)[i]->svid=d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*alm)[i]->wn = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->toa = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->af0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->af1 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->e = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->sqrta = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->m0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->w = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->omg0 = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->odot = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%f",&f)!=1) { + return gps_errno; + } + (*alm)[i]->i = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*alm)[i]->hlth=d; + } + + if (!type) { + n = 32; + } + + return n; } @@ -341,121 +379,157 @@ int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf) int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 i; - long pos; - int32 ret; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 0; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude")) - ++n; - } - fseek(inf,pos,0); - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - - for(i=0;iprot = type; + } + + + for (i=0; iprot = type; - } - - for(i=0;idst = f; - } - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 i; + long pos; + int32 ret; + double f; + char *p; + + gps_errno = INPUT_ERROR; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strncmp(s,"Start",5)) { + return gps_errno; + } + + pos = ftell(inf); + n = 0; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude")) { + ++n; + } + } + fseek(inf,pos,0); + + if (!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + for (i=0; idst = f; + } + + return n; } @@ -610,34 +722,40 @@ int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + double f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + return 1; } @@ -653,43 +771,51 @@ static int32 GPS_Input_Get_D100(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + return 1; } @@ -705,7 +831,7 @@ static int32 GPS_Input_Get_D101(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf) { - return GPS_Input_Get_D101(way,inf); + return GPS_Input_Get_D101(way,inf); } @@ -721,50 +847,60 @@ static int32 GPS_Input_Get_D102(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + return 1; } @@ -780,7 +916,7 @@ static int32 GPS_Input_Get_D103(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf) { - return GPS_Input_Get_D103(way,inf); + return GPS_Input_Get_D103(way,inf); } @@ -796,39 +932,46 @@ static int32 GPS_Input_Get_D104(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->wpt_ident,s); - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + return 1; } @@ -844,58 +987,70 @@ static int32 GPS_Input_Get_D105(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,13,s); - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->wpt_ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->lnk_ident,s); - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char *)(*way)->subclass,13,s); + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->wpt_ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->lnk_ident,s); + + return 1; } @@ -911,23 +1066,26 @@ static int32 GPS_Input_Get_D106(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - int32 d; - int32 ret; - - if((ret=GPS_Input_Get_D103(way,inf))<0) - return ret; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - return 1; + char s[GPS_ARB_LEN]; + char *p; + + int32 d; + int32 ret; + + if ((ret=GPS_Input_Get_D103(way,inf))<0) { + return ret; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + return 1; } @@ -943,129 +1101,147 @@ static int32 GPS_Input_Get_D107(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - double f; - int32 d; - int32 xc; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + char s[GPS_ARB_LEN]; + char *p; + double f; + int32 d; + int32 xc; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->dpth = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + xc = d; + + if (xc>=0x80 && xc<=0x85) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char *)(*way)->subclass,18,s); + } else { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if (!xc) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cmnt,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->dpth = f; + if (xc>=0x40 && xc<=0x46) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->facility,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->city,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (xc==0x83) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->addr,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + if (xc==0x82) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cross_road,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - xc = d; - - if(xc>=0x80 && xc<=0x85) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,18,s); - } - else - { - GPS_Util_Put_Short((*way)->subclass,0); - GPS_Util_Put_Int((*way)->subclass+2,0); - GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); - } - - if(!xc) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cmnt,s); - } - - if(xc>=0x40 && xc<=0x46) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->facility,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->city,s); - } - - if(xc==0x83) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->addr,s); - } - - if(xc==0x82) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cross_road,s); - } - - return 1; + return 1; } @@ -1082,129 +1258,147 @@ static int32 GPS_Input_Get_D108(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum) { - char s[GPS_ARB_LEN]; - char *p; - double f; - int32 d; - int32 xc; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->colour = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + char s[GPS_ARB_LEN]; + char *p; + double f; + int32 d; + int32 xc; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->colour = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->dpth = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = d; + xc = d; + + if (xc>=0x80 && xc<=0x85) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((char *)(*way)->subclass,18,s); + } else { + GPS_Util_Put_Short((*way)->subclass,0); + GPS_Util_Put_Int((*way)->subclass+2,0); + GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); + GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); + } + + if (!xc) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cmnt,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->dpth = f; + if (xc>=0x40 && xc<=0x46) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->facility,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->city,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (xc==0x83) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->addr,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + if (xc==0x82) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)->cross_road,s); + } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = d; - xc = d; - - if(xc>=0x80 && xc<=0x85) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((char *)(*way)->subclass,18,s); - } - else - { - GPS_Util_Put_Short((*way)->subclass,0); - GPS_Util_Put_Int((*way)->subclass+2,0); - GPS_Util_Put_Uint((*way)->subclass+6,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+10,0xffffffff); - GPS_Util_Put_Uint((*way)->subclass+14,0xffffffff); - } - - if(!xc) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cmnt,s); - } - - if(xc>=0x40 && xc<=0x46) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->facility,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->city,s); - } - - if(xc==0x83) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->addr,s); - } - - if(xc==0x82) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)->cross_road,s); - } - - return 1; + return 1; } @@ -1219,73 +1413,85 @@ static int32 GPS_Input_Get_D109(GPS_PWay *way, FILE *inf, int protonum) ************************************************************************/ static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1301,73 +1507,85 @@ static int32 GPS_Input_Get_D150(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 2) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 2) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1382,7 +1600,7 @@ static int32 GPS_Input_Get_D151(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf) { - return GPS_Input_Get_D150(way,inf); + return GPS_Input_Get_D150(way,inf); } @@ -1398,80 +1616,94 @@ static int32 GPS_Input_Get_D152(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4 && cl != 8) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4 && cl != 8) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1487,87 +1719,103 @@ static int32 GPS_Input_Get_D154(GPS_PWay *way, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf) { - char s[GPS_ARB_LEN]; - char *p; - - double f; - int32 d; - int32 cl=0; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->ident,6,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*way)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cmnt,40,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->smbl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->dspl = d; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->wpt_class = cl = d; - - if(cl != 4 && cl != 8) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->cc,2,s); + char s[GPS_ARB_LEN]; + char *p; + + double f; + int32 d; + int32 cl=0; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->ident,6,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*way)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cmnt,40,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->smbl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->dspl = d; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; + } + (*way)->wpt_class = cl = d; + + if (cl != 4 && cl != 8) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->cc,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->city,24,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->city,24,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->state,2,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)->state,2,s); - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)->name,30,s); + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; } + GPS_Input_Load_String((*way)->name,30,s); + } - if(!cl) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_errno; - (*way)->alt = d; + if (!cl) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_errno; } + (*way)->alt = d; + } - return 1; + return 1; } @@ -1584,90 +1832,97 @@ static int32 GPS_Input_Get_D155(GPS_PWay *way, FILE *inf) int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 i; - long pos; - int32 a; - int32 d; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Track log",9)) - return gps_errno; - - if(sscanf(s,"Track log %d%d",(int *)&a,(int *)&d)!=2) - return INPUT_ERROR; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 0; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude")) - ++n; - if(strstr(s,"Header")) - ++n; - } - fseek(inf,pos,0); - - - if(!(*trk=(GPS_PTrack *)malloc(n*sizeof(GPS_PTrack *)))) - return MEMORY_ERROR; - for(i=0;itnew=1; + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } else { + (*trk)[i]->tnew=0; + } + + switch (d) { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; default: - return INPUT_ERROR; - } - - - - for(i=0;itnew=1; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - else - (*trk)[i]->tnew=0; - - switch(d) - { - case pD300: - GPS_Input_Get_D300(&((*trk)[i]),inf,s); - break; - case pD301: - GPS_Input_Get_D301(&((*trk)[i]),inf,s); - break; - default: - return PROTOCOL_ERROR; - } - } - - return n; + return PROTOCOL_ERROR; + } + } + + return n; } @@ -1685,67 +1940,70 @@ int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf) ************************************************************************/ static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, - int32 n) + int32 n) { - char s[GPS_ARB_LEN]; - int32 i; - char *p; - int32 x; - - for(i=0;iishdr = 1; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*trk)[i]->trk_ident,s); - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&x)!=1) - return INPUT_ERROR; - (*trk)[i]->dspl = x; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&x)!=1) - return INPUT_ERROR; - (*trk)[i]->colour = x; - - continue; - } - - (*trk)[i]->ishdr = 0; - - if(!strcmp(s,"New track")) - { - (*trk)[i]->tnew=1; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - else - (*trk)[i]->tnew=0; - - switch(type) - { - case pD300: - GPS_Input_Get_D300(&((*trk)[i]),inf,s); - break; - case pD301: - GPS_Input_Get_D301(&((*trk)[i]),inf,s); - break; - default: - return PROTOCOL_ERROR; - } - } - - return n; + char s[GPS_ARB_LEN]; + int32 i; + char *p; + int32 x; + + for (i=0; iishdr = 1; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*trk)[i]->trk_ident,s); + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&x)!=1) { + return INPUT_ERROR; + } + (*trk)[i]->dspl = x; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&x)!=1) { + return INPUT_ERROR; + } + (*trk)[i]->colour = x; + + continue; + } + + (*trk)[i]->ishdr = 0; + + if (!strcmp(s,"New track")) { + (*trk)[i]->tnew=1; + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } else { + (*trk)[i]->tnew=0; + } + + switch (type) { + case pD300: + GPS_Input_Get_D300(&((*trk)[i]),inf,s); + break; + case pD301: + GPS_Input_Get_D301(&((*trk)[i]),inf,s); + break; + default: + return PROTOCOL_ERROR; + } + } + + return n; } @@ -1763,26 +2021,30 @@ static int32 GPS_Input_Get_Track301(GPS_PTrack **trk, FILE *inf, int32 type, static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s) { - char *p; - double f; - - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - (*trk)->Time = 0; - - return 1; + char *p; + double f; + + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + (*trk)->Time = 0; + + return 1; } @@ -1800,40 +2062,48 @@ static int32 GPS_Input_Get_D300(GPS_PTrack *trk, FILE *inf, char *s) static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s) { - char *p; - double f; - - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lat = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->lon = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - (*trk)->Time = 0; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->alt = f; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - p=strchr(s,':'); - if(sscanf(p+1,"%lf",&f)!=1) - return gps_errno; - (*trk)->dpth = f; - - return 1; + char *p; + double f; + + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lat = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->lon = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + (*trk)->Time = 0; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->alt = f; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + p=strchr(s,':'); + if (sscanf(p+1,"%lf",&f)!=1) { + return gps_errno; + } + (*trk)->dpth = f; + + return 1; } @@ -1850,197 +2120,238 @@ static int32 GPS_Input_Get_D301(GPS_PTrack *trk, FILE *inf, char *s) int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 rtype=0; - int32 atype=0; - int32 i; - long pos; - int32 ret; - char *p; - int32 d; - - gps_errno = INPUT_ERROR; - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route log %d",(int *)&atype)!=1) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - switch(atype) - { - case pA200: - break; - case pA201: - return GPS_Input_Get_Route201(way,inf); + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype=0; + int32 atype=0; + int32 i; + long pos; + int32 ret; + char *p; + int32 d; + + gps_errno = INPUT_ERROR; + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route log %d",(int *)&atype)!=1) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + switch (atype) { + case pA200: + break; + case pA201: + return GPS_Input_Get_Route201(way,inf); + default: + GPS_Error("GPS_Input_Get_Route: Unknown protocol"); + return PROTOCOL_ERROR; + } + + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route Type: %d",(int *)&rtype)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strncmp(s,"Start",5)) { + return gps_errno; + } + + pos = ftell(inf); + n = 1; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude") || strstr(s,"Route")) { + ++n; + } + } + fseek(inf,0L,0); + + + if (!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + for (i=0; irte_prot = rtype; + (*way)[i]->islink = 0; + if (strstr(s,"Route")) { + (*way)[i]->isrte = 1; + switch (rtype) { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + ++p; + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+2); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + continue; + } else { + (*way)[i]->isrte=0; + } + + if (strstr(s,"End")) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + continue; + } + + + switch (type) { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; default: - GPS_Error("GPS_Input_Get_Route: Unknown protocol"); - return PROTOCOL_ERROR; - } - - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strncmp(s,"Start",5)) - return gps_errno; - - pos = ftell(inf); - n = 1; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude") || strstr(s,"Route")) - ++n; - } - fseek(inf,0L,0); - - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - for(i=0;irte_prot = rtype; - (*way)[i]->islink = 0; - if(strstr(s,"Route")) - { - (*way)[i]->isrte = 1; - switch(rtype) - { - case 200: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - break; - case 201: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - ++p; - GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+2); - break; - case 202: - p = strchr(s,':'); - p = strchr(p+1,':'); - GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); - break; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - continue; - } - else - (*way)[i]->isrte=0; - - if(strstr(s,"End")) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - continue; - } - - - switch(type) - { - case 100: - ret = GPS_Input_Get_D100(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 101: - ret = GPS_Input_Get_D101(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 102: - ret = GPS_Input_Get_D102(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 103: - ret = GPS_Input_Get_D103(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 104: - ret = GPS_Input_Get_D104(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 105: - ret = GPS_Input_Get_D105(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 106: - ret = GPS_Input_Get_D106(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 107: - ret = GPS_Input_Get_D107(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 108: - ret = GPS_Input_Get_D108(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 150: - ret = GPS_Input_Get_D150(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 151: - ret = GPS_Input_Get_D151(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 152: - ret = GPS_Input_Get_D152(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 154: - ret = GPS_Input_Get_D154(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 155: - ret = GPS_Input_Get_D155(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - default: - GPS_Error("Input_Get_Waypoints: Unknown protocol"); - return PROTOCOL_ERROR; - } - - } - - return n; + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + + } + + return n; } @@ -2057,206 +2368,241 @@ int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf) static int32 GPS_Input_Get_Route201(GPS_PWay **way, FILE *inf) { - char s[GPS_ARB_LEN]; - int32 n; - int32 type; - int32 rtype; - int32 i; - long pos; - int32 ret; - char *p; - int32 d; - - gps_errno = INPUT_ERROR; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Route Type: %d",(int *)&rtype)!=1) - return gps_errno; - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) - return gps_errno; - - - pos = ftell(inf); - n = 1; - while(strncmp(s,"End",3)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(strstr(s,"Latitude") || strstr(s,"Route") || strstr(s,"Link Class")) - ++n; - } - fseek(inf,0L,0); - - if(!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) - return MEMORY_ERROR; - for(i=0;iprot = type; - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - - for(i=0;irte_prot = rtype; - (*way)[i]->islink = 0; - if(strstr(s,"Route")) - { - (*way)[i]->isrte = 1; - switch(rtype) - { - case 200: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - break; - case 201: - p = strchr(s,':'); - p = strchr(p+1,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_num=d; - p = strchr(p+1,':'); - GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+1); - break; - case 202: - p = strchr(s,':'); - p = strchr(p+1,':'); - GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); - break; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - continue; - } - else - (*way)[i]->isrte=0; - - - - if(strstr(s,"Link Class")) - { - (*way)[i]->islink = 1; - - p = strchr(s,':'); - if(sscanf(p+1,"%d",(int *)&d)!=1) - return gps_error; - (*way)[i]->rte_link_class=d; - - if(!((*way)[i]->rte_link_class==3 || (*way)[i]->rte_link_class - ==0xff)) - { - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_String((*way)[i]->rte_link_subclass,18,s); - } - else - { - GPS_Util_Put_Short((UC *)(*way)[i]->rte_link_subclass,0); - GPS_Util_Put_Int((UC *)(*way)[i]->rte_link_subclass+2,0); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+6, - 0xffffffff); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+10, - 0xffffffff); - GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+14, - 0xffffffff); - } - - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - GPS_Input_Load_Strnull((*way)[i]->rte_link_ident,s); - - continue; - } - else - (*way)[i]->islink=0; - - - if(strstr(s,"End")) - { - GPS_Error("Get_Route201: Unexpected End"); - return INPUT_ERROR; - } - - - switch(type) - { - case 100: - ret = GPS_Input_Get_D100(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 101: - ret = GPS_Input_Get_D101(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 102: - ret = GPS_Input_Get_D102(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 103: - ret = GPS_Input_Get_D103(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 104: - ret = GPS_Input_Get_D104(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 105: - ret = GPS_Input_Get_D105(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 106: - ret = GPS_Input_Get_D106(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 107: - ret = GPS_Input_Get_D107(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 108: - ret = GPS_Input_Get_D108(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 150: - ret = GPS_Input_Get_D150(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 151: - ret = GPS_Input_Get_D151(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 152: - ret = GPS_Input_Get_D152(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 154: - ret = GPS_Input_Get_D154(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - case 155: - ret = GPS_Input_Get_D155(&((*way)[i]),inf); - if(ret<0) return gps_errno; - break; - default: - GPS_Error("Input_Get_Waypoints: Unknown protocol"); - return PROTOCOL_ERROR; - } - if(!GPS_Input_Read_Line(s,inf)) - return gps_errno; - } - - return n; + char s[GPS_ARB_LEN]; + int32 n; + int32 type; + int32 rtype; + int32 i; + long pos; + int32 ret; + char *p; + int32 d; + + gps_errno = INPUT_ERROR; + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Route Type: %d",(int *)&rtype)!=1) { + return gps_errno; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (sscanf(s,"Waypoints Type: %d",(int *)&type)!=1) { + return gps_errno; + } + + + pos = ftell(inf); + n = 1; + while (strncmp(s,"End",3)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (strstr(s,"Latitude") || strstr(s,"Route") || strstr(s,"Link Class")) { + ++n; + } + } + fseek(inf,0L,0); + + if (!(*way=(GPS_PWay *)malloc(n*sizeof(GPS_PWay *)))) { + return MEMORY_ERROR; + } + for (i=0; iprot = type; + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + + for (i=0; irte_prot = rtype; + (*way)[i]->islink = 0; + if (strstr(s,"Route")) { + (*way)[i]->isrte = 1; + switch (rtype) { + case 200: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + break; + case 201: + p = strchr(s,':'); + p = strchr(p+1,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_num=d; + p = strchr(p+1,':'); + GPS_Input_Load_String((*way)[i]->rte_cmnt,20,p+1); + break; + case 202: + p = strchr(s,':'); + p = strchr(p+1,':'); + GPS_Input_Load_Strnull((*way)[i]->rte_ident,p+1); + break; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + continue; + } else { + (*way)[i]->isrte=0; + } + + + + if (strstr(s,"Link Class")) { + (*way)[i]->islink = 1; + + p = strchr(s,':'); + if (sscanf(p+1,"%d",(int *)&d)!=1) { + return gps_error; + } + (*way)[i]->rte_link_class=d; + + if (!((*way)[i]->rte_link_class==3 || (*way)[i]->rte_link_class + ==0xff)) { + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_String((*way)[i]->rte_link_subclass,18,s); + } else { + GPS_Util_Put_Short((UC *)(*way)[i]->rte_link_subclass,0); + GPS_Util_Put_Int((UC *)(*way)[i]->rte_link_subclass+2,0); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+6, + 0xffffffff); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+10, + 0xffffffff); + GPS_Util_Put_Uint((UC *)(*way)[i]->rte_link_subclass+14, + 0xffffffff); + } + + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + GPS_Input_Load_Strnull((*way)[i]->rte_link_ident,s); + + continue; + } else { + (*way)[i]->islink=0; + } + + + if (strstr(s,"End")) { + GPS_Error("Get_Route201: Unexpected End"); + return INPUT_ERROR; + } + + + switch (type) { + case 100: + ret = GPS_Input_Get_D100(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 101: + ret = GPS_Input_Get_D101(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 102: + ret = GPS_Input_Get_D102(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 103: + ret = GPS_Input_Get_D103(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 104: + ret = GPS_Input_Get_D104(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 105: + ret = GPS_Input_Get_D105(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 106: + ret = GPS_Input_Get_D106(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 107: + ret = GPS_Input_Get_D107(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 108: + ret = GPS_Input_Get_D108(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 150: + ret = GPS_Input_Get_D150(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 151: + ret = GPS_Input_Get_D151(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 152: + ret = GPS_Input_Get_D152(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 154: + ret = GPS_Input_Get_D154(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + case 155: + ret = GPS_Input_Get_D155(&((*way)[i]),inf); + if (ret<0) { + return gps_errno; + } + break; + default: + GPS_Error("Input_Get_Waypoints: Unknown protocol"); + return PROTOCOL_ERROR; + } + if (!GPS_Input_Read_Line(s,inf)) { + return gps_errno; + } + } + + return n; } diff --git a/gpsbabel/jeeps/gpsinput.h b/gpsbabel/jeeps/gpsinput.h index 5b0e41615..b8dc1ec64 100644 --- a/gpsbabel/jeeps/gpsinput.h +++ b/gpsbabel/jeeps/gpsinput.h @@ -9,11 +9,11 @@ extern "C" #include "gps.h" -int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf); -int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf); -int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf); -int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf); -int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf); + int32 GPS_Input_Get_Almanac(GPS_PAlmanac **alm, FILE *inf); + int32 GPS_Input_Get_Waypoint(GPS_PWay **way, FILE *inf); + int32 GPS_Input_Get_Proximity(GPS_PWay **way, FILE *inf); + int32 GPS_Input_Get_Track(GPS_PTrack **trk, FILE *inf); + int32 GPS_Input_Get_Route(GPS_PWay **way, FILE *inf); #endif diff --git a/gpsbabel/jeeps/gpslibusb.c b/gpsbabel/jeeps/gpslibusb.c index ef82454b3..752b33b46 100644 --- a/gpsbabel/jeeps/gpslibusb.c +++ b/gpsbabel/jeeps/gpslibusb.c @@ -47,11 +47,11 @@ #define TMOUT_B 5000 /* Milliseconds to timeout bulk pipe access. */ typedef struct { - struct usb_bus *busses; - unsigned product_id; + struct usb_bus *busses; + unsigned product_id; } libusb_unit_data; -/* +/* * TODO: this should all be moved into libusbdata in gpslibusb.h, * allocated once here in gusb_start, and deallocated at the end. */ @@ -67,27 +67,27 @@ static const gdx_info *gdx; #if __linux__ static -char ** os_get_garmin_mountpoints() +char ** os_get_garmin_mountpoints() { - // Hacked for testing. - return NULL; + // Hacked for testing. + return NULL; } #elif __APPLE__ // In fantasy land, we'd query iokit for enumerated devices of the Garmin // vendor ID and match that against the mounted device table. In practical // matters, that's crazy complex and this is where the devices seems to always // get mounted... -char ** os_get_garmin_mountpoints() +char ** os_get_garmin_mountpoints() { - char **dlist = xcalloc(2, sizeof *dlist); - dlist[0] = xstrdup("/Volumes/GARMIN"); - dlist[1] = NULL; - return dlist; + char **dlist = xcalloc(2, sizeof *dlist); + dlist[0] = xstrdup("/Volumes/GARMIN"); + dlist[1] = NULL; + return dlist; } #else -char ** os_get_garmin_mountpoints() +char ** os_get_garmin_mountpoints() { - return NULL; + return NULL; } #endif @@ -95,64 +95,64 @@ char ** os_get_garmin_mountpoints() static int gusb_libusb_send(const garmin_usb_packet *opkt, size_t sz) { - int r; - r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_B); - - if (r != (int) sz) { - fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); - if (r < 0) { - fatal("usb_bulk_write failed. '%s'\n", - usb_strerror()); - } - } - - return r; + int r; + r = usb_bulk_write(udev, gusb_bulk_out_ep, (char *)(void *)opkt->dbuf, sz, TMOUT_B); + + if (r != (int) sz) { + fprintf(stderr, "Bad cmdsend r %d sz %ld\n", r, (unsigned long) sz); + if (r < 0) { + fatal("usb_bulk_write failed. '%s'\n", + usb_strerror()); + } + } + + return r; } static int gusb_libusb_get(garmin_usb_packet *ibuf, size_t sz) { - unsigned char *buf = &ibuf->dbuf[0]; - int r = -1; + unsigned char *buf = &ibuf->dbuf[0]; + int r = -1; - r = usb_interrupt_read(udev, gusb_intr_in_ep, (char *) buf, sz, TMOUT_I); - return r; + r = usb_interrupt_read(udev, gusb_intr_in_ep, (char *) buf, sz, TMOUT_I); + return r; } static int gusb_libusb_get_bulk(garmin_usb_packet *ibuf, size_t sz) { - int r; - unsigned char *buf = &ibuf->dbuf[0]; + int r; + unsigned char *buf = &ibuf->dbuf[0]; - r = usb_bulk_read(udev, gusb_bulk_in_ep, (char *) buf, sz, TMOUT_B); + r = usb_bulk_read(udev, gusb_bulk_in_ep, (char *) buf, sz, TMOUT_B); - return r; + return r; } static int gusb_teardown(gpsdevh *dh) { - if (udev) { - usb_release_interface(udev, 0); - usb_close(udev); - /* In the worst case, we leak a little bit of memory - * when called via the atexit handler. That's not too - * terrible. - */ - if (NULL != dh) { - xfree(dh); - } - udev = NULL; - } - return 0; + if (udev) { + usb_release_interface(udev, 0); + usb_close(udev); + /* In the worst case, we leak a little bit of memory + * when called via the atexit handler. That's not too + * terrible. + */ + if (NULL != dh) { + xfree(dh); + } + udev = NULL; + } + return 0; } static void gusb_atexit_teardown(void) { - gusb_teardown(NULL); + gusb_teardown(NULL); } @@ -164,21 +164,21 @@ gusb_atexit_teardown(void) * set. After a reset, the toggles both match. So we tear through the * conversation and life is good. Unfortunately, the second time through, * if we had an odd number of transactions in the previous conversation, - * we send a configuration set and reset the toggle on the HCI but the + * we send a configuration set and reset the toggle on the HCI but the * toggle on the device's end of the pipe is now out of whack which means * that the subsequent transaction will hang. - * + * * This isn't a problem in Windows since the configuration set is done only * once there. - * + * * This code has been tested in loops of 1000 cycles on Linux and OS/X and * it seems to cure this at a mere cost of complexity and startup time. I'll * be delighted when all the firmware gets revved and updated and we can * remove this. * - * 9/2008 But wait, there's more. The very toggle reset that we *had* to + * 9/2008 But wait, there's more. The very toggle reset that we *had* to * implement in 2006 to make non-Windows OSes work actually locks up verion - * 2.70 of the Venture HC. On that model, the second product request + * 2.70 of the Venture HC. On that model, the second product request * (you know, the one that we *use*, locks that device's protocol stack * after the RET2INTR that immediately follows the REQBLK (and why is it * telling us to go into bulk mode followed by an immeidate EOF, anyway?) @@ -190,273 +190,290 @@ gusb_atexit_teardown(void) * * Grrrr! */ -unsigned +unsigned gusb_reset_toggles(void) { - static const char oinit[12] = - {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; - static const char oid[12] = - {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int t; - unsigned rv = 0; - - /* Start off with three session starts. - * #1 resets the bulk out toggle. It may not make it to the device. - * #2 resets the the intr in toggle. It will make it to the device - * since #1 reset the the bulk out toggle. The device will - * respond on the intr in pipe which will clear its toggle. - * #3 actually starts the session now that the above are both clear. - */ - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - - t = 10; - while(1) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - break; - } - if (t-- <= 0) { - fatal("Could not start session in a reasonable number of tries.\n"); - } - } - - /* - * Now that the bulk out and intr in packets are good, we send - * a product ID. On devices that respond totally on the intr - * pipe, this does nothing interesting, but on devices that respon - * on the bulk pipe this will reset the toggles on the bulk in. - */ - - t = 10; - gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid)); - while(1) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_get(&iresp, sizeof(iresp)); - - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { - rv = le_read16(iresp.gusb_pkt.databuf+0); - } - - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return rv; - if (t-- <= 0) { - fatal("Could not start session in a reasonable number of tries.\n"); - } - } - return 0; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int t; + unsigned rv = 0; + + /* Start off with three session starts. + * #1 resets the bulk out toggle. It may not make it to the device. + * #2 resets the the intr in toggle. It will make it to the device + * since #1 reset the the bulk out toggle. The device will + * respond on the intr in pipe which will clear its toggle. + * #3 actually starts the session now that the above are both clear. + */ + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + + t = 10; + while (1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + break; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + + /* + * Now that the bulk out and intr in packets are good, we send + * a product ID. On devices that respond totally on the intr + * pipe, this does nothing interesting, but on devices that respon + * on the bulk pipe this will reset the toggles on the bulk in. + */ + + t = 10; + gusb_cmd_send((const garmin_usb_packet *) oid, sizeof(oid)); + while (1) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_get(&iresp, sizeof(iresp)); + + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + rv = le_read16(iresp.gusb_pkt.databuf+0); + } + + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) { + return rv; + } + if (t-- <= 0) { + fatal("Could not start session in a reasonable number of tries.\n"); + } + } + return 0; } void garmin_usb_start(struct usb_device *dev, libusb_unit_data *lud) { - int i; + int i; - if (udev) return; - udev = usb_open(dev); - atexit(gusb_atexit_teardown); + if (udev) { + return; + } + udev = usb_open(dev); + atexit(gusb_atexit_teardown); - if (!udev) { fatal("usb_open failed: %s\n", usb_strerror()); } - /* - * Hrmph. No iManufacturer or iProduct headers.... - */ + if (!udev) { + fatal("usb_open failed: %s\n", usb_strerror()); + } + /* + * Hrmph. No iManufacturer or iProduct headers.... + */ #if __APPLE__ - // On Leopard, if we don't do an explicit set_configuration, some - // devices will work only the first time after a reset. - if (usb_set_configuration(udev, 1) < 0) { - fatal("usb_set_configuration failed: %s\n", usb_strerror()); - }; + // On Leopard, if we don't do an explicit set_configuration, some + // devices will work only the first time after a reset. + if (usb_set_configuration(udev, 1) < 0) { + fatal("usb_set_configuration failed: %s\n", usb_strerror()); + }; #endif #if 0 - if (usb_set_configuration(udev, 1) < 0) { + if (usb_set_configuration(udev, 1) < 0) { #if __linux__ - char drvnm[128]; - drvnm[0] = 0; - /* - * Most Linux distributions ship a slightly broken - * kernel driver that bonds with the hardware. - */ - usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); - fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" - "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); + char drvnm[128]; + drvnm[0] = 0; + /* + * Most Linux distributions ship a slightly broken + * kernel driver that bonds with the hardware. + */ + usb_get_driver_np(udev, 0, drvnm, sizeof(drvnm)-1); + fatal("usb_set_configuration failed, probably because kernel driver '%s'\n is blocking our access to the USB device.\n" + "For more information see http://www.gpsbabel.org/os/Linux_Hotplug.html\n", drvnm); #else - fatal("usb_set_configuration failed: %s\n", usb_strerror()); + fatal("usb_set_configuration failed: %s\n", usb_strerror()); #endif - } + } #endif - if (usb_claim_interface(udev, 0) < 0) { - fatal("Claim interfaced failed: %s\n", usb_strerror()); - } - - libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; - - /* - * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac - * with Venture HC) we get a dev with a valid vendor ID, but no - * associated configuration. I was unable to see a single instance - * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading - * me to think this is some kind of bug in the Venture HC. - * - * Rather than crash, we at least print - * a nastygram. Experiments with retrying various USB ops brought - * no joy, so just call fatal and move on. - */ - if (!dev->config) { - fatal("Found USB device with no configuration.\n"); - } - - for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { - struct usb_endpoint_descriptor * ep; - ep = &dev->config->interface->altsetting->endpoint[i]; - - switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { + if (usb_claim_interface(udev, 0) < 0) { + fatal("Claim interfaced failed: %s\n", usb_strerror()); + } + + libusb_llops.max_tx_size = dev->descriptor.bMaxPacketSize0; + + /* + * About 5% of the time on OS/X (Observed on 10.5.4 on Intel Imac + * with Venture HC) we get a dev with a valid vendor ID, but no + * associated configuration. I was unable to see a single instance + * of this on a 276, a 60CS, a 60CSx, an SP310, or an Edge 305, leading + * me to think this is some kind of bug in the Venture HC. + * + * Rather than crash, we at least print + * a nastygram. Experiments with retrying various USB ops brought + * no joy, so just call fatal and move on. + */ + if (!dev->config) { + fatal("Found USB device with no configuration.\n"); + } + + for (i = 0; i < dev->config->interface->altsetting->bNumEndpoints; i++) { + struct usb_endpoint_descriptor * ep; + ep = &dev->config->interface->altsetting->endpoint[i]; + + switch (ep->bmAttributes & USB_ENDPOINT_TYPE_MASK) { #define EA(x) x & USB_ENDPOINT_ADDRESS_MASK - case USB_ENDPOINT_TYPE_BULK: - if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; - else - gusb_bulk_out_ep = EA(ep->bEndpointAddress); - break; - case USB_ENDPOINT_TYPE_INTERRUPT: - if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) - gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; - break; - } - } - - /* - * Zero is the configuration endpoint, so if we made it through - * that loop without non-zero values for all three, we're hosed. - */ - if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { - lud->product_id = gusb_reset_toggles(); - switch (lud->product_id) { - // Search for "Venture HC" for more on this siliness.. - // It's a case instead of an 'if' becuase I have a - // feeling there are more affected models either - // on the market or on the way. - case 695: break; // Venture HC - case 941: break; // Venture HC, Japanese version. - case 957: break; // Legend H - case 285: break; // GPSMap 276C/4.80 - case 402: break; // GPSMap 396C/4.50 - case 1095: break; // GPS72H/2.30 - default: gusb_syncup(); - } - return; - } - - fatal("Could not identify endpoints on USB device.\n" - "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", - gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); + case USB_ENDPOINT_TYPE_BULK: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + gusb_bulk_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; + } else { + gusb_bulk_out_ep = EA(ep->bEndpointAddress); + } + break; + case USB_ENDPOINT_TYPE_INTERRUPT: + if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + gusb_intr_in_ep = (EA(ep->bEndpointAddress)) | USB_ENDPOINT_IN; + } + break; + } + } + + /* + * Zero is the configuration endpoint, so if we made it through + * that loop without non-zero values for all three, we're hosed. + */ + if (gusb_intr_in_ep && gusb_bulk_in_ep && gusb_bulk_out_ep) { + lud->product_id = gusb_reset_toggles(); + switch (lud->product_id) { + // Search for "Venture HC" for more on this siliness.. + // It's a case instead of an 'if' becuase I have a + // feeling there are more affected models either + // on the market or on the way. + case 695: + break; // Venture HC + case 941: + break; // Venture HC, Japanese version. + case 957: + break; // Legend H + case 285: + break; // GPSMap 276C/4.80 + case 402: + break; // GPSMap 396C/4.50 + case 1095: + break; // GPS72H/2.30 + default: + gusb_syncup(); + } + return; + } + + fatal("Could not identify endpoints on USB device.\n" + "Found endpoints Intr In 0x%x Bulk Out 0x%x Bulk In %0xx\n", + gusb_intr_in_ep, gusb_bulk_out_ep, gusb_bulk_in_ep); } static int garmin_usb_scan(libusb_unit_data *lud, int req_unit_number) { - int found_devices = 0; - struct usb_bus *bus; - - for (bus = lud->busses; bus; bus = bus->next) { - struct usb_device *dev; - - for (dev = bus->devices; dev; dev = dev->next) { - /* - * Exclude Mass Storage devices (CO, OR, Nuvi, etc.) - * from this scan. - * At least on Mac, bDeviceClass isn't - * USB_MASS_STORAGE as it should be (perhaps because - * the storage driver has already bound to it?) so - * we fondle only the proprietary class devices. - */ - if (dev->descriptor.idVendor == GARMIN_VID && - dev->config && - dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC ) { - if (req_unit_number < 0) { - garmin_usb_start(dev, lud); - /* - * It's important to call _close - * here since the bulk/intr models - * may have a "dangling" packet that - * needs to be drained. - */ - gusb_close(NULL); - } else - if (req_unit_number == found_devices) - garmin_usb_start(dev, lud); - found_devices++; - } - } - } - - if (req_unit_number < 0) { - gusb_list_units(); - exit (0); - } - - if (0 == found_devices) { - /* It's time for Plan B. The user told us to use - * Garmin Protocol in device "usb:" but it's possible - * that they're talking to one of the dozens of models - * that is wants to read and write GPX files on a - * mounted drive. Try that now. - */ - char **dlist = os_get_garmin_mountpoints(); - gdx = gdx_find_file(dlist); - if (gdx) return 1; - /* Plan C. */ - fatal("Found no Garmin USB devices.\n"); - } else { - return 1; + int found_devices = 0; + struct usb_bus *bus; + + for (bus = lud->busses; bus; bus = bus->next) { + struct usb_device *dev; + + for (dev = bus->devices; dev; dev = dev->next) { + /* + * Exclude Mass Storage devices (CO, OR, Nuvi, etc.) + * from this scan. + * At least on Mac, bDeviceClass isn't + * USB_MASS_STORAGE as it should be (perhaps because + * the storage driver has already bound to it?) so + * we fondle only the proprietary class devices. + */ + if (dev->descriptor.idVendor == GARMIN_VID && + dev->config && + dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC) { + if (req_unit_number < 0) { + garmin_usb_start(dev, lud); + /* + * It's important to call _close + * here since the bulk/intr models + * may have a "dangling" packet that + * needs to be drained. + */ + gusb_close(NULL); + } else if (req_unit_number == found_devices) { + garmin_usb_start(dev, lud); } + found_devices++; + } + } + } + + if (req_unit_number < 0) { + gusb_list_units(); + exit(0); + } + + if (0 == found_devices) { + /* It's time for Plan B. The user told us to use + * Garmin Protocol in device "usb:" but it's possible + * that they're talking to one of the dozens of models + * that is wants to read and write GPX files on a + * mounted drive. Try that now. + */ + char **dlist = os_get_garmin_mountpoints(); + gdx = gdx_find_file(dlist); + if (gdx) { + return 1; + } + /* Plan C. */ + fatal("Found no Garmin USB devices.\n"); + } else { + return 1; + } } static gusb_llops_t libusb_llops = { - gusb_libusb_get, - gusb_libusb_get_bulk, - gusb_libusb_send, - gusb_teardown + gusb_libusb_get, + gusb_libusb_get_bulk, + gusb_libusb_send, + gusb_teardown }; int gusb_init(const char *portname, gpsdevh **dh) { - int req_unit_number = 0; - libusb_unit_data *lud = xcalloc(sizeof (libusb_unit_data), 1); + int req_unit_number = 0; + libusb_unit_data *lud = xcalloc(sizeof(libusb_unit_data), 1); - *dh = (gpsdevh*) lud; + *dh = (gpsdevh*) lud; // usb_set_debug(99); - usb_init(); - gusb_register_ll(&libusb_llops); - - /* if "usb:N", read "N" to be the unit number. */ - if (strlen(portname) > 4) { - if (0 == strcmp(portname+4, "list")) { - req_unit_number = -1; - } else { - req_unit_number = atoi(portname + 4); - } - } - usb_find_busses(); - usb_find_devices(); - lud->busses = usb_get_busses(); - return garmin_usb_scan(lud, req_unit_number); + usb_init(); + gusb_register_ll(&libusb_llops); + + /* if "usb:N", read "N" to be the unit number. */ + if (strlen(portname) > 4) { + if (0 == strcmp(portname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(portname + 4); + } + } + usb_find_busses(); + usb_find_devices(); + lud->busses = usb_get_busses(); + return garmin_usb_scan(lud, req_unit_number); } #endif /* HAVE_LIBUSB */ diff --git a/gpsbabel/jeeps/gpsmath.c b/gpsbabel/jeeps/gpsmath.c index 6a5ee3df2..a26f8f0c8 100644 --- a/gpsbabel/jeeps/gpsmath.c +++ b/gpsbabel/jeeps/gpsmath.c @@ -2,20 +2,20 @@ ** @source JEEPS arithmetic/conversion functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -29,10 +29,10 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, - char *zc, double *Mc, double *E0, - double *N0, double *F0); + char *zc, double *Mc, double *E0, + double *N0, double *F0); static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, - double *E0, double *N0, double *F0); + double *E0, double *N0, double *F0); @@ -47,7 +47,7 @@ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, double GPS_Math_Deg_To_Rad(double v) { - return v*(double)((double)GPS_PI/(double)180.); + return v*(double)((double)GPS_PI/(double)180.); } @@ -63,7 +63,7 @@ double GPS_Math_Deg_To_Rad(double v) double GPS_Math_Rad_To_Deg(double v) { - return v*(double)((double)180./(double)GPS_PI); + return v*(double)((double)180./(double)GPS_PI); } @@ -81,28 +81,27 @@ double GPS_Math_Rad_To_Deg(double v) void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m) { - int32 sign; - - if(v<(double)0.) - { - v *= (double)-1.; - sign = 1; - } - else - sign = 0; - - *d = (int32)v; - *m = (v-(double)*d) * (double)60.0; - if(*m>(double)59.999) - { - ++*d; - *m = (double)0.0; - } - - if(sign) - *d = -*d; - - return; + int32 sign; + + if (v<(double)0.) { + v *= (double)-1.; + sign = 1; + } else { + sign = 0; + } + + *d = (int32)v; + *m = (v-(double)*d) * (double)60.0; + if (*m>(double)59.999) { + ++*d; + *m = (double)0.0; + } + + if (sign) { + *d = -*d; + } + + return; } @@ -121,11 +120,12 @@ void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m) void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg) { - *deg = ((double)abs(d)) + m / (double)60.0; - if(d<0) - *deg = -*deg; + *deg = ((double)abs(d)) + m / (double)60.0; + if (d<0) { + *deg = -*deg; + } - return; + return; } @@ -144,41 +144,39 @@ void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg) void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) { - int32 sign; - double t; - - if(v<(double)0.) - { - v *= (double)-1.; - sign = 1; - } - else - sign = 0; - - *d = (int32)v; - t = (v -(double)*d) * (double)60.0; - *m = (v-(double)*d) * (double)60.0; - *s = (t - (int32)t) * (double)60.0; - - if(*s>(double)59.999) - { - ++t; - *s = (double)0.0; - } + int32 sign; + double t; - - if(t>(double)59.999) - { - ++*d; - t = 0; - } + if (v<(double)0.) { + v *= (double)-1.; + sign = 1; + } else { + sign = 0; + } + + *d = (int32)v; + t = (v -(double)*d) * (double)60.0; + *m = (v-(double)*d) * (double)60.0; + *s = (t - (int32)t) * (double)60.0; + + if (*s>(double)59.999) { + ++t; + *s = (double)0.0; + } - *m = (int32)t; - if(sign) - *d = -*d; + if (t>(double)59.999) { + ++*d; + t = 0; + } - return; + *m = (int32)t; + + if (sign) { + *d = -*d; + } + + return; } @@ -198,18 +196,19 @@ void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s) void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) { - *deg = ((double)abs(d)) + ((double)m + s / (double)60.0) / (double)60.0; - if(d<0) - *deg = -*deg; + *deg = ((double)abs(d)) + ((double)m + s / (double)60.0) / (double)60.0; + if (d<0) { + *deg = -*deg; + } - return; + return; } /* @func GPS_Math_Metres_To_Feet ******************************************* ** -** Convert metres to feet +** Convert metres to feet ** ** @param [r] v [double] metres ** @@ -218,7 +217,7 @@ void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg) double GPS_Math_Metres_To_Feet(double v) { - return v/0.3048; + return v/0.3048; } @@ -234,7 +233,7 @@ double GPS_Math_Metres_To_Feet(double v) double GPS_Math_Feet_To_Metres(double v) { - return v * 0.3048; + return v * 0.3048; } @@ -250,7 +249,7 @@ double GPS_Math_Feet_To_Metres(double v) int32 GPS_Math_Deg_To_Semi(double v) { - return ( (double)(1U<<31) / (double)180) * v; + return ((double)(1U<<31) / (double)180) * v; } @@ -266,7 +265,7 @@ int32 GPS_Math_Deg_To_Semi(double v) double GPS_Math_Semi_To_Deg(int32 v) { - return (double) (((double)v / (double)(1U<<31)) * (double)180); + return (double)(((double)v / (double)(1U<<31)) * (double)180); } @@ -282,7 +281,7 @@ double GPS_Math_Semi_To_Deg(int32 v) time_t GPS_Math_Utime_To_Gtime(time_t v) { - return v-631065600; + return v-631065600; } @@ -298,7 +297,7 @@ time_t GPS_Math_Utime_To_Gtime(time_t v) time_t GPS_Math_Gtime_To_Utime(time_t v) { - return v+631065600; + return v+631065600; } @@ -321,24 +320,24 @@ time_t GPS_Math_Gtime_To_Utime(time_t v) ** @return [void] ************************************************************************/ void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z, - double a, double b) + double *x, double *y, double *z, + double a, double b) { - double esq; - double nu; + double esq; + double nu; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - - esq = ((a*a)-(b*b)) / (a*a); - - nu = a / pow(((double)1.0-esq*sin(phi)*sin(phi)),(double)0.5); - *x = (nu+H) * cos(phi) * cos(lambda); - *y = (nu+H) * cos(phi) * sin(lambda); - *z = (((double)1.0-esq)*nu+H) * sin(phi); + esq = ((a*a)-(b*b)) / (a*a); - return; + nu = a / pow(((double)1.0-esq*sin(phi)*sin(phi)),(double)0.5); + *x = (nu+H) * cos(phi) * cos(lambda); + *y = (nu+H) * cos(phi) * sin(lambda); + *z = (((double)1.0-esq)*nu+H) * sin(phi); + + return; } @@ -360,40 +359,47 @@ void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, ** @return [void] ************************************************************************/ void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z, - double a, double b) + double x, double y, double z, + double a, double b) { - double esq; - double nu=0.0; - double phix; - double nphi; - double rho; - int32 t1=0; - int32 t2=0; - - if(x<(double)0 && y>=(double)0) t1=1; - if(x<(double)0 && y<(double)0) t2=1; - - rho = pow(((x*x)+(y*y)),(double)0.5); - esq = ((a*a)-(b*b)) / (a*a); - phix = atan(z/(((double)1.0 - esq) * rho)); - nphi = (double)1e20; - - while(fabs(phix-nphi)>(double)0.00000000001) - { - nphi = phix; - nu = a / pow(((double)1.0-esq*sin(nphi)*sin(nphi)),(double)0.5); - phix = atan((z+esq*nu*sin(nphi))/rho); - } - - *phi = GPS_Math_Rad_To_Deg(phix); - *H = (rho / cos(phix)) - nu; - *lambda = GPS_Math_Rad_To_Deg(atan(y/x)); - - if(t1) *lambda += (double)180.0; - if(t2) *lambda -= (double)180.0; - - return; + double esq; + double nu=0.0; + double phix; + double nphi; + double rho; + int32 t1=0; + int32 t2=0; + + if (x<(double)0 && y>=(double)0) { + t1=1; + } + if (x<(double)0 && y<(double)0) { + t2=1; + } + + rho = pow(((x*x)+(y*y)),(double)0.5); + esq = ((a*a)-(b*b)) / (a*a); + phix = atan(z/(((double)1.0 - esq) * rho)); + nphi = (double)1e20; + + while (fabs(phix-nphi)>(double)0.00000000001) { + nphi = phix; + nu = a / pow(((double)1.0-esq*sin(nphi)*sin(nphi)),(double)0.5); + phix = atan((z+esq*nu*sin(nphi))/rho); + } + + *phi = GPS_Math_Rad_To_Deg(phix); + *H = (rho / cos(phix)) - nu; + *lambda = GPS_Math_Rad_To_Deg(atan(y/x)); + + if (t1) { + *lambda += (double)180.0; + } + if (t2) { + *lambda -= (double)180.0; + } + + return; } @@ -413,14 +419,14 @@ void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, ** @return [void] ************************************************************************/ void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z) + double *x, double *y, double *z) { - double a = 6377563.396; - double b = 6356256.910; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -440,14 +446,14 @@ void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, ** @return [void] ************************************************************************/ void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z) + double *x, double *y, double *z) { - double a = 6378137.000; - double b = 6356752.3141; + double a = 6378137.000; + double b = 6356752.3141; - GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); + GPS_Math_LatLonH_To_XYZ(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -467,14 +473,14 @@ void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, ** @return [void] ************************************************************************/ void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z) + double x, double y, double z) { - double a = 6377563.396; - double b = 6356256.910; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -493,14 +499,14 @@ void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, ** @return [void] ************************************************************************/ void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z) + double x, double y, double z) { - double a = 6378137.000; - double b = 66356752.3141; + double a = 6378137.000; + double b = 66356752.3141; - GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); + GPS_Math_XYZ_To_LatLonH(phi,lambda,H,x,y,z,a,b); - return; + return; } @@ -524,87 +530,87 @@ void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, ** @return [void] ************************************************************************/ void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, - double lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b) + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) { - double esq; - double n; - double etasq; - double nu; - double rho; - double M; - double I; - double II; - double III; - double IIIA; - double IV; - double V; - double VI; - - double tmp; - double tmp2; - double fdf; - double fde; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - - esq = ((a*a)-(b*b)) / (a*a); - n = (a-b) / (a+b); - - tmp = (double)1.0 - (esq * sin(phi) * sin(phi)); - nu = a * F0 * pow(tmp,(double)-0.5); - rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); - etasq = (nu / rho) - (double)1.0; - - fdf = (double)5.0 / (double)4.0; - tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); - tmp *= (phi - phi0); - tmp2 = (double)3.0*n + (double)3.0*n*n + ((double)21./(double)8.)*n*n*n; - tmp2 *= (sin(phi-phi0) * cos(phi+phi0)); - tmp -= tmp2; - - fde = ((double)15.0 / (double)8.0); - tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (phi-phi0)); - tmp2 *= cos((double)2.0 * (phi+phi0)); - tmp += tmp2; - - tmp2 = ((double)35.0/(double)24.0) * n * n * n; - tmp2 *= sin((double)3.0 * (phi-phi0)); - tmp2 *= cos((double)3.0 * (phi+phi0)); - tmp -= tmp2; - - M = b * F0 * tmp; - I = M + N0; - II = (nu / (double)2.0) * sin(phi) * cos(phi); - III = (nu / (double)24.0) * sin(phi) * cos(phi) * cos(phi) * cos(phi); - III *= ((double)5.0 - (tan(phi) * tan(phi)) + ((double)9.0 * etasq)); - IIIA = (nu / (double)720.0) * sin(phi) * pow(cos(phi),(double)5.0); - IIIA *= ((double)61.0 - ((double)58.0*tan(phi)*tan(phi)) + - pow(tan(phi),(double)4.0)); - IV = nu * cos(phi); - - tmp = pow(cos(phi),(double)3.0); - tmp *= ((nu/rho) - tan(phi) * tan(phi)); - V = (nu/(double)6.0) * tmp; - - tmp = (double)5.0 - ((double)18.0 * tan(phi) * tan(phi)); - tmp += tan(phi)*tan(phi)*tan(phi)*tan(phi) + ((double)14.0 * etasq); - tmp -= ((double)58.0 * tan(phi) * tan(phi) * etasq); - tmp2 = cos(phi)*cos(phi)*cos(phi)*cos(phi)*cos(phi) * tmp; - VI = (nu / (double)120.0) * tmp2; - - *N = I + II*(lambda-lambda0)*(lambda-lambda0) + - III*pow((lambda-lambda0),(double)4.0) + - IIIA*pow((lambda-lambda0),(double)6.0); - - *E = E0 + IV*(lambda-lambda0) + V*pow((lambda-lambda0),(double)3.0) + - VI * pow((lambda-lambda0),(double)5.0); - - return; + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double I; + double II; + double III; + double IIIA; + double IV; + double V; + double VI; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + + esq = ((a*a)-(b*b)) / (a*a); + n = (a-b) / (a+b); + + tmp = (double)1.0 - (esq * sin(phi) * sin(phi)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + fdf = (double)5.0 / (double)4.0; + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (phi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(phi-phi0) * cos(phi+phi0)); + tmp -= tmp2; + + fde = ((double)15.0 / (double)8.0); + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (phi-phi0)); + tmp2 *= cos((double)2.0 * (phi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (phi-phi0)); + tmp2 *= cos((double)3.0 * (phi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + I = M + N0; + II = (nu / (double)2.0) * sin(phi) * cos(phi); + III = (nu / (double)24.0) * sin(phi) * cos(phi) * cos(phi) * cos(phi); + III *= ((double)5.0 - (tan(phi) * tan(phi)) + ((double)9.0 * etasq)); + IIIA = (nu / (double)720.0) * sin(phi) * pow(cos(phi),(double)5.0); + IIIA *= ((double)61.0 - ((double)58.0*tan(phi)*tan(phi)) + + pow(tan(phi),(double)4.0)); + IV = nu * cos(phi); + + tmp = pow(cos(phi),(double)3.0); + tmp *= ((nu/rho) - tan(phi) * tan(phi)); + V = (nu/(double)6.0) * tmp; + + tmp = (double)5.0 - ((double)18.0 * tan(phi) * tan(phi)); + tmp += tan(phi)*tan(phi)*tan(phi)*tan(phi) + ((double)14.0 * etasq); + tmp -= ((double)58.0 * tan(phi) * tan(phi) * etasq); + tmp2 = cos(phi)*cos(phi)*cos(phi)*cos(phi)*cos(phi) * tmp; + VI = (nu / (double)120.0) * tmp2; + + *N = I + II*(lambda-lambda0)*(lambda-lambda0) + + III*pow((lambda-lambda0),(double)4.0) + + IIIA*pow((lambda-lambda0),(double)6.0); + + *E = E0 + IV*(lambda-lambda0) + V*pow((lambda-lambda0),(double)3.0) + + VI * pow((lambda-lambda0),(double)5.0); + + return; } @@ -622,19 +628,19 @@ void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, ** @return [void] ************************************************************************/ void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, - double *N) + double *N) { - double N0 = 250000; - double E0 = 200000; - double F0 = 1.000035; - double phi0 = 53.5; - double lambda0 = -8.; - double a = 6377340.189; - double b = 6356034.447; + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - return; + return; } @@ -653,25 +659,25 @@ void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, - double *N) + double *N) { - double N0 = -100000; - double E0 = 400000; - double F0 = 0.9996012717; - double phi0 = 49.; - double lambda0 = -2.; - double a = 6377563.396; - double b = 6356256.910; + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - return; + return; } /* @func int32 GPS_Math_WGS84_To_Swiss_EN ****************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Swiss CH-1903 National Grid Eastings and Northings ** ( Oblique Mercator Projection ) ** @@ -684,30 +690,34 @@ void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, ************************************************************************/ int32 GPS_Math_WGS84_To_Swiss_EN(double lat, double lon, double *E, - double *N) + double *N) { - const double phi0 = 46.95240556; - const double lambda0 = 7.43958333; - const double E0 = 600000.0; - const double N0 = 200000.0; - double phi, lambda, alt, a, b; - - if (lat < 44.89022757) return 0; - if (lon < -0.16386312) return 0; - - a = GPS_Ellipse[4].a; - b = a - (a / GPS_Ellipse[4].invf); - - GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, 123); - GPS_Math_Swiss_LatLon_To_EN(phi, lambda, E, N, phi0, lambda0, E0, N0, a, b); - - return 1; + const double phi0 = 46.95240556; + const double lambda0 = 7.43958333; + const double E0 = 600000.0; + const double N0 = 200000.0; + double phi, lambda, alt, a, b; + + if (lat < 44.89022757) { + return 0; + } + if (lon < -0.16386312) { + return 0; + } + + a = GPS_Ellipse[4].a; + b = a - (a / GPS_Ellipse[4].invf); + + GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, 123); + GPS_Math_Swiss_LatLon_To_EN(phi, lambda, E, N, phi0, lambda0, E0, N0, a, b); + + return 1; } /* @GPS_Math_Swiss_EN_To_WGS84 ***************************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Swiss CH-1903 National Grid Eastings and Northings ** ** @param [r] E [double] Swiss-NG easting (metres) @@ -719,17 +729,17 @@ int32 GPS_Math_WGS84_To_Swiss_EN(double lat, double lon, double *E, ************************************************************************/ void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon) { - const double phi0 = 46.95240556; - const double lambda0 = 7.43958333; - const double E0 = 600000.0; - const double N0 = 200000.0; - double phi, lambda, alt, a, b; - - a = GPS_Ellipse[4].a; - b = a - (a / GPS_Ellipse[4].invf); - - GPS_Math_Swiss_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, E0, N0, a, b); - GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, 123); + const double phi0 = 46.95240556; + const double lambda0 = 7.43958333; + const double E0 = 600000.0; + const double N0 = 200000.0; + double phi, lambda, alt, a, b; + + a = GPS_Ellipse[4].a; + b = a - (a / GPS_Ellipse[4].invf); + + GPS_Math_Swiss_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, E0, N0, a, b); + GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, 123); } @@ -752,126 +762,128 @@ void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon) ** @return [void] ************************************************************************/ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) + double *N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double phis; - double phic; - double phit; - double phis2; - double phis4; - double phis6; - double RD; - double dlam; - double NN; - double TT; - double WW; - double WW2; - double WW3; - double WW4; - double WW5; - double CC; - double MM; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - phic = cos(phi); - phit = tan(phi); - RD = pow((double)1.-e2*phis*phis,(double).5); - NN = a/RD; - TT = phit*phit; - WW = dlam*phic; - WW2 = WW*WW; - WW3 = WW*WW2; - WW4 = WW*WW3; - WW5 = WW*WW4; - CC = e2*phic*phic/om0; - lat = c0*phi; - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (lat-phis2+phis4-phis6); - - *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* - (TT*WW5/(double)120.)) + E0; - *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * - WW4/(double)24.) + N0; - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double phis; + double phic; + double phit; + double phis2; + double phis4; + double phis6; + double RD; + double dlam; + double NN; + double TT; + double WW; + double WW2; + double WW3; + double WW4; + double WW5; + double CC; + double MM; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + phit = tan(phi); + RD = pow((double)1.-e2*phis*phis,(double).5); + NN = a/RD; + TT = phit*phit; + WW = dlam*phic; + WW2 = WW*WW; + WW3 = WW*WW2; + WW4 = WW*WW3; + WW5 = WW*WW4; + CC = e2*phic*phic/om0; + lat = c0*phi; + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (lat-phis2+phis4-phis6); + + *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* + (TT*WW5/(double)120.)) + E0; + *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * + WW4/(double)24.) + N0; + return; } @@ -896,161 +908,160 @@ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double mu; - double mus2; - double mus4; - double mus6; - double mus8; - double M1; - double phi1; - double phi1s; - double phi1c; - double phi1t; - double T; - double T1; - double N1; - double R1; - double RD; - double DD; - double D2; - double D3; - double D4; - double D5; - double tol; - - M0 = GPS_Math_Deg_To_Rad(M0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - - tol = (double)1.e-5; - - dx = E - E0; - dy = N - N0; - M1 = AM0 + dy; - mu = M1 / (a*c0); - mus2 = A0 * sin((double)2.*mu); - mus4 = A1 * sin((double)4.*mu); - mus6 = A2 * sin((double)6.*mu); - mus8 = A3 * sin((double)8.*mu); - phi1 = mu + mus2 + mus4 + mus6 + mus8; - - if((((po2-tol)po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; } - else if((((-po2-tol)GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; } - else - { - phi1s = sin(phi1); - phi1c = cos(phi1); - phi1t = tan(phi1); - T1 = phi1t*phi1t; - RD = pow((double)1.-e2*phi1s*phi1s,(double).5); - N1 = a/RD; - R1 = N1 * om0 / (RD*RD); - DD = dx/N1; - D2 = DD*DD; - D3 = DD*D2; - D4 = DD*D3; - D5 = DD*D4; - T = (double)1. + (double)3.*T1; - *phi = phi1-(N1*phi1t/R1)*(D2/(double)2.-T*D4/(double)24.); - *lambda = M0+(DD-T1*D3/(double)3.+T*T1*D5/(double)15.)/phi1c; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -1058,7 +1069,7 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, /* @func int32 GPS_Math_WGS84_To_ICS_EN ****************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Israeli old Grid Eastings and Northings ** ( Israeli Cassini Soldner ) ** @@ -1071,31 +1082,31 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, ************************************************************************/ int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, - double *N) + double *N) { - double const phi0 = 31.73409694444; // 31 44 2.749 - double const lambda0 = 35.21208055556; // 35 12 43.49 - double const E0 = 170251.555; - double const N0 = 1126867.909; - double phi, lambda, alt, a, b; - - int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); - int32 ellipse = GPS_Datum[datum].ellipse; - - a = GPS_Ellipse[ellipse].a; - b = a - (a / GPS_Ellipse[ellipse].invf); - - GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, datum); - GPS_Math_Cassini_LatLon_To_EN(phi, lambda, E, N, - phi0, lambda0, E0, N0, a, b); - - return 1; + double const phi0 = 31.73409694444; // 31 44 2.749 + double const lambda0 = 35.21208055556; // 35 12 43.49 + double const E0 = 170251.555; + double const N0 = 1126867.909; + double phi, lambda, alt, a, b; + + int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); + int32 ellipse = GPS_Datum[datum].ellipse; + + a = GPS_Ellipse[ellipse].a; + b = a - (a / GPS_Ellipse[ellipse].invf); + + GPS_Math_WGS84_To_Known_Datum_M(lat, lon, 0, &phi, &lambda, &alt, datum); + GPS_Math_Cassini_LatLon_To_EN(phi, lambda, E, N, + phi0, lambda0, E0, N0, a, b); + + return 1; } /* @GPS_Math_ICS_EN_To_WGS84 ***************************************** ** -** Convert WGS84 latitude and longitude to +** Convert WGS84 latitude and longitude to ** Israeli Oldl Grid Eastings and Northings ** ** @param [r] E [double] ICS easting (metres) @@ -1107,20 +1118,20 @@ int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, ************************************************************************/ void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon) { - double const phi0 = 31.73409694444; // 31 44 2.749 - double const lambda0 = 35.21208055556; // 35 12 43.49 - double const E0 = 170251.555; - double const N0 = 1126867.909; - double phi, lambda, alt, a, b; - int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); - int32 ellipse = GPS_Datum[datum].ellipse; - - a = GPS_Ellipse[ellipse].a; - b = a - (a / GPS_Ellipse[ellipse].invf); - - GPS_Math_Cassini_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, - E0, N0, a, b); - GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, datum); + double const phi0 = 31.73409694444; // 31 44 2.749 + double const lambda0 = 35.21208055556; // 35 12 43.49 + double const E0 = 170251.555; + double const N0 = 1126867.909; + double phi, lambda, alt, a, b; + int32 datum = GPS_Lookup_Datum_Index("Palestine 1923"); + int32 ellipse = GPS_Datum[datum].ellipse; + + a = GPS_Ellipse[ellipse].a; + b = a - (a / GPS_Ellipse[ellipse].invf); + + GPS_Math_Cassini_EN_To_LatLon(E, N, &phi, &lambda, phi0, lambda0, + E0, N0, a, b); + GPS_Math_Known_Datum_To_WGS84_M(phi, lambda, 0, lat, lon, &alt, datum); } @@ -1144,114 +1155,114 @@ void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon) ** @return [void] ************************************************************************/ void GPS_Math_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b) + double *lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b) { - double esq; - double n; - double etasq; - double nu; - double rho; - double M; - double VII; - double VIII; - double IX; - double X; - double XI; - double XII; - double XIIA; - double phix; - double nphi=0.0; - - double tmp; - double tmp2; - double fdf; - double fde; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - n = (a-b) / (a+b); - fdf = (double)5.0 / (double)4.0; - fde = ((double)15.0 / (double)8.0); - - esq = ((a*a)-(b*b)) / (a*a); - - - phix = ((N-N0)/(a*F0)) + phi0; - - tmp = (double)1.0 - (esq * sin(phix) * sin(phix)); - nu = a * F0 * pow(tmp,(double)-0.5); - rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); - etasq = (nu / rho) - (double)1.0; - - M = (double)-1e20; - - while(N-N0-M > (double)0.000001) - { - nphi = phix; - - tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); - tmp *= (nphi - phi0); - tmp2 = (double)3.0*n + (double)3.0*n*n + - ((double)21./(double)8.)*n*n*n; - tmp2 *= (sin(nphi-phi0) * cos(nphi+phi0)); - tmp -= tmp2; - - - tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (nphi-phi0)); - tmp2 *= cos((double)2.0 * (nphi+phi0)); - tmp += tmp2; - - tmp2 = ((double)35.0/(double)24.0) * n * n * n; - tmp2 *= sin((double)3.0 * (nphi-phi0)); - tmp2 *= cos((double)3.0 * (nphi+phi0)); - tmp -= tmp2; - - M = b * F0 * tmp; - - if(N-N0-M > (double)0.000001) - phix = ((N-N0-M)/(a*F0)) + nphi; + double esq; + double n; + double etasq; + double nu; + double rho; + double M; + double VII; + double VIII; + double IX; + double X; + double XI; + double XII; + double XIIA; + double phix; + double nphi=0.0; + + double tmp; + double tmp2; + double fdf; + double fde; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + n = (a-b) / (a+b); + fdf = (double)5.0 / (double)4.0; + fde = ((double)15.0 / (double)8.0); + + esq = ((a*a)-(b*b)) / (a*a); + + + phix = ((N-N0)/(a*F0)) + phi0; + + tmp = (double)1.0 - (esq * sin(phix) * sin(phix)); + nu = a * F0 * pow(tmp,(double)-0.5); + rho = a * F0 * ((double)1.0 - esq) * pow(tmp,(double)-1.5); + etasq = (nu / rho) - (double)1.0; + + M = (double)-1e20; + + while (N-N0-M > (double)0.000001) { + nphi = phix; + + tmp = (double)1.0 + n + (fdf * n * n) + (fdf * n * n * n); + tmp *= (nphi - phi0); + tmp2 = (double)3.0*n + (double)3.0*n*n + + ((double)21./(double)8.)*n*n*n; + tmp2 *= (sin(nphi-phi0) * cos(nphi+phi0)); + tmp -= tmp2; + + + tmp2 = ((fde*n*n) + (fde*n*n*n)) * sin((double)2.0 * (nphi-phi0)); + tmp2 *= cos((double)2.0 * (nphi+phi0)); + tmp += tmp2; + + tmp2 = ((double)35.0/(double)24.0) * n * n * n; + tmp2 *= sin((double)3.0 * (nphi-phi0)); + tmp2 *= cos((double)3.0 * (nphi+phi0)); + tmp -= tmp2; + + M = b * F0 * tmp; + + if (N-N0-M > (double)0.000001) { + phix = ((N-N0-M)/(a*F0)) + nphi; } - + } + - VII = tan(nphi) / ((double)2.0 * rho * nu); + VII = tan(nphi) / ((double)2.0 * rho * nu); - tmp = (double)5.0 + (double)3.0 * tan(nphi) * tan(nphi) + etasq; - tmp -= (double)9.0 * tan(nphi) * tan(nphi) * etasq; - VIII = (tan(nphi)*tmp) / ((double)24.0 * rho * nu*nu*nu); + tmp = (double)5.0 + (double)3.0 * tan(nphi) * tan(nphi) + etasq; + tmp -= (double)9.0 * tan(nphi) * tan(nphi) * etasq; + VIII = (tan(nphi)*tmp) / ((double)24.0 * rho * nu*nu*nu); - tmp = (double)61.0 + (double)90.0 * tan(nphi) * tan(nphi); - tmp += (double)45.0 * pow(tan(nphi),(double)4.0); - IX = tan(nphi) / ((double)720.0 * rho * pow(nu,(double)5.0)) * tmp; + tmp = (double)61.0 + (double)90.0 * tan(nphi) * tan(nphi); + tmp += (double)45.0 * pow(tan(nphi),(double)4.0); + IX = tan(nphi) / ((double)720.0 * rho * pow(nu,(double)5.0)) * tmp; - X = (double)1.0 / (cos(nphi) * nu); + X = (double)1.0 / (cos(nphi) * nu); - tmp = (nu / rho) + (double)2.0 * tan(nphi) * tan(nphi); - XI = ((double)1.0 / (cos(nphi) * (double)6.0 * nu*nu*nu)) * tmp; + tmp = (nu / rho) + (double)2.0 * tan(nphi) * tan(nphi); + XI = ((double)1.0 / (cos(nphi) * (double)6.0 * nu*nu*nu)) * tmp; - tmp = (double)5.0 + (double)28.0 * tan(nphi)*tan(nphi); - tmp += (double)24.0 * pow(tan(nphi),(double)4.0); - XII = ((double)1.0 / ((double)120.0 * pow(nu,(double)5.0) * cos(nphi))) - * tmp; + tmp = (double)5.0 + (double)28.0 * tan(nphi)*tan(nphi); + tmp += (double)24.0 * pow(tan(nphi),(double)4.0); + XII = ((double)1.0 / ((double)120.0 * pow(nu,(double)5.0) * cos(nphi))) + * tmp; - tmp = (double)61.0 + (double)662.0 * tan(nphi) * tan(nphi); - tmp += (double)1320.0 * pow(tan(nphi),(double)4.0); - tmp += (double)720.0 * pow(tan(nphi),(double)6.0); - XIIA = ((double)1.0 / (cos(nphi) * (double)5040.0 * pow(nu,(double)7.0))) - * tmp; + tmp = (double)61.0 + (double)662.0 * tan(nphi) * tan(nphi); + tmp += (double)1320.0 * pow(tan(nphi),(double)4.0); + tmp += (double)720.0 * pow(tan(nphi),(double)6.0); + XIIA = ((double)1.0 / (cos(nphi) * (double)5040.0 * pow(nu,(double)7.0))) + * tmp; - *phi = nphi - VII*pow((E-E0),(double)2.0) + VIII*pow((E-E0),(double)4.0) - - IX*pow((E-E0),(double)6.0); - - *lambda = lambda0 + X*(E-E0) - XI*pow((E-E0),(double)3.0) + - XII*pow((E-E0),(double)5.0) - XIIA*pow((E-E0),(double)7.0); + *phi = nphi - VII*pow((E-E0),(double)2.0) + VIII*pow((E-E0),(double)4.0) - + IX*pow((E-E0),(double)6.0); - *phi = GPS_Math_Rad_To_Deg(*phi); - *lambda = GPS_Math_Rad_To_Deg(*lambda); + *lambda = lambda0 + X*(E-E0) - XI*pow((E-E0),(double)3.0) + + XII*pow((E-E0),(double)5.0) - XIIA*pow((E-E0),(double)7.0); - return; + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; } @@ -1270,19 +1281,19 @@ void GPS_Math_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, - double *lambda) + double *lambda) { - double N0 = -100000; - double E0 = 400000; - double F0 = 0.9996012717; - double phi0 = 49.; - double lambda0 = -2.; - double a = 6377563.396; - double b = 6356256.910; - - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + double N0 = -100000; + double E0 = 400000; + double F0 = 0.9996012717; + double phi0 = 49.; + double lambda0 = -2.; + double a = 6377563.396; + double b = 6356256.910; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -1300,19 +1311,19 @@ void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, - double *lambda) + double *lambda) { - double N0 = 250000; - double E0 = 200000; - double F0 = 1.000035; - double phi0 = 53.5; - double lambda0 = -8.; - double a = 6377340.189; - double b = 6356034.447; - - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + double N0 = 250000; + double E0 = 200000; + double F0 = 1.000035; + double phi0 = 53.5; + double lambda0 = -8.; + double a = 6377340.189; + double b = 6356034.447; + + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -1331,25 +1342,26 @@ void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, ** @return [int32] success ************************************************************************/ int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, - double *mN, char *map) + double *mN, char *map) { - int32 t; - int32 idx; - - if(E>=(double)700000. || E<(double)0.0 || N<(double)0.0 || - N>=(double)1300000.0) - return 0; - - idx = ((int32)N/100000)*7 + (int32)E/100000; - (void) strcpy(map,UKNG[idx]); - - t = ((int32)E / 100000) * 100000; - *mE = E - (double)t; - - t = ((int32)N / 100000) * 100000; - *mN = N - (double)t; - - return 1; + int32 t; + int32 idx; + + if (E>=(double)700000. || E<(double)0.0 || N<(double)0.0 || + N>=(double)1300000.0) { + return 0; + } + + idx = ((int32)N/100000)*7 + (int32)E/100000; + (void) strcpy(map,UKNG[idx]); + + t = ((int32)E / 100000) * 100000; + *mE = E - (double)t; + + t = ((int32)N / 100000) * 100000; + *mN = N - (double)t; + + return 1; } @@ -1369,32 +1381,35 @@ int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, double *E, - double *N) + double *N) { - int32 t; - int32 idx; - - if(mapE>=(double)100000.0 || mapE<(double)0.0 || mapN<(double)0.0 || - mapN>(double)100000.0) - return 0; - - idx=0; - while(*UKNG[idx]) - { - if(!strcmp(UKNG[idx],map)) break; - ++idx; + int32 t; + int32 idx; + + if (mapE>=(double)100000.0 || mapE<(double)0.0 || mapN<(double)0.0 || + mapN>(double)100000.0) { + return 0; + } + + idx=0; + while (*UKNG[idx]) { + if (!strcmp(UKNG[idx],map)) { + break; } - if(!*UKNG[idx]) - return 0; - + ++idx; + } + if (!*UKNG[idx]) { + return 0; + } + - t = (idx / 7) * 100000; - *N = mapN + (double)t; + t = (idx / 7) * 100000; + *N = mapN + (double)t; - t = (idx % 7) * 100000; - *E = mapE + (double)t; + t = (idx % 7) * 100000; + *E = mapE + (double)t; - return 1; + return 1; } @@ -1420,67 +1435,67 @@ int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, - double Sif, double *Dphi, double *Dlam, - double *DH, double Da, double Dif, double dx, - double dy, double dz) + double Sif, double *Dphi, double *Dlam, + double *DH, double Da, double Dif, double dx, + double dy, double dz) { - double Sf; - double Df; - double esq; - double bda; - double da; - double df; - double N; - double M; - double tmp; - double tmp2; - double dphi; - double dlambda; - double dheight; - double phis; - double phic; - double lams; - double lamc; - - Sf = (double)1.0 / Sif; - Df = (double)1.0 / Dif; - - esq = (double)2.0*Sf - pow(Sf,(double)2.0); - bda = (double)1.0 - Sf; - Sphi = GPS_Math_Deg_To_Rad(Sphi); - Slam = GPS_Math_Deg_To_Rad(Slam); - - da = Da - Sa; - df = Df - Sf; - - phis = sin(Sphi); - phic = cos(Sphi); - lams = sin(Slam); - lamc = cos(Slam); - - N = Sa / sqrt((double)1.0 - esq*pow(phis,(double)2.0)); - - tmp = ((double)1.0-esq) /pow(((double)1.0-esq*pow(phis,(double)2.0)),1.5); - M = Sa * tmp; - - tmp = df * ((M/bda)+N*bda) * phis * phic; - tmp2 = da * N * esq * phis * phic / Sa; - tmp2 += ((-dx*phis*lamc-dy*phis*lams) + dz*phic); - dphi = (tmp2 + tmp) / (M + SH); - - dlambda = (-dx*lams+dy*lamc) / ((N+SH)*phic); - - dheight = dx*phic*lamc + dy*phic*lams + dz*phis - da*(Sa/N) + - df*bda*N*phis*phis; - - *Dphi = Sphi + dphi; - *Dlam = Slam + dlambda; - *DH = SH + dheight; - - *Dphi = GPS_Math_Rad_To_Deg(*Dphi); - *Dlam = GPS_Math_Rad_To_Deg(*Dlam); - - return; + double Sf; + double Df; + double esq; + double bda; + double da; + double df; + double N; + double M; + double tmp; + double tmp2; + double dphi; + double dlambda; + double dheight; + double phis; + double phic; + double lams; + double lamc; + + Sf = (double)1.0 / Sif; + Df = (double)1.0 / Dif; + + esq = (double)2.0*Sf - pow(Sf,(double)2.0); + bda = (double)1.0 - Sf; + Sphi = GPS_Math_Deg_To_Rad(Sphi); + Slam = GPS_Math_Deg_To_Rad(Slam); + + da = Da - Sa; + df = Df - Sf; + + phis = sin(Sphi); + phic = cos(Sphi); + lams = sin(Slam); + lamc = cos(Slam); + + N = Sa / sqrt((double)1.0 - esq*pow(phis,(double)2.0)); + + tmp = ((double)1.0-esq) /pow(((double)1.0-esq*pow(phis,(double)2.0)),1.5); + M = Sa * tmp; + + tmp = df * ((M/bda)+N*bda) * phis * phic; + tmp2 = da * N * esq * phis * phic / Sa; + tmp2 += ((-dx*phis*lamc-dy*phis*lams) + dz*phic); + dphi = (tmp2 + tmp) / (M + SH); + + dlambda = (-dx*lams+dy*lamc) / ((N+SH)*phic); + + dheight = dx*phic*lamc + dy*phic*lams + dz*phis - da*(Sa/N) + + df*bda*N*phis*phis; + + *Dphi = Sphi + dphi; + *Dlam = Slam + dlambda; + *DH = SH + dheight; + + *Dphi = GPS_Math_Rad_To_Deg(*Dphi); + *Dlam = GPS_Math_Rad_To_Deg(*Dlam); + + return; } @@ -1500,31 +1515,31 @@ void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double *Dphi, double *Dlam, double *DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - - Da = (double) 6378137.0; - Dif = (double) 298.257223563; - - idx = GPS_Datum[n].ellipse; - Sa = GPS_Ellipse[idx].a; - Sif = GPS_Ellipse[idx].invf; - x = GPS_Datum[n].dx; - y = GPS_Datum[n].dy; - z = GPS_Datum[n].dz; - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1544,31 +1559,31 @@ void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double *Dphi, double *Dlam, double *DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - - Sa = (double) 6378137.0; - Sif = (double) 298.257223563; - - idx = GPS_Datum[n].ellipse; - Da = GPS_Ellipse[idx].a; - Dif = GPS_Ellipse[idx].invf; - x = -GPS_Datum[n].dx; - y = -GPS_Datum[n].dy; - z = -GPS_Datum[n].dz; - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1588,44 +1603,44 @@ void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double *Dphi, double *Dlam, double *DH, + int32 n) { - double Sa; - double Sif; - double Sb; - double Da; - double Dif; - double Db; - double x; - double y; - double z; - int32 idx; - double sx; - double sy; - double sz; - - Da = (double) 6378137.0; - Dif = (double) 298.257223563; - Db = Da - (Da / Dif); - - idx = GPS_Datum[n].ellipse; - Sa = GPS_Ellipse[idx].a; - Sif = GPS_Ellipse[idx].invf; - Sb = Sa - (Sa / Sif); - - x = GPS_Datum[n].dx; - y = GPS_Datum[n].dy; - z = GPS_Datum[n].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&sx,&sy,&sz,Sa,Sb); - sx += x; - sy += y; - sz += z; - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,sx,sy,sz,Da,Db); - - return; + double Sa; + double Sif; + double Sb; + double Da; + double Dif; + double Db; + double x; + double y; + double z; + int32 idx; + double sx; + double sy; + double sz; + + Da = (double) 6378137.0; + Dif = (double) 298.257223563; + Db = Da - (Da / Dif); + + idx = GPS_Datum[n].ellipse; + Sa = GPS_Ellipse[idx].a; + Sif = GPS_Ellipse[idx].invf; + Sb = Sa - (Sa / Sif); + + x = GPS_Datum[n].dx; + y = GPS_Datum[n].dy; + z = GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&sx,&sy,&sz,Sa,Sb); + sx += x; + sy += y; + sz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,sx,sy,sz,Da,Db); + + return; } @@ -1645,44 +1660,44 @@ void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n) + double *Dphi, double *Dlam, double *DH, + int32 n) { - double Sa; - double Sif; - double Da; - double Dif; - double x; - double y; - double z; - int32 idx; - double Sb; - double Db; - double dx; - double dy; - double dz; - - Sa = (double) 6378137.0; - Sif = (double) 298.257223563; - Sb = Sa - (Sa / Sif); - - idx = GPS_Datum[n].ellipse; - Da = GPS_Ellipse[idx].a; - Dif = GPS_Ellipse[idx].invf; - Db = Da - (Da / Dif); - - x = -GPS_Datum[n].dx; - y = -GPS_Datum[n].dy; - z = -GPS_Datum[n].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); - dx += x; - dy += y; - dz += z; - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x; + double y; + double z; + int32 idx; + double Sb; + double Db; + double dx; + double dy; + double dz; + + Sa = (double) 6378137.0; + Sif = (double) 298.257223563; + Sb = Sa - (Sa / Sif); + + idx = GPS_Datum[n].ellipse; + Da = GPS_Ellipse[idx].a; + Dif = GPS_Ellipse[idx].invf; + Db = Da - (Da / Dif); + + x = -GPS_Datum[n].dx; + y = -GPS_Datum[n].dy; + z = -GPS_Datum[n].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += x; + dy += y; + dz += z; + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; } @@ -1703,48 +1718,48 @@ void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2) + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2) { - double Sa; - double Sif; - double Da; - double Dif; - double x1; - double y1; - double z1; - double x2; - double y2; - double z2; - double x; - double y; - double z; - - int32 idx1; - int32 idx2; - - - idx1 = GPS_Datum[n1].ellipse; - Sa = GPS_Ellipse[idx1].a; - Sif = GPS_Ellipse[idx1].invf; - x1 = GPS_Datum[n1].dx; - y1 = GPS_Datum[n1].dy; - z1 = GPS_Datum[n1].dz; - - idx2 = GPS_Datum[n2].ellipse; - Da = GPS_Ellipse[idx2].a; - Dif = GPS_Ellipse[idx2].invf; - x2 = GPS_Datum[n2].dx; - y2 = GPS_Datum[n2].dy; - z2 = GPS_Datum[n2].dz; - - x = -(x2-x1); - y = -(y2-y1); - z = -(z2-z1); - - GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + double x; + double y; + double z; + + int32 idx1; + int32 idx2; + + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + x = -(x2-x1); + y = -(y2-y1); + z = -(z2-z1); + + GPS_Math_Molodensky(Sphi,Slam,SH,Sa,Sif,Dphi,Dlam,DH,Da,Dif,x,y,z); + + return; } @@ -1765,55 +1780,55 @@ void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, ** @return [void] ************************************************************************/ void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2) + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2) { - double Sa; - double Sif; - double Da; - double Dif; - double x1; - double y1; - double z1; - double x2; - double y2; - double z2; - - int32 idx1; - int32 idx2; - - double Sb; - double Db; - double dx; - double dy; - double dz; - - idx1 = GPS_Datum[n1].ellipse; - Sa = GPS_Ellipse[idx1].a; - Sif = GPS_Ellipse[idx1].invf; - Sb = Sa - (Sa / Sif); - - x1 = GPS_Datum[n1].dx; - y1 = GPS_Datum[n1].dy; - z1 = GPS_Datum[n1].dz; - - idx2 = GPS_Datum[n2].ellipse; - Da = GPS_Ellipse[idx2].a; - Dif = GPS_Ellipse[idx2].invf; - Db = Da - (Da / Dif); - - x2 = GPS_Datum[n2].dx; - y2 = GPS_Datum[n2].dy; - z2 = GPS_Datum[n2].dz; - - GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); - dx += -(x2-x1); - dy += -(y2-y1); - dz += -(z2-z1); - - GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); - - return; + double Sa; + double Sif; + double Da; + double Dif; + double x1; + double y1; + double z1; + double x2; + double y2; + double z2; + + int32 idx1; + int32 idx2; + + double Sb; + double Db; + double dx; + double dy; + double dz; + + idx1 = GPS_Datum[n1].ellipse; + Sa = GPS_Ellipse[idx1].a; + Sif = GPS_Ellipse[idx1].invf; + Sb = Sa - (Sa / Sif); + + x1 = GPS_Datum[n1].dx; + y1 = GPS_Datum[n1].dy; + z1 = GPS_Datum[n1].dz; + + idx2 = GPS_Datum[n2].ellipse; + Da = GPS_Ellipse[idx2].a; + Dif = GPS_Ellipse[idx2].invf; + Db = Da - (Da / Dif); + + x2 = GPS_Datum[n2].dx; + y2 = GPS_Datum[n2].dy; + z2 = GPS_Datum[n2].dz; + + GPS_Math_LatLonH_To_XYZ(Sphi,Slam,SH,&dx,&dy,&dz,Sa,Sb); + dx += -(x2-x1); + dy += -(y2-y1); + dz += -(z2-z1); + + GPS_Math_XYZ_To_LatLonH(Dphi,Dlam,DH,dx,dy,dz,Da,Db); + + return; } @@ -1832,23 +1847,24 @@ void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, ** @return [int32] success ************************************************************************/ int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, - double *mN, char *map) + double *mN, char *map) { - double alat; - double alon; - double aht; - double aE; - double aN; + double alat; + double alon; + double aht; + double aE; + double aN; - GPS_Math_WGS84_To_Known_Datum_M(lat,lon,30,&alat,&alon,&aht,86); + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,30,&alat,&alon,&aht,86); - GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); - if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) - return 0; + if (!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) { + return 0; + } - return 1; + return 1; } @@ -1867,22 +1883,23 @@ int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, - double *lat, double *lon) + double *lat, double *lon) { - double E; - double N; - double alat; - double alon; - double ht; - - if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) - return 0; + double E; + double N; + double alat; + double alon; + double ht; - GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + if (!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) { + return 0; + } - GPS_Math_Known_Datum_To_WGS84_M(alat,alon,0,lat,lon,&ht,86); + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); - return 1; + GPS_Math_Known_Datum_To_WGS84_M(alat,alon,0,lat,lon,&ht,86); + + return 1; } @@ -1901,23 +1918,24 @@ int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, ** @return [int32] success ************************************************************************/ int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, - double *mN, char *map) + double *mN, char *map) { - double alat; - double alon; - double aht; - double aE; - double aN; + double alat; + double alon; + double aht; + double aE; + double aN; - GPS_Math_WGS84_To_Known_Datum_C(lat,lon,30,&alat,&alon,&aht,86); + GPS_Math_WGS84_To_Known_Datum_C(lat,lon,30,&alat,&alon,&aht,86); - GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); + GPS_Math_Airy1830LatLonToNGEN(alat,alon,&aE,&aN); - if(!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) - return 0; + if (!GPS_Math_EN_To_UKOSNG_Map(aE,aN,mE,mN,map)) { + return 0; + } - return 1; + return 1; } @@ -1936,22 +1954,23 @@ int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, - double *lat, double *lon) + double *lat, double *lon) { - double E; - double N; - double alat; - double alon; - double ht; - - if(!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) - return 0; + double E; + double N; + double alat; + double alon; + double ht; + + if (!GPS_Math_UKOSNG_Map_To_EN(map,mE,mN,&E,&N)) { + return 0; + } - GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); + GPS_Math_NGENToAiry1830LatLon(E,N,&alat,&alon); - GPS_Math_Known_Datum_To_WGS84_C(alat,alon,0,lat,lon,&ht,86); + GPS_Math_Known_Datum_To_WGS84_C(alat,alon,0,lat,lon,&ht,86); - return 1; + return 1; } @@ -1971,90 +1990,83 @@ int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, ** @return [int32] success ************************************************************************/ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, - char *zc, double *Mc, double *E0, - double *N0, double *F0) + char *zc, double *Mc, double *E0, + double *N0, double *F0) { - int32 ilon; - int32 ilat; - int32 psign; - int32 lsign; - - if(lat >= (double)84.0 || lat < (double)-80.0) - return 0; - - psign = lsign = 0; - if(lon < (double)0.0) - lsign=1; - if(lat < (double)0.0) - psign=1; - - ilon = abs((int32)lon); - ilat = abs((int32)lat); - - if(!lsign) - { - *zone = 31 + (ilon / 6); - *Mc = (double)((ilon / 6) * 6 + 3); - } - else - { - *zone = 30 - (ilon / 6); - *Mc = -(double)((ilon / 6) * 6 + 3); + int32 ilon; + int32 ilat; + int32 psign; + int32 lsign; + + if (lat >= (double)84.0 || lat < (double)-80.0) { + return 0; + } + + psign = lsign = 0; + if (lon < (double)0.0) { + lsign=1; + } + if (lat < (double)0.0) { + psign=1; + } + + ilon = abs((int32)lon); + ilat = abs((int32)lat); + + if (!lsign) { + *zone = 31 + (ilon / 6); + *Mc = (double)((ilon / 6) * 6 + 3); + } else { + *zone = 30 - (ilon / 6); + *Mc = -(double)((ilon / 6) * 6 + 3); + } + + if (!psign) { + *zc = 'N' + ilat / 8; + if (*zc > 'N') { + ++*zc; } - - if(!psign) - { - *zc = 'N' + ilat / 8; - if(*zc > 'N') ++*zc; + } else { + *zc = 'M' - (ilat / 8); + if (*zc <= 'I') { + --*zc; } - else - { - *zc = 'M' - (ilat / 8); - if(*zc <= 'I') --*zc; + } + + + if (lat>=(double)56.0 && lat<(double)64.0 && lon>=(double)3.0 && + lon<(double)12.0) { + *zone = 32; + *zc = 'V'; + *Mc = (double)9.0; + } + + if (*zc=='X' && lon>=(double)0.0 && lon<(double)42.0) { + if (lon<(double)9.0) { + *zone = 31; + *Mc = (double)3.0; + } else if (lon<(double)21.0) { + *zone = 33; + *Mc = (double)15.0; + } else if (lon<(double)33.0) { + *zone = 35; + *Mc = (double)27.0; + } else { + *zone = 37; + *Mc = (double)39.0; } + } + if (!psign) { + *N0 = (double)0.0; + } else { + *N0 = (double)10000000; + } - if(lat>=(double)56.0 && lat<(double)64.0 && lon>=(double)3.0 && - lon<(double)12.0) - { - *zone = 32; - *zc = 'V'; - *Mc = (double)9.0; - } - - if(*zc=='X' && lon>=(double)0.0 && lon<(double)42.0) - { - if(lon<(double)9.0) - { - *zone = 31; - *Mc = (double)3.0; - } - else if(lon<(double)21.0) - { - *zone = 33; - *Mc = (double)15.0; - } - else if(lon<(double)33.0) - { - *zone = 35; - *Mc = (double)27.0; - } - else - { - *zone = 37; - *Mc = (double)39.0; - } - } - - if(!psign) - *N0 = (double)0.0; - else - *N0 = (double)10000000; - - *E0 = (double)500000; - *F0 = (double)0.9996; - - return 1; + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; } @@ -2073,28 +2085,29 @@ static int32 GPS_Math_LatLon_To_UTM_Param(double lat, double lon, int32 *zone, ** @return [int32] success ************************************************************************/ int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc) + double *N, int32 *zone, char *zc) { - double phi0; - double lambda0; - double N0; - double E0; - double F0; - double a; - double b; + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; - if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, - &N0,&F0)) - return 0; + if (!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) { + return 0; + } - phi0 = (double)0.0; + phi0 = (double)0.0; - a = (double) GPS_Ellipse[21].a; - b = a - (a/GPS_Ellipse[21].invf); + a = (double) GPS_Ellipse[21].a; + b = a - (a/GPS_Ellipse[21].invf); - GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); - return 1; + return 1; } @@ -2113,17 +2126,18 @@ int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, ** @return [int32] success ************************************************************************/ int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc) + double *N, int32 *zone, char *zc) { - double phi; - double lambda; - double H; - - GPS_Math_WGS84_To_Known_Datum_M(lat,lon,0,&phi,&lambda,&H,77); - if(!GPS_Math_NAD83_To_UTM_EN(phi,lambda,E,N,zone,zc)) - return 0; - - return 1; + double phi; + double lambda; + double H; + + GPS_Math_WGS84_To_Known_Datum_M(lat,lon,0,&phi,&lambda,&H,77); + if (!GPS_Math_NAD83_To_UTM_EN(phi,lambda,E,N,zone,zc)) { + return 0; + } + + return 1; } @@ -2143,38 +2157,46 @@ int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, ** @return [int32] success ************************************************************************/ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, - double *E0, double *N0, double *F0) + double *E0, double *N0, double *F0) { - if(zone>60 || zone<0 || zc<'C' || zc>'X') - return 0; - - if(zone > 30) - *Mc = (double)((zone-31)*6) + (double)3.0; - else - *Mc = (double) -(((30-zone)*6)+3); - - if(zone==32 && zc=='V') - *Mc = (double)9.0; - - if(zone==31 && zc=='X') - *Mc = (double)3.0; - if(zone==33 && zc=='X') - *Mc = (double)15.0; - if(zone==35 && zc=='X') - *Mc = (double)27.0; - if(zone==37 && zc=='X') - *Mc = (double)39.0; - - if(zc>'M') - *N0 = (double)0.0; - else - *N0 = (double)10000000; - - *E0 = (double)500000; - *F0 = (double)0.9996; - - return 1; + if (zone>60 || zone<0 || zc<'C' || zc>'X') { + return 0; + } + + if (zone > 30) { + *Mc = (double)((zone-31)*6) + (double)3.0; + } else { + *Mc = (double) -(((30-zone)*6)+3); + } + + if (zone==32 && zc=='V') { + *Mc = (double)9.0; + } + + if (zone==31 && zc=='X') { + *Mc = (double)3.0; + } + if (zone==33 && zc=='X') { + *Mc = (double)15.0; + } + if (zone==35 && zc=='X') { + *Mc = (double)27.0; + } + if (zone==37 && zc=='X') { + *Mc = (double)39.0; + } + + if (zc>'M') { + *N0 = (double)0.0; + } else { + *N0 = (double)10000000; + } + + *E0 = (double)500000; + *F0 = (double)0.9996; + + return 1; } @@ -2193,9 +2215,9 @@ static int32 GPS_Math_UTM_Param_To_Mc(int32 zone, char zc, double *Mc, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, - double N, int32 zone, char zc) + double N, int32 zone, char zc) { - return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 77); + return GPS_Math_UTM_EN_To_Known_Datum(lat, lon, E, N, zone, zc, 77); } @@ -2214,17 +2236,19 @@ int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, - double N, int32 zone, char zc) + double N, int32 zone, char zc) { - double lambda0; - double N0; - double E0; - double F0; + double lambda0; + double N0; + double E0; + double F0; - if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) return 0; + if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) { + return 0; + } - GPS_Math_UTM_EN_to_LatLon(GPS_Datum[118].ellipse, N, E, lat, lon, lambda0, E0, N0); - return 1; + GPS_Math_UTM_EN_to_LatLon(GPS_Datum[118].ellipse, N, E, lat, lon, lambda0, E0, N0); + return 1; } @@ -2243,30 +2267,31 @@ int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, ** @return [int32] success ************************************************************************/ int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc, const int n) + double *N, int32 *zone, char *zc, const int n) { - double phi0; - double lambda0; - double N0; - double E0; - double F0; - double a; - double b; - int32 idx; - - if(!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, - &N0,&F0)) - return 0; - - phi0 = (double)0.0; - - idx = GPS_Datum[n].ellipse; - a = (double) GPS_Ellipse[idx].a; - b = a - (a/GPS_Ellipse[idx].invf); - - GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); - - return 1; + double phi0; + double lambda0; + double N0; + double E0; + double F0; + double a; + double b; + int32 idx; + + if (!GPS_Math_LatLon_To_UTM_Param(lat,lon,zone,zc,&lambda0,&E0, + &N0,&F0)) { + return 0; + } + + phi0 = (double)0.0; + + idx = GPS_Datum[n].ellipse; + a = (double) GPS_Ellipse[idx].a; + b = a - (a/GPS_Ellipse[idx].invf); + + GPS_Math_LatLon_To_EN(E,N,lat,lon,N0,E0,phi0,lambda0,F0,a,b); + + return 1; } /* @func GPS_Math_UTM_EN_To_Known_Datum ********************************* @@ -2284,17 +2309,19 @@ int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, ** @return [int32] success ************************************************************************/ int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, - double N, int32 zone, char zc, const int n) + double N, int32 zone, char zc, const int n) { - double lambda0; - double N0; - double E0; - double F0; + double lambda0; + double N0; + double E0; + double F0; - if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) return 0; + if (!GPS_Math_UTM_Param_To_Mc(zone,zc,&lambda0,&E0,&N0,&F0)) { + return 0; + } - GPS_Math_UTM_EN_to_LatLon(GPS_Datum[n].ellipse, N, E, lat, lon, lambda0, E0, N0); - return 1; + GPS_Math_UTM_EN_to_LatLon(GPS_Datum[n].ellipse, N, E, lat, lon, lambda0, E0, N0); + return 1; } /* !!! copied from unused gpsproj.c !!! */ @@ -2317,64 +2344,64 @@ int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, ** @return [void] ***************************************************************************/ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b) + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double c; - double ephi0p; - double phip; - double sphip; - double phid; - double slambda2; - double lambda1; - double lambda2; - double K; - double po4; - double w; - double R; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - po4=GPS_PI/(double)4.0; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); - - ephi0p = asin(sin(phi0)/c); - - K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - lambda1 = c*(lambda-lambda0); - w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; - - - phip = (double)2. * (atan(exp(w)) - po4); - - sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); - phid = asin(sphip); - - slambda2 = cos(phip)*sin(lambda1) / cos(phid); - lambda2 = asin(slambda2); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - *N = R*log(tan(po4 + phid/(double)2.)) + N0; - *E = R*lambda2 + E0; - return; + double a2; + double b2; + double esq; + double e; + double c; + double ephi0p; + double phip; + double sphip; + double phid; + double slambda2; + double lambda1; + double lambda2; + double K; + double po4; + double w; + double R; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + po4=GPS_PI/(double)4.0; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); + + ephi0p = asin(sin(phi0)/c); + + K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - + e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + lambda1 = c*(lambda-lambda0); + w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; + + + phip = (double)2. * (atan(exp(w)) - po4); + + sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); + phid = asin(sphip); + + slambda2 = cos(phip)*sin(lambda1) / cos(phid); + lambda2 = asin(slambda2); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + *N = R*log(tan(po4 + phid/(double)2.)) + N0; + *E = R*lambda2 + E0; + return; } /* !!! copied from unused gpsproj.c !!! */ @@ -2398,159 +2425,157 @@ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, *************************************************************************/ void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double R; - double c; - double po4; - double phid; - double phi1; - double lambdad; - double lambda1; - double slambda1; - double ephi0p; - double sphip; - double tol; - double cr; - double C; - double K; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - po4=GPS_PI/(double)4.0; - tol=(double)0.00001; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - phid = (double)2.*(atan(exp((N - N0)/R)) - po4); - lambdad = (E - E0)/R; - - c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / - ((double)1.-esq))); - ephi0p = asin(sin(phi0) / c); - - sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); - phi1 = asin(sphip); - - slambda1 = cos(phid)*sin(lambdad)/cos(phi1); - lambda1 = asin(slambda1); - - *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); - - K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - C = (K - log(tan(po4 + phi1/(double)2.)))/c; - - do - { - cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * - ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / - ((double)1.-esq)); - phi1 -= cr; - } - while (fabs(cr) > tol); - - *phi = GPS_Math_Rad_To_Deg(phi1); - - return; + double a2; + double b2; + double esq; + double e; + double R; + double c; + double po4; + double phid; + double phi1; + double lambdad; + double lambda1; + double slambda1; + double ephi0p; + double sphip; + double tol; + double cr; + double C; + double K; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + po4=GPS_PI/(double)4.0; + tol=(double)0.00001; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + phid = (double)2.*(atan(exp((N - N0)/R)) - po4); + lambdad = (E - E0)/R; + + c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / + ((double)1.-esq))); + ephi0p = asin(sin(phi0) / c); + + sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); + phi1 = asin(sphip); + + slambda1 = cos(phid)*sin(lambdad)/cos(phi1); + lambda1 = asin(slambda1); + + *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); + + K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) + - e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + C = (K - log(tan(po4 + phi1/(double)2.)))/c; + + do { + cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * + ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / + ((double)1.-esq)); + phi1 -= cr; + } while (fabs(cr) > tol); + + *phi = GPS_Math_Rad_To_Deg(phi1); + + return; } /********************************************************************/ -void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, - const double UTMNorthing, const double UTMEasting, - double *Lat, double *Lon, - const double lambda0, - const double E0, - const double N0) +void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, + const double UTMNorthing, const double UTMEasting, + double *Lat, double *Lon, + const double lambda0, + const double E0, + const double N0) { -//converts UTM coords to lat/long. Equations from USGS Bulletin 1532 -//East Longitudes are positive, West longitudes are negative. +//converts UTM coords to lat/long. Equations from USGS Bulletin 1532 +//East Longitudes are positive, West longitudes are negative. //North latitudes are positive, South latitudes are negative -//Lat and Long are in decimal degrees. +//Lat and Long are in decimal degrees. //based on code witten by Chuck Gantz- chuck.gantz@globalstar.com //found at http://www.gpsy.com/gpsinfo/geotoutm/index.html - double k0 = 0.9996; - double a, b; - double eccSquared; - double eccPrimeSquared; - double e1; - double N1, T1, C1, R1, D, M; - double mu, phi1, phi1Rad; - double x, y; - - a = GPS_Ellipse[ReferenceEllipsoid].a; - b = 1 / GPS_Ellipse[ReferenceEllipsoid].invf; - eccSquared = b * (2.0 - b); - e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared)); - - x = UTMEasting - E0; //remove false easting - y = UTMNorthing - N0; //remove false northing - - eccPrimeSquared = (eccSquared)/(1-eccSquared); - - M = y / k0; - mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)); - - phi1Rad = mu+ (3*e1/2-27*e1*e1*e1/32)*sin(2*mu) + - (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu) + - (151*e1*e1*e1/96)*sin(6*mu); - phi1 = GPS_Math_Rad_To_Deg(phi1Rad); - - N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad)); - T1 = tan(phi1Rad)*tan(phi1Rad); - C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad); - R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5); - D = x/(N1*k0); - - *Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24 - +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720); - *Lat = GPS_Math_Rad_To_Deg(*Lat); - - *Lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120)/cos(phi1Rad); - *Lon = lambda0 + GPS_Math_Rad_To_Deg(*Lon); + double k0 = 0.9996; + double a, b; + double eccSquared; + double eccPrimeSquared; + double e1; + double N1, T1, C1, R1, D, M; + double mu, phi1, phi1Rad; + double x, y; + + a = GPS_Ellipse[ReferenceEllipsoid].a; + b = 1 / GPS_Ellipse[ReferenceEllipsoid].invf; + eccSquared = b * (2.0 - b); + e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared)); + + x = UTMEasting - E0; //remove false easting + y = UTMNorthing - N0; //remove false northing + + eccPrimeSquared = (eccSquared)/(1-eccSquared); + + M = y / k0; + mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)); + + phi1Rad = mu+ (3*e1/2-27*e1*e1*e1/32)*sin(2*mu) + + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu) + + (151*e1*e1*e1/96)*sin(6*mu); + phi1 = GPS_Math_Rad_To_Deg(phi1Rad); + + N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad)); + T1 = tan(phi1Rad)*tan(phi1Rad); + C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad); + R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5); + D = x/(N1*k0); + + *Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24 + +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720); + *Lat = GPS_Math_Rad_To_Deg(*Lat); + + *Lon = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120)/cos(phi1Rad); + *Lon = lambda0 + GPS_Math_Rad_To_Deg(*Lon); } /********************************************************************/ int32 GPS_Lookup_Datum_Index(const char *n) { - GPS_PDatum dp; - GPS_PDatum_Alias al; - - for (al = GPS_DatumAlias; al->alias; al++) { - if (case_ignore_strcmp(al->alias, n) == 0) { - return al->datum; - } - } - - for (dp = GPS_Datum; dp->name; dp++) { - if (0 == case_ignore_strcmp(dp->name, n)) { - return dp - GPS_Datum; - } - } - - return -1; + GPS_PDatum dp; + GPS_PDatum_Alias al; + + for (al = GPS_DatumAlias; al->alias; al++) { + if (case_ignore_strcmp(al->alias, n) == 0) { + return al->datum; + } + } + + for (dp = GPS_Datum; dp->name; dp++) { + if (0 == case_ignore_strcmp(dp->name, n)) { + return dp - GPS_Datum; + } + } + + return -1; } char * GPS_Math_Get_Datum_Name(const int datum_index) { - return GPS_Datum[datum_index].name; + return GPS_Datum[datum_index].name; } diff --git a/gpsbabel/jeeps/gpsmath.h b/gpsbabel/jeeps/gpsmath.h index dbd8b51a5..3bab7217e 100644 --- a/gpsbabel/jeeps/gpsmath.h +++ b/gpsbabel/jeeps/gpsmath.h @@ -14,134 +14,134 @@ extern "C" #define GPS_FLTMAX 3.402823466E+38 -double GPS_Math_Deg_To_Rad(double v); -double GPS_Math_Rad_To_Deg(double v); - -double GPS_Math_Metres_To_Feet(double v); -double GPS_Math_Feet_To_Metres(double v); - -int32 GPS_Math_Deg_To_Semi(double v); -double GPS_Math_Semi_To_Deg(int32 v); - -time_t GPS_Math_Utime_To_Gtime(time_t v); -time_t GPS_Math_Gtime_To_Utime(time_t v); - -void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m); -void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg); -void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s); -void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg); - - -void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, - double *N); -void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, - double *N); -int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, - double *E, double *N); - -void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z, - double a, double b); -void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z, - double a, double b); - -void GPS_Math_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b); -void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, - double lambda, double N0, double E0, - double phi0, double lambda0, - double F0, double a, double b); - -void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, - double *lambda); -void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, - double *lambda); - - -void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z); -void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, - double *x, double *y, double *z); -void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z); -void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, - double x, double y, double z); - -void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, - double Sif, double *Dphi, double *Dlam, - double *DH, double Da, double Dif, double dx, - double dy, double dz); -void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); -void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, double *DH, - int32 n); - -void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2); -void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, - double *Dphi, double *Dlam, - double *DH, int32 n1, int32 n2); - -int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, - double *lat, double *lon); -int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, - double *mN, char *map); -int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, - double *lat, double *lon); - - -int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc); -int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc); - -int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, - double N, int32 zone, char zc); -int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, - double N, int32 zone, char zc); - -int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, - double *N, int32 *zone, char *zc, const int n); -int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, - double N, int32 zone, char zc, const int n); - -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); - -int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, - double *N); -void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon); - -int32 GPS_Math_WGS84_To_Swiss_EN(double phi, double lambda, double *E, double *N); -void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon); - -void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, - const double UTMNorthing, const double UTMEasting, - double *Lat, double *Lon, - const double lambda0, const double E0, const double N0); - -int32 GPS_Lookup_Datum_Index(const char *n); -char *GPS_Math_Get_Datum_Name(const int datum_index); + double GPS_Math_Deg_To_Rad(double v); + double GPS_Math_Rad_To_Deg(double v); + + double GPS_Math_Metres_To_Feet(double v); + double GPS_Math_Feet_To_Metres(double v); + + int32 GPS_Math_Deg_To_Semi(double v); + double GPS_Math_Semi_To_Deg(int32 v); + + time_t GPS_Math_Utime_To_Gtime(time_t v); + time_t GPS_Math_Gtime_To_Utime(time_t v); + + void GPS_Math_Deg_To_DegMin(double v, int32 *d, double *m); + void GPS_Math_DegMin_To_Deg(int32 d, double m, double *deg); + void GPS_Math_Deg_To_DegMinSec(double v, int32 *d, int32 *m, double *s); + void GPS_Math_DegMinSec_To_Deg(int32 d, int32 m, double s, double *deg); + + + void GPS_Math_Airy1830LatLonToNGEN(double phi, double lambda, double *E, + double *N); + void GPS_Math_Airy1830M_LatLonToINGEN(double phi, double lambda, double *E, + double *N); + int32 GPS_Math_EN_To_UKOSNG_Map(double E, double N, double *mE, + double *mN, char *map); + int32 GPS_Math_UKOSNG_Map_To_EN(char *map, double mapE, double mapN, + double *E, double *N); + + void GPS_Math_LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z, + double a, double b); + void GPS_Math_XYZ_To_LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z, + double a, double b); + + void GPS_Math_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); + void GPS_Math_LatLon_To_EN(double *E, double *N, double phi, + double lambda, double N0, double E0, + double phi0, double lambda0, + double F0, double a, double b); + + void GPS_Math_NGENToAiry1830LatLon(double E, double N, double *phi, + double *lambda); + void GPS_Math_INGENToAiry1830MLatLon(double E, double N, double *phi, + double *lambda); + + + void GPS_Math_Airy1830LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z); + void GPS_Math_WGS84LatLonH_To_XYZ(double phi, double lambda, double H, + double *x, double *y, double *z); + void GPS_Math_XYZ_To_Airy1830LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z); + void GPS_Math_XYZ_To_WGS84LatLonH(double *phi, double *lambda, double *H, + double x, double y, double z); + + void GPS_Math_Molodensky(double Sphi, double Slam, double SH, double Sa, + double Sif, double *Dphi, double *Dlam, + double *DH, double Da, double Dif, double dx, + double dy, double dz); + void GPS_Math_Known_Datum_To_WGS84_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); + void GPS_Math_WGS84_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); + void GPS_Math_Known_Datum_To_WGS84_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); + void GPS_Math_WGS84_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, double *DH, + int32 n); + + void GPS_Math_Known_Datum_To_Known_Datum_M(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2); + void GPS_Math_Known_Datum_To_Known_Datum_C(double Sphi, double Slam, double SH, + double *Dphi, double *Dlam, + double *DH, int32 n1, int32 n2); + + int32 GPS_Math_WGS84_To_UKOSMap_M(double lat, double lon, double *mE, + double *mN, char *map); + int32 GPS_Math_UKOSMap_To_WGS84_M(char *map, double mE, double mN, + double *lat, double *lon); + int32 GPS_Math_WGS84_To_UKOSMap_C(double lat, double lon, double *mE, + double *mN, char *map); + int32 GPS_Math_UKOSMap_To_WGS84_C(char *map, double mE, double mN, + double *lat, double *lon); + + + int32 GPS_Math_NAD83_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc); + int32 GPS_Math_WGS84_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc); + + int32 GPS_Math_UTM_EN_To_WGS84(double *lat, double *lon, double E, + double N, int32 zone, char zc); + int32 GPS_Math_UTM_EN_To_NAD83(double *lat, double *lon, double E, + double N, int32 zone, char zc); + + int32 GPS_Math_Known_Datum_To_UTM_EN(double lat, double lon, double *E, + double *N, int32 *zone, char *zc, const int n); + int32 GPS_Math_UTM_EN_To_Known_Datum(double *lat, double *lon, double E, + double N, int32 zone, char zc, const int n); + + void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + + int32 GPS_Math_WGS84_To_ICS_EN(double lat, double lon, double *E, + double *N); + void GPS_Math_ICS_EN_To_WGS84(double E, double N, double *lat, double *lon); + + int32 GPS_Math_WGS84_To_Swiss_EN(double phi, double lambda, double *E, double *N); + void GPS_Math_Swiss_EN_To_WGS84(double E, double N, double *lat, double *lon); + + void GPS_Math_UTM_EN_to_LatLon(int ReferenceEllipsoid, + const double UTMNorthing, const double UTMEasting, + double *Lat, double *Lon, + const double lambda0, const double E0, const double N0); + + int32 GPS_Lookup_Datum_Index(const char *n); + char *GPS_Math_Get_Datum_Name(const int datum_index); #endif diff --git a/gpsbabel/jeeps/gpsmem.c b/gpsbabel/jeeps/gpsmem.c index 8425422ec..3530a7fda 100644 --- a/gpsbabel/jeeps/gpsmem.c +++ b/gpsbabel/jeeps/gpsmem.c @@ -2,23 +2,23 @@ ** @source JEEPS constructor and deconstructor functions ** ** @author Copyright (C) 1999,2000 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified December 28th 1999 Alan Bleasby. First version ** @modified June 29th 2000 Alan Bleasby. NMEA additions ** @modified Copyright (C) 2006 Robert Lipe ** @modified Copyright (C) 2007 Achim Schumacher ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -39,25 +39,24 @@ GPS_PPacket GPS_Packet_New(void) { - GPS_PPacket ret; - int hdr_size = sizeof(GPS_OPacket) ; - if(!(ret=(GPS_PPacket )calloc(1, hdr_size))) - - { - perror("malloc"); - fprintf(stderr,"GPS_Packet_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - if(!(ret->data = (UC *)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PPacket ret; + int hdr_size = sizeof(GPS_OPacket) ; + if (!(ret=(GPS_PPacket)calloc(1, hdr_size))) + + { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + if (!(ret->data = (UC *)calloc(1, MAX_GPS_PACKET_SIZE*sizeof(UC)))) { + perror("malloc"); + fprintf(stderr,"GPS_Packet_New: Insufficient data memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -72,10 +71,10 @@ GPS_PPacket GPS_Packet_New(void) void GPS_Packet_Del(GPS_PPacket *thys) { - free((void *)(*thys)->data); - free((void *)*thys); + free((void *)(*thys)->data); + free((void *)*thys); - return; + return; } @@ -89,17 +88,16 @@ void GPS_Packet_Del(GPS_PPacket *thys) GPS_PPvt_Data GPS_Pvt_New(void) { - GPS_PPvt_Data ret; - - if(!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PPvt_Data ret; + + if (!(ret=(GPS_PPvt_Data)calloc(1, sizeof(GPS_OPvt_Data)))) { + perror("malloc"); + fprintf(stderr,"GPS_Pvt_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -115,9 +113,9 @@ GPS_PPvt_Data GPS_Pvt_New(void) void GPS_Pvt_Del(GPS_PPvt_Data *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } @@ -131,21 +129,20 @@ void GPS_Pvt_Del(GPS_PPvt_Data *thys) GPS_PAlmanac GPS_Almanac_New(void) { - GPS_PAlmanac ret; - - if(!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - ret->svid=0xff; - ret->wn = -1; - ret->hlth=0xff; - - return ret; + GPS_PAlmanac ret; + + if (!(ret=(GPS_PAlmanac)calloc(1, sizeof(GPS_OAlmanac)))) { + perror("malloc"); + fprintf(stderr,"GPS_Almanac_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + ret->svid=0xff; + ret->wn = -1; + ret->hlth=0xff; + + return ret; } @@ -161,9 +158,9 @@ GPS_PAlmanac GPS_Almanac_New(void) void GPS_Almanac_Del(GPS_PAlmanac *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } @@ -177,17 +174,16 @@ void GPS_Almanac_Del(GPS_PAlmanac *thys) GPS_PTrack GPS_Track_New(void) { - GPS_PTrack ret; - - if(!(ret=(GPS_PTrack)calloc(1,sizeof(GPS_OTrack)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Track_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PTrack ret; + + if (!(ret=(GPS_PTrack)calloc(1,sizeof(GPS_OTrack)))) { + perror("malloc"); + fprintf(stderr,"GPS_Track_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -203,9 +199,9 @@ GPS_PTrack GPS_Track_New(void) void GPS_Track_Del(GPS_PTrack *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } @@ -219,62 +215,65 @@ void GPS_Track_Del(GPS_PTrack *thys) GPS_PWay GPS_Way_New(void) { - GPS_PWay ret; - int32 i; - - if(!(ret=(GPS_PWay)xcalloc(sizeof(GPS_OWay),1))) - { - perror("malloc"); - fprintf(stderr,"GPS_Way_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - /* - * It turns out that the Way struct, initialized with zeros (not the - * random stuff that we got with malloc, but REALLY initialized with - * zeros from the calloc above actually does use C strings and it's - * up to the various way_blah_send functions to zero/string pad things - * as it goes. So neutralize this. - */ + GPS_PWay ret; + int32 i; + + if (!(ret=(GPS_PWay)xcalloc(sizeof(GPS_OWay),1))) { + perror("malloc"); + fprintf(stderr,"GPS_Way_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + /* + * It turns out that the Way struct, initialized with zeros (not the + * random stuff that we got with malloc, but REALLY initialized with + * zeros from the calloc above actually does use C strings and it's + * up to the various way_blah_send functions to zero/string pad things + * as it goes. So neutralize this. + */ #if 0 - /* - * Mark all as "unused". These appear in the same order as in the struct. - */ + /* + * Mark all as "unused". These appear in the same order as in the struct. + */ #define BLANK(x) memset(x, ' ',sizeof(x)) - BLANK(ret->ident); - BLANK(ret->cmnt); - BLANK(ret->wpt_ident); - BLANK(ret->lnk_ident); - BLANK(ret->subclass); - BLANK(ret->name); - BLANK(ret->facility); - BLANK(ret->addr); - BLANK(ret->cross_road); - BLANK(ret->city); - BLANK(ret->rte_cmnt); - BLANK(ret->rte_ident); - BLANK(ret->rte_link_subclass); - BLANK(ret->rte_link_ident); - BLANK(ret->state); - BLANK(ret->cc); - - ret->facility[0] = 0; - ret->addr[0] = 0; - ret->wpt_ident[0] = 0; + BLANK(ret->ident); + BLANK(ret->cmnt); + BLANK(ret->wpt_ident); + BLANK(ret->lnk_ident); + BLANK(ret->subclass); + BLANK(ret->name); + BLANK(ret->facility); + BLANK(ret->addr); + BLANK(ret->cross_road); + BLANK(ret->city); + BLANK(ret->rte_cmnt); + BLANK(ret->rte_ident); + BLANK(ret->rte_link_subclass); + BLANK(ret->rte_link_ident); + BLANK(ret->state); + BLANK(ret->cc); + + ret->facility[0] = 0; + ret->addr[0] = 0; + ret->wpt_ident[0] = 0; #endif - - ret->lat = ret->lon = GPS_FLTMAX; - ret->dst = 0; - ret->smbl = ret->dspl = ret->colour = ret->alt = ret->prot = INT_MAX; - - ret->dst = 0; - ret->attr = 0x60; - for(i=0;i<7;++i) ret->subclass[i] = 0; - for(i=6;i<18;++i) ret->subclass[i] = 0xff; - - return ret; + + ret->lat = ret->lon = GPS_FLTMAX; + ret->dst = 0; + ret->smbl = ret->dspl = ret->colour = ret->alt = ret->prot = INT_MAX; + + ret->dst = 0; + ret->attr = 0x60; + for (i=0; i<7; ++i) { + ret->subclass[i] = 0; + } + for (i=6; i<18; ++i) { + ret->subclass[i] = 0xff; + } + + return ret; } @@ -290,9 +289,9 @@ GPS_PWay GPS_Way_New(void) void GPS_Way_Del(GPS_PWay *thys) { - xfree((void *)*thys); + xfree((void *)*thys); - return; + return; } /* @func GPS_Lap_New *********************************************** @@ -304,17 +303,16 @@ void GPS_Way_Del(GPS_PWay *thys) GPS_PLap GPS_Lap_New(void) { - GPS_PLap ret; - - if(!(ret=(GPS_PLap)calloc(1,sizeof(GPS_OLap)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Lap_New: Insufficient memory"); - fflush(stderr); - return NULL; - } - - return ret; + GPS_PLap ret; + + if (!(ret=(GPS_PLap)calloc(1,sizeof(GPS_OLap)))) { + perror("malloc"); + fprintf(stderr,"GPS_Lap_New: Insufficient memory"); + fflush(stderr); + return NULL; + } + + return ret; } @@ -330,9 +328,9 @@ GPS_PLap GPS_Lap_New(void) void GPS_Lap_Del(GPS_PLap *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } @@ -344,17 +342,16 @@ void GPS_Lap_Del(GPS_PLap *thys) **********************************************************************/ GPS_PCourse GPS_Course_New(void) { - GPS_PCourse ret; + GPS_PCourse ret; - if(!(ret=(GPS_PCourse)calloc(1,sizeof(GPS_OCourse)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse)calloc(1,sizeof(GPS_OCourse)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -369,9 +366,9 @@ GPS_PCourse GPS_Course_New(void) **********************************************************************/ void GPS_Course_Del(GPS_PCourse *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } /* @func GPS_Course_Lap_New *********************************************** @@ -383,17 +380,16 @@ void GPS_Course_Del(GPS_PCourse *thys) GPS_PCourse_Lap GPS_Course_Lap_New(void) { - GPS_PCourse_Lap ret; + GPS_PCourse_Lap ret; - if(!(ret=(GPS_PCourse_Lap)calloc(1,sizeof(GPS_OCourse_Lap)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_Lap_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse_Lap)calloc(1,sizeof(GPS_OCourse_Lap)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_Lap_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -409,9 +405,9 @@ GPS_PCourse_Lap GPS_Course_Lap_New(void) void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } /* @func GPS_Course_Point_New *********************************************** @@ -423,17 +419,16 @@ void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys) GPS_PCourse_Point GPS_Course_Point_New(void) { - GPS_PCourse_Point ret; + GPS_PCourse_Point ret; - if(!(ret=(GPS_PCourse_Point)calloc(1,sizeof(GPS_OCourse_Point)))) - { - perror("malloc"); - fprintf(stderr,"GPS_Course_Point_New: Insufficient memory"); - fflush(stderr); - return NULL; - } + if (!(ret=(GPS_PCourse_Point)calloc(1,sizeof(GPS_OCourse_Point)))) { + perror("malloc"); + fprintf(stderr,"GPS_Course_Point_New: Insufficient memory"); + fflush(stderr); + return NULL; + } - return ret; + return ret; } @@ -449,7 +444,7 @@ GPS_PCourse_Point GPS_Course_Point_New(void) void GPS_Course_Point_Del(GPS_PCourse_Point *thys) { - free((void *)*thys); + free((void *)*thys); - return; + return; } diff --git a/gpsbabel/jeeps/gpsmem.h b/gpsbabel/jeeps/gpsmem.h index 91292f7d6..e5f29ee39 100644 --- a/gpsbabel/jeeps/gpsmem.h +++ b/gpsbabel/jeeps/gpsmem.h @@ -9,24 +9,24 @@ extern "C" #include "gps.h" -GPS_PPacket GPS_Packet_New(void); -void GPS_Packet_Del(GPS_PPacket *thys); -GPS_PPvt_Data GPS_Pvt_New(void); -void GPS_Pvt_Del(GPS_PPvt_Data *thys); -GPS_PAlmanac GPS_Almanac_New(void); -void GPS_Almanac_Del(GPS_PAlmanac *thys); -GPS_PTrack GPS_Track_New(void); -void GPS_Track_Del(GPS_PTrack *thys); -GPS_PWay GPS_Way_New(void); -void GPS_Way_Del(GPS_PWay *thys); -GPS_PLap GPS_Lap_New(void); -void GPS_Lap_Del(GPS_PLap *thys); -GPS_PCourse GPS_Course_New(void); -void GPS_Course_Del(GPS_PCourse *thys); -GPS_PCourse_Lap GPS_Course_Lap_New(void); -void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys); -GPS_PCourse_Point GPS_Course_Point_New(void); -void GPS_Course_Point_Del(GPS_PCourse_Point *thys); + GPS_PPacket GPS_Packet_New(void); + void GPS_Packet_Del(GPS_PPacket *thys); + GPS_PPvt_Data GPS_Pvt_New(void); + void GPS_Pvt_Del(GPS_PPvt_Data *thys); + GPS_PAlmanac GPS_Almanac_New(void); + void GPS_Almanac_Del(GPS_PAlmanac *thys); + GPS_PTrack GPS_Track_New(void); + void GPS_Track_Del(GPS_PTrack *thys); + GPS_PWay GPS_Way_New(void); + void GPS_Way_Del(GPS_PWay *thys); + GPS_PLap GPS_Lap_New(void); + void GPS_Lap_Del(GPS_PLap *thys); + GPS_PCourse GPS_Course_New(void); + void GPS_Course_Del(GPS_PCourse *thys); + GPS_PCourse_Lap GPS_Course_Lap_New(void); + void GPS_Course_Lap_Del(GPS_PCourse_Lap *thys); + GPS_PCourse_Point GPS_Course_Point_New(void); + void GPS_Course_Point_Del(GPS_PCourse_Point *thys); #endif diff --git a/gpsbabel/jeeps/gpsproj.c b/gpsbabel/jeeps/gpsproj.c index c2634b370..8d1478864 100644 --- a/gpsbabel/jeeps/gpsproj.c +++ b/gpsbabel/jeeps/gpsproj.c @@ -2,20 +2,20 @@ ** @source JEEPS projection functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Feb 04 2000 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -47,116 +47,119 @@ ** @return [void] ************************************************************************/ void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double dlambda; - double phis; - double phic; - double e; - double esq; - double esqs; - double omesqs2; - - double a2; - double b2; - double q; - double q0; - double q1; - double q2; - double m1; - double m2; - double n; - double phi0s; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double ess; - double om0; - double m1sq; - double C; - double nq; - double nq0; - double rho; - double rho0; - double theta; - - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - dlambda = lambda - M0; - if(dlambda > GPS_PI) - dlambda -= ((double)2.0 * GPS_PI); - if(dlambda < -GPS_PI) - dlambda += ((double)2.0 * GPS_PI); - - phis = sin(phi); - phic = cos(phi); - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - - phi0s = sin(phi0); - ess = e * phi0s; - om0 = ((double)1.0 - ess*ess); - q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - om0 = ((double)1.0 - ess*ess); - m1 = phi1c/pow(om0,(double)0.5); - q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - - m1sq = m1*m1; - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - om0 = ((double)1.0 - ess*ess); - m2 = phi2c/pow(om0,(double)0.5); - q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - n = (m1sq - m2*m2) / (q2-q1); - } - else - n = phi1s; - - C = m1sq + n*q1; - nq0 = n * q0; - if(C < nq0) - rho0 = (double)0.; - else - rho0 = (a/n) * pow(C-nq0,(double)0.5); - - - esqs = e * phis; - omesqs2 = ((double)1.0 - esqs*esqs); - q = ((double)1.0 - esq) * (phis / omesqs2-((double)1.0/(e+e)) * - log(((double)1.0-esqs)/((double)1.0+esqs))); - nq = n*q; - if(C GPS_PI) { + dlambda -= ((double)2.0 * GPS_PI); + } + if (dlambda < -GPS_PI) { + dlambda += ((double)2.0 * GPS_PI); + } + + phis = sin(phi); + phic = cos(phi); + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + + phi0s = sin(phi0); + ess = e * phi0s; + om0 = ((double)1.0 - ess*ess); + q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + om0 = ((double)1.0 - ess*ess); + m1 = phi1c/pow(om0,(double)0.5); + q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + + m1sq = m1*m1; + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } else { + n = phi1s; + } + + C = m1sq + n*q1; + nq0 = n * q0; + if (C < nq0) { + rho0 = (double)0.; + } else { + rho0 = (a/n) * pow(C-nq0,(double)0.5); + } + + + esqs = e * phis; + omesqs2 = ((double)1.0 - esqs*esqs); + q = ((double)1.0 - esq) * (phis / omesqs2-((double)1.0/(e+e)) * + log(((double)1.0-esqs)/((double)1.0+esqs))); + nq = n*q; + if (C1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - om0 = ((double)1.0 - ess*ess); - m2 = phi2c/pow(om0,(double)0.5); - q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * - log(((double)1.0-ess)/((double)1.0+ess))); - n = (m1sq - m2*m2) / (q2-q1); + double po2; + double rho; + double rho0; + double C; + double a2; + double b2; + double esq; + double e; + double phi0s; + double q0; + double q1; + double q2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double m1; + double m1sq; + double m2; + double n; + double nq0; + + double dx; + double dy; + double rhom; + double q; + double qc; + double qd2; + double rhon; + double lat; + double dphi; + double phis; + double ess; + double om0; + double theta; + double tol; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + M0 = GPS_Math_Deg_To_Rad(M0); + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + + phi0s = sin(phi0); + ess = e * phi0s; + om0 = ((double)1.0 - ess*ess); + q0 = ((double)1.0 - esq) * (phi0s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + om0 = ((double)1.0 - ess*ess); + m1 = phi1c/pow(om0,(double)0.5); + q1 = ((double)1.0 - esq) * (phi1s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + + m1sq = m1*m1; + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + om0 = ((double)1.0 - ess*ess); + m2 = phi2c/pow(om0,(double)0.5); + q2 = ((double)1.0 - esq) * (phi2s / om0-((double)1.0/(e+e)) * + log(((double)1.0-ess)/((double)1.0+ess))); + n = (m1sq - m2*m2) / (q2-q1); + } else { + n = phi1s; + } + + C = m1sq + n*q1; + nq0 = n * q0; + if (C < nq0) { + rho0 = (double)0.; + } else { + rho0 = (a/n) * pow(C-nq0,(double)0.5); + } + + + dphi = (double) 1.0; + theta = (double) 0.0; + tol = (double) 4.85e-10; + po2 = (double)GPS_PI / (double)2.0; + + dy = N-N0; + dx = E-E0; + rhom = rho0-dy; + rho = pow(dx*dx+rhom*rhom,(double)0.5); + + if (n<0.0) { + rho *= (double)-1.0; + dx *= (double)-1.0; + dy *= (double)-1.0; + rhom *= (double)-1.0; + } + + if (rho) { + theta = atan2(dx,rhom); + } + rhon = rho*n; + q = (C - (rhon*rhon) / a2) / n; + qc = (double)1.0 - ((double)1.0 / (e+e)) * + log(((double)1.0-e)/((double)1.0+e)); + if (fabs(fabs(qc)-fabs(q))>1.9e-6) { + qd2 = q/(double)2.0; + if (qd2>1.0) { + *phi = po2; + } else if (qd2<-1.0) { + *phi = -po2; + } else { + lat = asin(qd2); + if (e<1.0e-10) { + *phi = lat; + } else { + while (fabs(dphi)>tol) { + phis = sin(lat); + ess = e*phis; + om0 = ((double)1.0 - ess*ess); + dphi = (om0*om0) / ((double)2.0*cos(lat))* + (q/((double)1.0-esq) - phis / om0 + + (log(((double)1.0-ess)/((double)1.0+ess)) / + (e+e))); + lat += dphi; + } + *phi = lat; + } + + if (*phi > po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } } - else - n = phi1s; - - C = m1sq + n*q1; - nq0 = n * q0; - if(C < nq0) - rho0 = (double)0.; - else - rho0 = (a/n) * pow(C-nq0,(double)0.5); - - - dphi = (double) 1.0; - theta = (double) 0.0; - tol = (double) 4.85e-10; - po2 = (double)GPS_PI / (double)2.0; - - dy = N-N0; - dx = E-E0; - rhom = rho0-dy; - rho = pow(dx*dx+rhom*rhom,(double)0.5); - - if(n<0.0) - { - rho *= (double)-1.0; - dx *= (double)-1.0; - dy *= (double)-1.0; - rhom *= (double)-1.0; + } else { + if (q>=0.0) { + *phi = po2; + } else { + *phi = -po2; } - - if(rho) - theta = atan2(dx,rhom); - rhon = rho*n; - q = (C - (rhon*rhon) / a2) / n; - qc = (double)1.0 - ((double)1.0 / (e+e)) * - log(((double)1.0-e)/((double)1.0+e)); - if(fabs(fabs(qc)-fabs(q))>1.9e-6) - { - qd2 = q/(double)2.0; - if(qd2>1.0) - *phi = po2; - else if(qd2<-1.0) - *phi = -po2; - else - { - lat = asin(qd2); - if(e<1.0e-10) - *phi = lat; - else - { - while(fabs(dphi)>tol) - { - phis = sin(lat); - ess = e*phis; - om0 = ((double)1.0 - ess*ess); - dphi = (om0*om0) / ((double)2.0*cos(lat))* - (q/((double)1.0-esq) - phis / om0 + - (log(((double)1.0-ess)/((double)1.0+ess)) / - (e+e))); - lat += dphi; - } - *phi = lat; - } - - if(*phi > po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - } - } - else - { - if(q>=0.0) - *phi = po2; - else - *phi = -po2; - } - - *lambda = M0 + theta / n; - if(*lambda > GPS_PI) - *lambda -= GPS_PI * (double)2.0; - if(*lambda < -GPS_PI) - *lambda += GPS_PI * (double)2.0; - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda = -GPS_PI; - - *phi = GPS_Math_Rad_To_Deg(*phi); - *lambda = GPS_Math_Rad_To_Deg(*lambda); - - return; + } + + *lambda = M0 + theta / n; + if (*lambda > GPS_PI) { + *lambda -= GPS_PI * (double)2.0; + } + if (*lambda < -GPS_PI) { + *lambda += GPS_PI * (double)2.0; + } + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda = -GPS_PI; + } + + *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + + return; } @@ -376,112 +378,111 @@ void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double po2; - double po4; - double a2; - double b2; - double phi0s; - double e; - double esq; - double ed2; - double ess; - double t0; - double t1; - double t2; - double m1; - double m2; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double n; - double F; - double Fa; - double rho; - double rho0; - double phis; - double t; - double theta; - double dphi; - - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - - po2 = (double)GPS_PI / (double)2.0; - po4 = (double)GPS_PI / (double)4.0; - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - ed2 = e / (double)2.0; - - phi0s = sin(phi0); - ess = e * phi0s; - t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); - t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); - t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - n = log(m1/m2) / log(t1/t2); - } - else - n = phi1s; - - F = m1 / (n*pow(t1,n)); - Fa = F*a; - - rho0 = pow(t0,n) * Fa; - - if(fabs(fabs(phi)-po2)>1.0e-10) - { - phis = sin(phi); - ess = e * phis; - t = tan(po4-phi/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - rho = pow(t,n) * Fa; - } - else - { - if((phi*n)<=(double)0.0) - return; - rho = (double)0.0; + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + double dphi; + + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } else { + n = phi1s; + } + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + if (fabs(fabs(phi)-po2)>1.0e-10) { + phis = sin(phi); + ess = e * phis; + t = tan(po4-phi/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + rho = pow(t,n) * Fa; + } else { + if ((phi*n)<=(double)0.0) { + return; } - - dphi = lambda - M0; - if(dphi>GPS_PI) - dphi -= (double)GPS_PI * (double)2.0; - if(dphi<-GPS_PI) - dphi += (double)GPS_PI * (double)2.0; - theta = dphi*n; - - *E = rho * sin(theta) + E0; - *N = rho0 - rho * cos(theta) + N0; - - return; + rho = (double)0.0; + } + + dphi = lambda - M0; + if (dphi>GPS_PI) { + dphi -= (double)GPS_PI * (double)2.0; + } + if (dphi<-GPS_PI) { + dphi += (double)GPS_PI * (double)2.0; + } + theta = dphi*n; + + *E = rho * sin(theta) + E0; + *N = rho0 - rho * cos(theta) + N0; + + return; } @@ -508,151 +509,150 @@ void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b) + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b) { - double po2; - double po4; - double a2; - double b2; - double phi0s; - double e; - double esq; - double ed2; - double ess; - double t0; - double t1; - double t2; - double m1; - double m2; - double phi1s; - double phi1c; - double phi2s; - double phi2c; - double n; - double F; - double Fa; - double rho; - double rho0; - double phis; - double t; - double theta; - - double dx; - double dy; - double rhom; - double lat; - double tlat; - double tol; - - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi1 = GPS_Math_Deg_To_Rad(phi1); - phi2 = GPS_Math_Deg_To_Rad(phi2); - M0 = GPS_Math_Deg_To_Rad(M0); - - - po2 = (double)GPS_PI / (double)2.0; - po4 = (double)GPS_PI / (double)4.0; - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - ed2 = e / (double)2.0; - - phi0s = sin(phi0); - ess = e * phi0s; - t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - + double po2; + double po4; + double a2; + double b2; + double phi0s; + double e; + double esq; + double ed2; + double ess; + double t0; + double t1; + double t2; + double m1; + double m2; + double phi1s; + double phi1c; + double phi2s; + double phi2c; + double n; + double F; + double Fa; + double rho; + double rho0; + double phis; + double t; + double theta; + + double dx; + double dy; + double rhom; + double lat; + double tlat; + double tol; + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi1 = GPS_Math_Deg_To_Rad(phi1); + phi2 = GPS_Math_Deg_To_Rad(phi2); + M0 = GPS_Math_Deg_To_Rad(M0); + + + po2 = (double)GPS_PI / (double)2.0; + po4 = (double)GPS_PI / (double)4.0; + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + ed2 = e / (double)2.0; + + phi0s = sin(phi0); + ess = e * phi0s; + t0 = tan(po4-phi0/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + + phi1s = sin(phi1); + phi1c = cos(phi1); + ess = e * phi1s; + m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); + t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + + if (fabs(phi1-phi2)>1.0e-10) { + phi2s = sin(phi2); + phi2c = cos(phi2); + ess = e * phi2s; + m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); + t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / + ((double)1.0+ess),ed2); + n = log(m1/m2) / log(t1/t2); + } else { + n = phi1s; + } + + F = m1 / (n*pow(t1,n)); + Fa = F*a; + + rho0 = pow(t0,n) * Fa; + + tlat = theta = (double)0.0; + tol = (double)4.85e-10; + + dx = E - E0; + dy = N - N0; + rhom = rho0 - dy; + rho = pow(dx*dx + rhom*rhom,(double)0.5); + + if (n<0.0) { + rhom *= (double)-1.0; + dy *= (double)-1.0; + dx *= (double)-1.0; + rho *= (double)-1.0; + } + + if (rho) { + theta = atan2(dx,rhom); + t = pow(rho/Fa,(double)1.0/n); + lat = po2 - (double)2.0*atan(t); + while (fabs(lat-tlat)>tol) { + tlat = lat; + phis = sin(lat); + ess = e * phis; + lat = po2 - (double)2.0 * atan(t*pow(((double)1.0-ess) / + ((double)1.0+ess), + e / (double)2.0)); + } + *phi = lat; + *lambda = theta/n + M0; - phi1s = sin(phi1); - phi1c = cos(phi1); - ess = e * phi1s; - m1 = phi1c / pow(((double)1.0-ess*ess),(double)0.5); - t1 = tan(po4-phi1/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - - if(fabs(phi1-phi2)>1.0e-10) - { - phi2s = sin(phi2); - phi2c = cos(phi2); - ess = e * phi2s; - m2 = phi2c / pow(((double)1.0-ess*ess),(double)0.5); - t2 = tan(po4-phi2/(double)2.0) / pow(((double)1.0-ess) / - ((double)1.0+ess),ed2); - n = log(m1/m2) / log(t1/t2); + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + if (*lambda>GPS_PI) { + *lambda -= (double)GPS_PI * (double)2.0; } - else - n = phi1s; - - F = m1 / (n*pow(t1,n)); - Fa = F*a; - - rho0 = pow(t0,n) * Fa; - - tlat = theta = (double)0.0; - tol = (double)4.85e-10; - - dx = E - E0; - dy = N - N0; - rhom = rho0 - dy; - rho = pow(dx*dx + rhom*rhom,(double)0.5); - - if(n<0.0) - { - rhom *= (double)-1.0; - dy *= (double)-1.0; - dx *= (double)-1.0; - rho *= (double)-1.0; + if (*lambda<-GPS_PI) { + *lambda += (double)GPS_PI * (double)2.0; } - if(rho) - { - theta = atan2(dx,rhom); - t = pow(rho/Fa,(double)1.0/n); - lat = po2 - (double)2.0*atan(t); - while(fabs(lat-tlat)>tol) - { - tlat = lat; - phis = sin(lat); - ess = e * phis; - lat = po2 - (double)2.0 * atan(t*pow(((double)1.0-ess) / - ((double)1.0+ess), - e / (double)2.0)); - } - *phi = lat; - *lambda = theta/n + M0; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - if(*lambda>GPS_PI) - *lambda -= (double)GPS_PI * (double)2.0; - if(*lambda<-GPS_PI) - *lambda += (double)GPS_PI * (double)2.0; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda = -GPS_PI; + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda = -GPS_PI; } - else - { - if(n>0.0) - *phi = po2; - else - *phi = -po2; - *lambda = M0; + } else { + if (n>0.0) { + *phi = po2; + } else { + *phi = -po2; } + *lambda = M0; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -676,51 +676,54 @@ void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) + double *N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double R; - double e2; - double e4; - double e6; - double p2; - double po2; - double phis; - double dlam; - - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - - if(M0>GPS_PI) - M0 -= p2; - - phis = sin((double)0.8 * phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - *E = R*dlam+E0; - *N = (R/(double)1.6) * log(((double)1.0+phis) / ((double)1.0-phis)) + N0; - - return; + double a2; + double b2; + double R; + double e2; + double e4; + double e6; + double p2; + double po2; + double phis; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + + if (M0>GPS_PI) { + M0 -= p2; + } + + phis = sin((double)0.8 * phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + *E = R*dlam+E0; + *N = (R/(double)1.6) * log(((double)1.0+phis) / ((double)1.0-phis)) + N0; + + return; } @@ -744,62 +747,67 @@ void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double R; - double e; - double e2; - double e4; - double e6; - double p2; - double po2; - double dx; - double dy; - - dx = E - E0; - dy = N - N0; - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - e = pow(e2,(double)0.5); - - R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - if(M0>GPS_PI) - M0 -= p2; - - *phi = atan(sinh((double)0.8*dy/R)) / (double)0.8; - *lambda = M0+dx/R; - - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double R; + double e; + double e2; + double e4; + double e6; + double p2; + double po2; + double dx; + double dy; + + dx = E - E0; + dy = N - N0; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + e = pow(e2,(double)0.5); + + R = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + if (M0>GPS_PI) { + M0 -= p2; + } + + *phi = atan(sinh((double)0.8*dy/R)) / (double)0.8; + *lambda = M0+dx/R; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -824,127 +832,131 @@ void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) + double *N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double M1; - double m1; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double E1; - double E2; - double E3; - double E4; - double x; - double phi0s; - double lat; - double phi0c; - double phi0s2; - double phi0s4; - double phi0s6; - double as; - - double phis; - double phic; - double phis2; - double phis4; - double phis6; - double dlam; - double mm; - double MM; - double rho; - double EE; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - phi0s = sin(phi0); - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - phi0c = cos(phi0); - m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - M1 = a*(lat-phi0s2+phi0s4-phi0s6); - - x = pow((double)1.0-e2,(double)0.5); - E1 = ((double)1.0-x) / ((double)1.0+x); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - if(!phi0s) - as = (double)0.0; - else - as = a*m1/phi0s; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double M1; + double m1; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double E1; + double E2; + double E3; + double E4; + double x; + double phi0s; + double lat; + double phi0c; + double phi0s2; + double phi0s4; + double phi0s6; + double as; + + double phis; + double phic; + double phis2; + double phis4; + double phis6; + double dlam; + double mm; + double MM; + double rho; + double EE; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + phi0s = sin(phi0); + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + if (!phi0s) { + as = (double)0.0; + } else { + as = a*m1/phi0s; + } + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + + tol = (double)0.0001; + if (!(phi-phi0) && (((po2-tol)GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - phi0c = cos(phi0); - m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - M1 = a*(lat-phi0s2+phi0s4-phi0s6); - - x = pow((double)1.0-e2,(double)0.5); - E1 = ((double)1.0-x) / ((double)1.0+x); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - A0 = (double)3.0*E1/(double)2.0-(double)27.0*E3/(double)32.0; - A1 = (double)21.0*E2/(double)16.0-(double)55.0*E4/(double)32.0; - A2 = (double)151.0*E3/(double)96.0; - A3 = (double)1097.0*E4/(double)512.0; - if(!phi0s) - as = (double)0.0; - else - as = a*m1/phi0s; - - - dx = E - E0; - dy = N - N0; - asdy = as - dy; - rho = pow(dx*dx+asdy*asdy,(double)0.5); - if(phi0<(double)0.0) - rho=-rho; - MM = as+M1-rho; - - mu = MM / (a*c0); - smu2 = A0 * sin((double)2.0*mu); - smu4 = A1 * sin((double)4.0*mu); - smu6 = A2 * sin((double)6.0*mu); - smu8 = A3 * sin((double)8.0*mu); - *phi = mu+smu2+smu4+smu6+smu8; - - tol = (double)0.00001; - if(((po2-tol)GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + phi0c = cos(phi0); + m1 = phi0c/ pow(((double)1.0-e2*phi0s*phi0s),(double)0.5); + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + M1 = a*(lat-phi0s2+phi0s4-phi0s6); + + x = pow((double)1.0-e2,(double)0.5); + E1 = ((double)1.0-x) / ((double)1.0+x); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + A0 = (double)3.0*E1/(double)2.0-(double)27.0*E3/(double)32.0; + A1 = (double)21.0*E2/(double)16.0-(double)55.0*E4/(double)32.0; + A2 = (double)151.0*E3/(double)96.0; + A3 = (double)1097.0*E4/(double)512.0; + if (!phi0s) { + as = (double)0.0; + } else { + as = a*m1/phi0s; + } + + + dx = E - E0; + dy = N - N0; + asdy = as - dy; + rho = pow(dx*dx+asdy*asdy,(double)0.5); + if (phi0<(double)0.0) { + rho=-rho; + } + MM = as+M1-rho; + + mu = MM / (a*c0); + smu2 = A0 * sin((double)2.0*mu); + smu4 = A1 * sin((double)4.0*mu); + smu6 = A2 * sin((double)6.0*mu); + smu8 = A3 * sin((double)8.0*mu); + *phi = mu+smu2+smu4+smu6+smu8; + + tol = (double)0.00001; + if (((po2-tol)po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + *lambda = M0 + rho * (atan2(dx,asdy)) / (a * mm); + } + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -1140,126 +1157,128 @@ void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) + double *N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double phis; - double phic; - double phit; - double phis2; - double phis4; - double phis6; - double RD; - double dlam; - double NN; - double TT; - double WW; - double WW2; - double WW3; - double WW4; - double WW5; - double CC; - double MM; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - phic = cos(phi); - phit = tan(phi); - RD = pow((double)1.-e2*phis*phis,(double).5); - NN = a/RD; - TT = phit*phit; - WW = dlam*phic; - WW2 = WW*WW; - WW3 = WW*WW2; - WW4 = WW*WW3; - WW5 = WW*WW4; - CC = e2*phic*phic/om0; - lat = c0*phi; - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (lat-phis2+phis4-phis6); - - *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* - (TT*WW5/(double)120.)) + E0; - *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * - WW4/(double)24.) + N0; - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double om0; + double A0; + double A1; + double A2; + double A3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + double lat; + double x; + double E1; + double E2; + double E3; + double E4; + + double phis; + double phic; + double phit; + double phis2; + double phis4; + double phis6; + double RD; + double dlam; + double NN; + double TT; + double WW; + double WW2; + double WW3; + double WW4; + double WW5; + double CC; + double MM; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + te4 = (double)3.0 * e4; + j = (double)45. * e6 / (double)1024.; + c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; + c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + + lat = c0*phi0; + phi0s2 = c1 * sin((double)2.*phi0); + phi0s4 = c2 * sin((double)4.*phi0); + phi0s6 = c3 * sin((double)6.*phi0); + AM0 = a * (lat-phi0s2+phi0s4-phi0s6); + + om0 = (double)1.0 - e2; + x = pow(om0,(double)0.5); + E1 = ((double)1.0 - x) / ((double)1.0 + x); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + phic = cos(phi); + phit = tan(phi); + RD = pow((double)1.-e2*phis*phis,(double).5); + NN = a/RD; + TT = phit*phit; + WW = dlam*phic; + WW2 = WW*WW; + WW3 = WW*WW2; + WW4 = WW*WW3; + WW5 = WW*WW4; + CC = e2*phic*phic/om0; + lat = c0*phi; + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (lat-phis2+phis4-phis6); + + *E = NN*(WW-(TT*WW3/(double)6.)-((double)8.-TT+(double)8.*CC)* + (TT*WW5/(double)120.)) + E0; + *N = MM-AM0+NN*phit*((WW2/(double)2.)+((double)5.-TT+(double)6.*CC) * + WW4/(double)24.) + N0; + return; } @@ -1284,161 +1303,160 @@ void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double om0; - double A0; - double A1; - double A2; - double A3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - double lat; - double x; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double mu; - double mus2; - double mus4; - double mus6; - double mus8; - double M1; - double phi1; - double phi1s; - double phi1c; - double phi1t; - double T; - double T1; - double N1; - double R1; - double RD; - double DD; - double D2; - double D3; - double D4; - double D5; - double tol; - - M0 = GPS_Math_Deg_To_Rad(M0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - te4 = (double)3.0 * e4; - j = (double)45. * e6 / (double)1024.; - c0 = (double)1.0-e2/(double)4.-te4/(double)64.-(double)5.*e6/(double)256.; - c1 = (double)3.*e2/(double)8.+te4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - - lat = c0*phi0; - phi0s2 = c1 * sin((double)2.*phi0); - phi0s4 = c2 * sin((double)4.*phi0); - phi0s6 = c3 * sin((double)6.*phi0); - AM0 = a * (lat-phi0s2+phi0s4-phi0s6); - - om0 = (double)1.0 - e2; - x = pow(om0,(double)0.5); - E1 = ((double)1.0 - x) / ((double)1.0 + x); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - - tol = (double)1.e-5; - - dx = E - E0; - dy = N - N0; - M1 = AM0 + dy; - mu = M1 / (a*c0); - mus2 = A0 * sin((double)2.*mu); - mus4 = A1 * sin((double)4.*mu); - mus6 = A2 * sin((double)6.*mu); - mus8 = A3 * sin((double)8.*mu); - phi1 = mu + mus2 + mus4 + mus6 + mus8; - - if((((po2-tol)po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; } - else if((((-po2-tol)po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -1463,73 +1481,76 @@ void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) + double *N, double phi0, double M0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double k0; - double ak0; - double k2; - double c0; - double c1; - double c2; - double p2; - double po2; - double phi0s; - double phi0c; - - double dlam; - double qq; - double x; - double phis; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi0 = GPS_Math_Deg_To_Rad(phi0); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - c2 = (double)761.*e6/(double)45360.; - - phi0s = sin(phi0); - phi0c = cos(phi0); - k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); - ak0 = a*k0; - k2 = k0 * (double)2.; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - phis = sin(phi); - x = e * phis; - qq = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* - log(((double)1.-x)/((double)1.+x))); - *E = ak0 * dlam + E0; - *N = a * qq / k2 + N0; - - return; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dlam; + double qq; + double x; + double phis; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi0 = GPS_Math_Deg_To_Rad(phi0); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + phis = sin(phi); + x = e * phis; + qq = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + *E = ak0 * dlam + E0; + *N = a * qq / k2 + N0; + + return; } @@ -1554,103 +1575,109 @@ void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double k0; - double ak0; - double k2; - double c0; - double c1; - double c2; - double p2; - double po2; - double phi0s; - double phi0c; - - double dx; - double dy; - double qp; - double bt; - double phis; - double i; - double x; - double bs2; - double bs4; - double bs6; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - c2 = (double)761.*e6/(double)45360.; - - phi0s = sin(phi0); - phi0c = cos(phi0); - k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); - ak0 = a*k0; - k2 = k0 * (double)2.; - - dx = E - E0; - dy = N - N0; - phis = sin(po2); - x = e*phis; - qp = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* - log(((double)1.-x)/((double)1.+x))); - i = k2*dy/(a*qp); - if(i>(double)1.) - i=(double)1.; - else if(i<(double)-1.) - i=(double)-1.; - bt = asin(i); - bs2 = c0 * sin((double)2.*bt); - bs4 = c1 * sin((double)4.*bt); - bs6 = c2 * sin((double)6.*bt); - - *phi = bt+bs2+bs4+bs6; - *lambda = M0 + dx/ak0; - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double k0; + double ak0; + double k2; + double c0; + double c1; + double c2; + double p2; + double po2; + double phi0s; + double phi0c; + + double dx; + double dy; + double qp; + double bt; + double phis; + double i; + double x; + double bs2; + double bs4; + double bs6; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + c0 = e2/(double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + c1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + c2 = (double)761.*e6/(double)45360.; + + phi0s = sin(phi0); + phi0c = cos(phi0); + k0 = phi0c / pow((double)1.-e2*phi0s*phi0s,(double).5); + ak0 = a*k0; + k2 = k0 * (double)2.; + + dx = E - E0; + dy = N - N0; + phis = sin(po2); + x = e*phis; + qp = ((double)1.-e2)*(phis/((double)1.-x*x)-((double)1./((double)2.*e))* + log(((double)1.-x)/((double)1.+x))); + i = k2*dy/(a*qp); + if (i>(double)1.) { + i=(double)1.; + } else if (i<(double)-1.) { + i=(double)-1.; + } + bt = asin(i); + bs2 = c0 * sin((double)2.*bt); + bs4 = c1 * sin((double)4.*bt); + bs6 = c2 * sin((double)6.*bt); + + *phi = bt+bs2+bs4+bs6; + *lambda = M0 + dx/ak0; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -1674,77 +1701,79 @@ void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b) + double *N, double M0, double E0, double N0, + double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra0; - double Ra1; - double po2; - double p2; - - double Ra; - - double phis; - double theta; - double dtheta; - double thetas; - double thetac; - double n; - double dlam; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Ra0 = Ra * (double)0.4222382; - Ra1 = Ra * (double)1.3265004; - - theta = phi / (double)2.; - dtheta = (double)1.; - tol = (double)4.85e-10; - phis = sin(phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - while(fabs(dtheta)>tol) - { - thetas = sin(theta); - thetac = cos(theta); - n = theta+thetas*thetac+(double)2.*thetas; - dtheta = -(n-((double)2.+po2)*phis) / - ((double)2.*thetac*((double)1.+thetac)); - theta += dtheta; - } + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + + double phis; + double theta; + double dtheta; + double thetas; + double thetac; + double n; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + theta = phi / (double)2.; + dtheta = (double)1.; + tol = (double)4.85e-10; + phis = sin(phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + while (fabs(dtheta)>tol) { + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + dtheta = -(n-((double)2.+po2)*phis) / + ((double)2.*thetac*((double)1.+thetac)); + theta += dtheta; + } - *E = Ra0*dlam*((double)1.+cos(theta))+E0; - *N = Ra1*sin(theta)+N0; + *E = Ra0*dlam*((double)1.+cos(theta))+E0; + *N = Ra1*sin(theta)+N0; - return; + return; } @@ -1768,85 +1797,91 @@ void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra0; - double Ra1; - double po2; - double p2; - - double Ra; - double theta; - double thetas; - double thetac; - double n; - double dx; - double dy; - double i; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Ra0 = Ra * (double)0.4222382; - Ra1 = Ra * (double)1.3265004; - - dx = E - E0; - dy = N - N0; - i = dy/Ra1; - if(i>(double)1.) - i=(double)1.; - else if(i<(double)-1.) - i=(double)-1.; - - theta = asin(i); - thetas = sin(theta); - thetac = cos(theta); - n = theta+thetas*thetac+(double)2.*thetas; - - *phi = asin(n/((double)2. + po2)); - *lambda = M0 + dx / (Ra0*((double)1.+thetac)); - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra0; + double Ra1; + double po2; + double p2; + + double Ra; + double theta; + double thetas; + double thetac; + double n; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Ra0 = Ra * (double)0.4222382; + Ra1 = Ra * (double)1.3265004; + + dx = E - E0; + dy = N - N0; + i = dy/Ra1; + if (i>(double)1.) { + i=(double)1.; + } else if (i<(double)-1.) { + i=(double)-1.; + } + + theta = asin(i); + thetas = sin(theta); + thetac = cos(theta); + n = theta+thetas*thetac+(double)2.*thetas; + + *phi = asin(n/((double)2. + po2)); + *lambda = M0 + dx / (Ra0*((double)1.+thetac)); + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } - + @@ -1869,70 +1904,72 @@ void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b) + double *N, double M0, double E0, double N0, + double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rsq; - double IRa; - double po2; - double p2; - - double phis; - double theta; - double dtheta; - double dlam; - double tol; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Rsq = Ra/pow((double)2.+GPS_PI,(double).5); - IRa = (double)1./Rsq; - - phis = sin(phi); - theta = phi; - dtheta = (double)1.; - tol = (double)4.85e-10; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - while(fabs(dtheta)>tol) - { - dtheta = -(theta+sin(theta)-((double)1.+po2)*phis) / - ((double)1.+cos(theta)); - theta += dtheta; - } - - *E = Rsq*dlam*((double)1.+cos(theta))+E0; - *N = (double)2.*Rsq*theta+N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rsq; + double IRa; + double po2; + double p2; + + double phis; + double theta; + double dtheta; + double dlam; + double tol; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + phis = sin(phi); + theta = phi; + dtheta = (double)1.; + tol = (double)4.85e-10; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + while (fabs(dtheta)>tol) { + dtheta = -(theta+sin(theta)-((double)1.+po2)*phis) / + ((double)1.+cos(theta)); + theta += dtheta; + } + + *E = Rsq*dlam*((double)1.+cos(theta))+E0; + *N = (double)2.*Rsq*theta+N0; + + return; } @@ -1956,79 +1993,85 @@ void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double Rsq; - double IRa; - double po2; - double p2; - - double Ra; - double theta; - double dx; - double dy; - double i; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.; - po2 = (double)GPS_PI / (double)2.; - - if(M0>GPS_PI) - M0-=p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2) / a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - Rsq = Ra/pow((double)2.+GPS_PI,(double).5); - IRa = (double)1./Rsq; - - - dx = E - E0; - dy = N - N0; - theta = IRa * dy / (double)2.; - i = (theta+sin(theta)) / ((double)1.+po2); - if(i>(double)1.) - *phi = po2; - else if(i<(double)-1.) - *phi = -po2; - else - *phi= asin(i); - *lambda = M0 + IRa * dx / ((double)1.+cos(theta)); - - if(*phi>po2) - *phi=po2; - else if(*phi<-po2) - *phi=-po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double Rsq; + double IRa; + double po2; + double p2; + + double Ra; + double theta; + double dx; + double dy; + double i; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.; + po2 = (double)GPS_PI / (double)2.; + + if (M0>GPS_PI) { + M0-=p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2) / a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + Rsq = Ra/pow((double)2.+GPS_PI,(double).5); + IRa = (double)1./Rsq; + + + dx = E - E0; + dy = N - N0; + theta = IRa * dy / (double)2.; + i = (theta+sin(theta)) / ((double)1.+po2); + if (i>(double)1.) { + *phi = po2; + } else if (i<(double)-1.) { + *phi = -po2; + } else { + *phi= asin(i); + } + *lambda = M0 + IRa * dx / ((double)1.+cos(theta)); + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } - + @@ -2052,53 +2095,56 @@ void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) + double *N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rac; - double phi0c; - - double dlam; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - phi0c = cos(phi0); - Rac = Ra * phi0c; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - *E = Rac * dlam + E0; - *N = Ra * phi + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + *E = Rac * dlam + E0; + *N = Ra * phi + N0; + + return; } @@ -2123,72 +2169,78 @@ void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double Rac; - double phi0c; - - double dx; - double dy; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- - (double)67.*e6/(double)3024.); - phi0c = cos(phi0); - Rac = Ra * phi0c; - - dx = E - E0; - dy = N - N0; - - if(!Rac) - *lambda = (double)0.; - else - *lambda = M0 + dx / Rac; - - *phi = dy/Ra; - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double Rac; + double phi0c; + + double dx; + double dy; + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.- + (double)67.*e6/(double)3024.); + phi0c = cos(phi0); + Rac = Ra * phi0c; + + dx = E - E0; + dy = N - N0; + + if (!Rac) { + *lambda = (double)0.; + } else { + *lambda = M0 + dx / Rac; + } + + *phi = dy/Ra; + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -2212,110 +2264,113 @@ void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) + double *N, double M0, double E0, + double N0, double a, double b) { - double po2; - double p2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double pRa; - - double gg; - double pp; - double pp2; - double gm0; - double ppa; - double thetai; - double theta; - double thetas; - double thetac; - double qq; - double tol; - double aa; - double aa2; - double dlam; - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - pRa = (double)GPS_PI * Ra; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - tol = (double)1.0e-5; - - if(!phi) - { - *N = (double)0.0; - *E = Ra*dlam+E0; + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double gg; + double pp; + double pp2; + double gm0; + double ppa; + double thetai; + double theta; + double thetas; + double thetac; + double qq; + double tol; + double aa; + double aa2; + double dlam; + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + tol = (double)1.0e-5; + + if (!phi) { + *N = (double)0.0; + *E = Ra*dlam+E0; + } else if (!dlam || (((po2-tol)(double)1.) { + thetai=(double)1.; + } else if (thetai<(double)-1.) { + thetai=(double)-1.; + } + + theta = asin(thetai); + *E = 0; + *N = pRa * tan(theta/(double)2.) * N0; + if (phi<(double)0.0) { + *N *= (double)-1.; } - else if(!dlam || (((po2-tol)(double)1.) - thetai=(double)1.; - else if(thetai<(double)-1.) - thetai=(double)-1.; - - theta = asin(thetai); - *E = 0; - *N = pRa * tan(theta/(double)2.) * N0; - if(phi<(double)0.0) - *N *= (double)-1.; + } else { + aa = (double).5*fabs((double)GPS_PI/dlam - dlam/(double)GPS_PI); + thetai = fabs(((double)2./(double)GPS_PI) * phi); + if (thetai>(double)1.) { + thetai=(double)1.; + } else if (thetai<(double)-1.) { + thetai=(double)-1.; + } + + theta = asin(thetai); + thetas = sin(theta); + thetac = cos(theta); + gg = thetac/(thetas+thetac-(double)1.); + pp = gg*((double)2./thetas-(double)1.); + aa2 = aa*aa; + pp2 = pp*pp; + gm0 = gg-pp2; + ppa = pp2+aa2; + qq = aa2+gg; + *E = pRa*(aa*gm0+pow(aa2*gm0*gm0-ppa*(gg*gg-pp2),(double).5))/ppa+E0; + if (dlam<(double)0.0) { + *E *= (double)-1.; } - else - { - aa = (double).5*fabs((double)GPS_PI/dlam - dlam/(double)GPS_PI); - thetai = fabs(((double)2./(double)GPS_PI) * phi); - if(thetai>(double)1.) - thetai=(double)1.; - else if(thetai<(double)-1.) - thetai=(double)-1.; - - theta = asin(thetai); - thetas = sin(theta); - thetac = cos(theta); - gg = thetac/(thetas+thetac-(double)1.); - pp = gg*((double)2./thetas-(double)1.); - aa2 = aa*aa; - pp2 = pp*pp; - gm0 = gg-pp2; - ppa = pp2+aa2; - qq = aa2+gg; - *E = pRa*(aa*gm0+pow(aa2*gm0*gm0-ppa*(gg*gg-pp2),(double).5))/ppa+E0; - if(dlam<(double)0.0) - *E *= (double)-1.; - *N = pRa*(pp*qq-aa*pow((aa2+(double)1.)*ppa-qq*qq,(double).5))/ppa+N0; - if(phi<(double)0.0) - *N *= (double)-1.; + *N = pRa*(pp*qq-aa*pow((aa2+(double)1.)*ppa-qq*qq,(double).5))/ppa+N0; + if (phi<(double)0.0) { + *N *= (double)-1.; } + } - return; + return; } @@ -2339,118 +2394,122 @@ void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double po2; - double p2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double pRa; - - double dx; - double dy; - double xx; - double xx2; - double yy; - double yy2; - double tyy2; - double xpy; - double c1; - double c2; - double c3; - double c3c3; - double co; - double dd; - double a1; - double m1; - double i; - double theta; - - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - pRa = (double)GPS_PI * Ra; - - - dx = E - E0; - dy = N - N0; - xx = dx/pRa; - yy = dy/pRa; - xx2 = xx*xx; - yy2 = yy*yy; - xpy = xx2+yy2; - tyy2 = yy2*(double)2.; - - if(!N) - *phi=(double)0.0; - else - { - c1 = -fabs(yy)*((double)1.+xpy); - c2 = c1-tyy2+xx2; - c3 = (double)-2.*c1+(double)1.+tyy2+xpy*xpy; - co = c2/((double)3.*c3); - c3c3 = c3*c3; - dd = yy2/c3+(((double)2.*c2*c2*c2)/(c3c3*c3)-((double)9.*c1*c2)/ - c3c3)/(double)27.; - a1 = (c1-c2*co)/c3; - m1 = (double)2.* pow(-((double)1./(double)3.)*a1,(double).5); - i = (double)3.*dd/(a1*m1); - if((i>(double)1.)||(i<(double)-1.)) - *phi=po2; - else - { - theta = ((double)1./(double)3.)*acos((double)3.*dd/(a1*m1)); - *phi = (double)GPS_PI*(-m1*cos(theta+(double)GPS_PI/(double)3.)- - co); - } + double po2; + double p2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double pRa; + + double dx; + double dy; + double xx; + double xx2; + double yy; + double yy2; + double tyy2; + double xpy; + double c1; + double c2; + double c3; + double c3c3; + double co; + double dd; + double a1; + double m1; + double i; + double theta; + + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + Ra = a*((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + pRa = (double)GPS_PI * Ra; + + + dx = E - E0; + dy = N - N0; + xx = dx/pRa; + yy = dy/pRa; + xx2 = xx*xx; + yy2 = yy*yy; + xpy = xx2+yy2; + tyy2 = yy2*(double)2.; + + if (!N) { + *phi=(double)0.0; + } else { + c1 = -fabs(yy)*((double)1.+xpy); + c2 = c1-tyy2+xx2; + c3 = (double)-2.*c1+(double)1.+tyy2+xpy*xpy; + co = c2/((double)3.*c3); + c3c3 = c3*c3; + dd = yy2/c3+(((double)2.*c2*c2*c2)/(c3c3*c3)-((double)9.*c1*c2)/ + c3c3)/(double)27.; + a1 = (c1-c2*co)/c3; + m1 = (double)2.* pow(-((double)1./(double)3.)*a1,(double).5); + i = (double)3.*dd/(a1*m1); + if ((i>(double)1.)||(i<(double)-1.)) { + *phi=po2; + } else { + theta = ((double)1./(double)3.)*acos((double)3.*dd/(a1*m1)); + *phi = (double)GPS_PI*(-m1*cos(theta+(double)GPS_PI/(double)3.)- + co); } - - if(N<(double)0.0) - *phi *= (double)-1.0; - - if(!xx) - *lambda = M0; - else - *lambda = (double)GPS_PI * (xpy-(double)1.+ - pow((double)1.+((double)2.*xx2-tyy2)+xpy*xpy,(double).5)) / - ((double)2.*xx) + M0; - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + } + + if (N<(double)0.0) { + *phi *= (double)-1.0; + } + + if (!xx) { + *lambda = M0; + } else + *lambda = (double)GPS_PI * (xpy-(double)1.+ + pow((double)1.+((double)2.*xx2-tyy2)+xpy*xpy,(double).5)) / + ((double)2.*xx) + M0; + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -2475,123 +2534,118 @@ void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double lambda1, - double E0, double N0, double a, double b) + double *N, double phi1, double lambda1, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4=(double)0.; - double e; - double eo2; - double sh; - double mc; - double tc=(double)0.; - double amc=(double)0.; - double ta; - double phi1s; - double phi1c; - double es; - double op; - double om; - double pe; - double polat; - double polon; - - double dlam; - double phis; - double t; - double rho; - - - lambda1 = GPS_Math_Deg_To_Rad(lambda1); - phi1 = GPS_Math_Deg_To_Rad(phi1); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - - ta = a * (double)2.0; - if(lambda1>GPS_PI) - lambda1 -= p2; - if(phi1<(double)0.0) - { - sh=(double)1.0; - polat = -phi1; - polon = -lambda1; - } - else - { - sh=(double)0.0; - polat = phi1; - polon = lambda1; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dlam; + double phis; + double t; + double rho; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if (lambda1>GPS_PI) { + lambda1 -= p2; + } + if (phi1<(double)0.0) { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } else { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } else { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + + if (fabs(fabs(phi)-po2)<(double)1.0e-10) { + *E = *N = (double)0.0; + } else { + if (sh) { + phi *= (double)-1.0; + lambda *= (double)-1.0; } - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e = pow(e2,(double).5); - eo2 = e/(double)2.; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - { - phi1s = sin(polat); - phi1c = cos(polat); - es = e*phi1s; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - mc = phi1c / pow((double)1.-es*es,(double).5); - amc = mc * a; - tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + dlam = lambda - polon; + if (dlam>GPS_PI) { + dlam -= p2; } - else - { - op = (double)1. + e; - om = (double)1. - e; - e4 = pow(pow(op,op)*pow(om,om),(double).5); + if (dlam<-GPS_PI) { + dlam += p2; + } + phis = sin(phi); + es = e * phis; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + t = tan(((double)GPS_PI/(double)4.)-phi/(double)2.) / pe; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + rho = amc * t / tc; + } else { + rho = ta * t / e4; } - - - - if(fabs(fabs(phi)-po2)<(double)1.0e-10) - *E = *N = (double)0.0; - else - { - if(sh) - { - phi *= (double)-1.0; - lambda *= (double)-1.0; - } - - dlam = lambda - polon; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - phis = sin(phi); - es = e * phis; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - t = tan(((double)GPS_PI/(double)4.)-phi/(double)2.) / pe; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - rho = amc * t / tc; - else - rho = ta * t / e4; - *E = rho * sin(dlam) + E0; - - if(sh) - { - *E *= (double)-1.; - *N = rho * cos(dlam) + N0; - } - else - *N = -rho * cos(dlam) + N0; + *E = rho * sin(dlam) + E0; + + if (sh) { + *E *= (double)-1.; + *N = rho * cos(dlam) + N0; + } else { + *N = -rho * cos(dlam) + N0; } - - return; + } + + return; } @@ -2616,144 +2670,138 @@ void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double lambda1, - double E0, double N0, double a, double b) + double *lambda, double phi1, double lambda1, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4=(double)0.; - double e; - double eo2; - double sh; - double mc; - double tc=(double)0.; - double amc=(double)0.; - double ta; - double phi1s; - double phi1c; - double es; - double op; - double om; - double pe; - double polat; - double polon; - - double dx; - double dy; - double t; - double rho; - double PHI; - double PHIS; - double TPHI; - - - lambda1 = GPS_Math_Deg_To_Rad(lambda1); - phi1 = GPS_Math_Deg_To_Rad(phi1); - - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - - ta = a * (double)2.0; - if(lambda1>GPS_PI) - lambda1 -= p2; - if(phi1<(double)0.0) - { - sh=(double)1.0; - polat = -phi1; - polon = -lambda1; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4=(double)0.; + double e; + double eo2; + double sh; + double mc; + double tc=(double)0.; + double amc=(double)0.; + double ta; + double phi1s; + double phi1c; + double es; + double op; + double om; + double pe; + double polat; + double polon; + + double dx; + double dy; + double t; + double rho; + double PHI; + double PHIS; + double TPHI; + + + lambda1 = GPS_Math_Deg_To_Rad(lambda1); + phi1 = GPS_Math_Deg_To_Rad(phi1); + + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + + ta = a * (double)2.0; + if (lambda1>GPS_PI) { + lambda1 -= p2; + } + if (phi1<(double)0.0) { + sh=(double)1.0; + polat = -phi1; + polon = -lambda1; + } else { + sh=(double)0.0; + polat = phi1; + polon = lambda1; + } + + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e = pow(e2,(double).5); + eo2 = e/(double)2.; + + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + phi1s = sin(polat); + phi1c = cos(polat); + es = e*phi1s; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + mc = phi1c / pow((double)1.-es*es,(double).5); + amc = mc * a; + tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + } else { + op = (double)1. + e; + om = (double)1. - e; + e4 = pow(pow(op,op)*pow(om,om),(double).5); + } + + + dx = E - E0; + dy = N - N0; + if (!dx && !dy) { + *phi = po2; + *lambda = polon; + } else { + if (sh) { + dx *= (double)-1.; + dy *= (double)-1.; } - else - { - sh=(double)0.0; - polat = phi1; - polon = lambda1; + rho = pow(dx*dx+dy*dy,(double).5); + if (fabs(fabs(polat)-po2)>(double)1.0e-10) { + t = rho * tc / amc; + } else { + t = rho * e4 / ta; } - - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e = pow(e2,(double).5); - eo2 = e/(double)2.; - - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - { - phi1s = sin(polat); - phi1c = cos(polat); - es = e*phi1s; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - mc = phi1c / pow((double)1.-es*es,(double).5); - amc = mc * a; - tc = tan(((double)GPS_PI/(double)4.)-polat/(double)2.) / pe; + TPHI = (double)0.0; + PHI = po2 - (double)2.*atan(t); + while (fabs(PHI-TPHI)>(double)1.0e-10) { + TPHI=PHI; + PHIS = sin(PHI); + es = e * PHIS; + pe = pow(((double)1.-es)/((double)1.+es),eo2); + PHI = po2 - (double)2. * atan(t*pe); } - else - { - op = (double)1. + e; - om = (double)1. - e; - e4 = pow(pow(op,op)*pow(om,om),(double).5); + *phi = PHI; + *lambda = polon + atan2(dx,-dy); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; } - - - dx = E - E0; - dy = N - N0; - if(!dx && !dy) - { - *phi = po2; - *lambda = polon; + + if (*lambda>GPS_PI) { + *lambda -= p2; } - else - { - if(sh) - { - dx *= (double)-1.; - dy *= (double)-1.; - } - rho = pow(dx*dx+dy*dy,(double).5); - if(fabs(fabs(polat)-po2)>(double)1.0e-10) - t = rho * tc / amc; - else - t = rho * e4 / ta; - TPHI = (double)0.0; - PHI = po2 - (double)2.*atan(t); - while(fabs(PHI-TPHI)>(double)1.0e-10) - { - TPHI=PHI; - PHIS = sin(PHI); - es = e * PHIS; - pe = pow(((double)1.-es)/((double)1.+es),eo2); - PHI = po2 - (double)2. * atan(t*pe); - } - *phi = PHI; - *lambda = polon + atan2(dx,-dy); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if (*lambda<-GPS_PI) { + *lambda += p2; } - if(sh) - { - *phi *= (double)-1.; - *lambda *= (double)1.; + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; } + } + if (sh) { + *phi *= (double)-1.; + *lambda *= (double)1.; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -2777,68 +2825,70 @@ void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) + double *N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double Ra; - double sRa2; - double sRa8; - - double ps; - double dlam; - double theta; - double thetap; - double d; - double tol; - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - sRa2 = pow((double)2.,(double).5) * Ra; - sRa8 = pow((double)8.,(double).5) * Ra; - - if(M0>GPS_PI) - M0 -= p2; - - ps = sin(phi) * (double)GPS_PI; - d = (double)0.1745329; - tol = (double)4.85e-10; - thetap = phi; - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - while(fabs(d)>tol) - { - d = -(thetap+sin(thetap)-ps)/((double)1.+cos(thetap)); - thetap += d; - } - theta = thetap / (double)2.; - *E = (sRa8/(double)GPS_PI) * dlam * cos(theta) + E0; - *N = sRa2 * sin(theta) + N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double ps; + double dlam; + double theta; + double thetap; + double d; + double tol; + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if (M0>GPS_PI) { + M0 -= p2; + } + + ps = sin(phi) * (double)GPS_PI; + d = (double)0.1745329; + tol = (double)4.85e-10; + thetap = phi; + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + while (fabs(d)>tol) { + d = -(thetap+sin(thetap)-ps)/((double)1.+cos(thetap)); + thetap += d; + } + theta = thetap / (double)2.; + *E = (sRa8/(double)GPS_PI) * dlam * cos(theta) + E0; + *N = sRa2 * sin(theta) + N0; + + return; } @@ -2862,84 +2912,88 @@ void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double Ra; - double sRa2; - double sRa8; - - double dx; - double dy; - double theta=(double)0.; - double tt; - double i; - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- - (double)67.0*e6/(double)3024.0); - sRa2 = pow((double)2.,(double).5) * Ra; - sRa8 = pow((double)8.,(double).5) * Ra; - - if(M0>GPS_PI) - M0 -= p2; - - dx = E - E0; - dy = N - N0; - i = dy/sRa2; - if(fabs(i)>(double)1.) - { - *phi = po2; - if(N<(double)0.0) - *phi *= (double)-1.; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double Ra; + double sRa2; + double sRa8; + + double dx; + double dy; + double theta=(double)0.; + double tt; + double i; + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + Ra = a*((double)1.0-e2/(double)6.0-(double)17.0*e4/(double)360.0- + (double)67.0*e6/(double)3024.0); + sRa2 = pow((double)2.,(double).5) * Ra; + sRa8 = pow((double)8.,(double).5) * Ra; + + if (M0>GPS_PI) { + M0 -= p2; + } + + dx = E - E0; + dy = N - N0; + i = dy/sRa2; + if (fabs(i)>(double)1.) { + *phi = po2; + if (N<(double)0.0) { + *phi *= (double)-1.; } - else - { - theta = asin(i); - tt = theta * (double)2.; - *phi = asin((tt+sin(tt))/(double)GPS_PI); - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; + } else { + theta = asin(i); + tt = theta * (double)2.; + *phi = asin((tt+sin(tt))/(double)GPS_PI); + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; } + } - if(fabs(fabs(*phi)-po2)<(double)1.0e-10) - *lambda = M0; - else - *lambda = M0 + (double)GPS_PI * dx / (sRa8 * cos(theta)); + if (fabs(fabs(*phi)-po2)<(double)1.0e-10) { + *lambda = M0; + } else { + *lambda = M0 + (double)GPS_PI * dx / (sRa8 * cos(theta)); + } - if(*lambda>GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; + if (*lambda>GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); - return; + return; } @@ -2964,62 +3018,65 @@ void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b) + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double phi0s; - double phi0c; - - double phis; - double phic; - double dlam; - double clc; - double cc; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - phi0s = sin(phi0); - phi0c = cos(phi0); - - dlam = lambda - lambda0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - - phis = sin(phi); - phic = cos(phi); - clc = phic * cos(dlam); - cc = phi0s * phis + phi0c * clc; - - *E = Ra * phic * sin(dlam) + E0; - *N = Ra * (phi0c * phis - phi0s * clc) + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double phis; + double phic; + double dlam; + double clc; + double cc; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + dlam = lambda - lambda0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + + phis = sin(phi); + phic = cos(phi); + clc = phic * cos(dlam); + cc = phi0s * phis + phi0c * clc; + + *E = Ra * phic * sin(dlam) + E0; + *N = Ra * (phi0c * phis - phi0s * clc) + N0; + + return; } @@ -3044,97 +3101,101 @@ void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double Ra; - double phi0s; - double phi0c; - - double dx; - double dy; - double rho; - double adod; - double ror; - double cc; - double ccs; - double ccc; - - - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* - e6/(double)3024.); - phi0s = sin(phi0); - phi0c = cos(phi0); - - - dx = E - E0; - dy = N - N0; - adod = atan(dx/dy); - rho = pow(dx*dx+dy*dy,(double).5); - if(!rho) - { - *phi = phi0; - *lambda = lambda0; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double Ra; + double phi0s; + double phi0c; + + double dx; + double dy; + double rho; + double adod; + double ror; + double cc; + double ccs; + double ccc; + + + + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + Ra = a * ((double)1.-e2/(double)6.-(double)17.*e4/(double)360.-(double)67.* + e6/(double)3024.); + phi0s = sin(phi0); + phi0c = cos(phi0); + + + dx = E - E0; + dy = N - N0; + adod = atan(dx/dy); + rho = pow(dx*dx+dy*dy,(double).5); + if (!rho) { + *phi = phi0; + *lambda = lambda0; + } else { + ror = rho/Ra; + if (ror>(double)1.) { + ror=(double)1.; + } else if (ror<(double)-1.) { + ror=(double)-1.; } - else - { - ror = rho/Ra; - if(ror>(double)1.) - ror=(double)1.; - else if(ror<(double)-1.) - ror=(double)-1.; - cc = asin(ror); - ccs = sin(cc); - ccc = cos(cc); - *phi = asin(ccc*phi0s+(dy*ccs*phi0c/rho)); - if(phi0==po2) - *lambda = lambda0 - adod; - else if(phi0==-po2) - *lambda = lambda0 + adod; - else - *lambda = lambda0+atan(dx*ccs/(rho*phi0c*ccc-dy*phi0s*ccs)); + cc = asin(ror); + ccs = sin(cc); + ccc = cos(cc); + *phi = asin(ccc*phi0s+(dy*ccs*phi0c/rho)); + if (phi0==po2) { + *lambda = lambda0 - adod; + } else if (phi0==-po2) { + *lambda = lambda0 + adod; + } else { + *lambda = lambda0+atan(dx*ccs/(rho*phi0c*ccc-dy*phi0s*ccs)); } - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + } + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3159,99 +3220,99 @@ void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b) + double *N, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - - double phis; - double phis2; - double phis4; - double phis6; - double dlam; - double NN; - double NNot; - double MM; - double EE; - double lat; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - - if(!phi) - { - *E = a * dlam + E0; - *N = -AM0 + N0; - } - else - { - NN = a / pow((double)1.-e2*phis*phis,(double).5); - NNot = NN / tan(phi); - lat = c0 * phi; - phis2 = c1 * sin((double)2.0*phi); - phis4 = c2 * sin((double)4.0*phi); - phis6 = c3 * sin((double)6.0*phi); - MM = a*(lat-phis2+phis4-phis6); - EE = dlam *phis; - *E = NNot * sin(EE) + E0; - *N = MM - AM0 + NNot * ((double)1.-cos(EE)) + N0; - } - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e6; + double AM0; + double c0; + double c1; + double c2; + double c3; + double j; + double te4; + double phi0s2; + double phi0s4; + double phi0s6; + + double phis; + double phis2; + double phis4; + double phis6; + double dlam; + double NN; + double NNot; + double MM; + double EE; + double lat; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + + if (!phi) { + *E = a * dlam + E0; + *N = -AM0 + N0; + } else { + NN = a / pow((double)1.-e2*phis*phis,(double).5); + NNot = NN / tan(phi); + lat = c0 * phi; + phis2 = c1 * sin((double)2.0*phi); + phis4 = c2 * sin((double)4.0*phi); + phis6 = c3 * sin((double)6.0*phi); + MM = a*(lat-phis2+phis4-phis6); + EE = dlam *phis; + *E = NNot * sin(EE) + E0; + *N = MM - AM0 + NNot * ((double)1.-cos(EE)) + N0; + } + + return; } @@ -3276,143 +3337,145 @@ void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e6; - double AM0; - double c0; - double c1; - double c2; - double c3; - double j; - double te4; - double phi0s2; - double phi0s4; - double phi0s6; - - double dx; - double dy; - double dxoa; - double AA; - double BB; - double CC=(double)0.; - double PHIn; - double PHId; - double PHIs; - double PHI; - double PHIs2; - double PHIs4; - double PHIs6; - double Mn; - double Mnp; - double Ma; - double AAMa; - double mpb; - double AAmin; - double tol; - double lat; - - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - tol = (double)1.0e-12; - - dx = E - E0; - dy = N - N0; - dxoa = dx/a; - if((((-AM0-(double)1.)GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + tol = (double)1.0e-12; + + dx = E - E0; + dy = N - N0; + dxoa = dx/a; + if ((((-AM0-(double)1.)tol) { + PHIs = sin(PHIn); + CC = pow((double)1.-e2*PHIs*PHIs,(double).5) * tan(PHIn); + PHI = PHIn * c0; + PHIs2 = c1 * sin((double)2.0*PHIn); + PHIs4 = c2 * sin((double)4.0*PHIn); + PHIs6 = c3 * sin((double)6.0*PHIn); + Mn = a*(PHI-PHIs2+PHIs4-PHIs6); + Mnp = c0 - (double)2.*c1*cos((double)2.*PHIn)+(double)4.*c2* + cos((double)4.*PHIn)-(double)6.*c3*cos((double)6.*PHIn); + Ma = Mn / a; + AAMa = AA * Ma; + mpb = Ma*Ma+BB; + AAmin = AA - Ma; + PHId = (AAMa*CC+AAmin-(double).5*mpb*CC)/ + (e2*PHIs2*(mpb-(double)2.*AAMa) / + (double)4.*CC+AAmin*(CC*Mnp-(double)2./PHIs2)-Mnp); + PHIn -= PHId; } - else - { - AA = (AM0+dy) / a; - BB = dxoa * dxoa + (AA*AA); - PHIn = AA; - PHId = (double)1.; - - while(fabs(PHId)>tol) - { - PHIs = sin(PHIn); - CC = pow((double)1.-e2*PHIs*PHIs,(double).5) * tan(PHIn); - PHI = PHIn * c0; - PHIs2 = c1 * sin((double)2.0*PHIn); - PHIs4 = c2 * sin((double)4.0*PHIn); - PHIs6 = c3 * sin((double)6.0*PHIn); - Mn = a*(PHI-PHIs2+PHIs4-PHIs6); - Mnp = c0 - (double)2.*c1*cos((double)2.*PHIn)+(double)4.*c2* - cos((double)4.*PHIn)-(double)6.*c3*cos((double)6.*PHIn); - Ma = Mn / a; - AAMa = AA * Ma; - mpb = Ma*Ma+BB; - AAmin = AA - Ma; - PHId = (AAMa*CC+AAmin-(double).5*mpb*CC)/ - (e2*PHIs2*(mpb-(double)2.*AAMa) / - (double)4.*CC+AAmin*(CC*Mnp-(double)2./PHIs2)-Mnp); - PHIn -= PHId; - } - *phi = PHIn; - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if((((po2-(double).00001)po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; } - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; + if ((((po2-(double).00001)GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } - return; + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3436,93 +3499,96 @@ void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b) + double *N, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double c0; - double c1; - double c2; - double c3; - double A1; - double A0; - double A2; - double A3; - double E1; - double E2; - double E3; - double E4; - double j; - double om0; - double som0; - - double phis; - double phis2; - double phis4; - double phis6; - double mm; - double MM; - double dlam; - - - phi = GPS_Math_Deg_To_Rad(phi); - lambda = GPS_Math_Deg_To_Rad(lambda); - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - j = (double)45.*e6/(double)1024.; - c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* - e6/(double)256.; - c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - om0 = (double)1. - e2; - som0 = pow(om0,(double).5); - E1 = ((double)1.-som0)/((double)1.+som0); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - if(M0>GPS_PI) - M0 -= p2; - - phis = sin(phi); - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam-=p2; - if(dlam<-GPS_PI) - dlam+=p2; - - mm = pow((double)1.-e2*phis*phis,(double).5); - phis2 = c1 * sin((double)2.*phi); - phis4 = c2 * sin((double)4.*phi); - phis6 = c3 * sin((double)6.*phi); - MM = a * (c0*phi-phis2+phis4-phis6); - - - - *E = a*dlam*cos(phi)/mm+E0; - *N = MM + N0; - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double phis; + double phis2; + double phis4; + double phis6; + double mm; + double MM; + double dlam; + + + phi = GPS_Math_Deg_To_Rad(phi); + lambda = GPS_Math_Deg_To_Rad(lambda); + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + if (M0>GPS_PI) { + M0 -= p2; + } + + phis = sin(phi); + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam-=p2; + } + if (dlam<-GPS_PI) { + dlam+=p2; + } + + mm = pow((double)1.-e2*phis*phis,(double).5); + phis2 = c1 * sin((double)2.*phi); + phis4 = c2 * sin((double)4.*phi); + phis6 = c3 * sin((double)6.*phi); + MM = a * (c0*phi-phis2+phis4-phis6); + + + + *E = a*dlam*cos(phi)/mm+E0; + *N = MM + N0; + + return; } @@ -3546,108 +3612,111 @@ void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b) + double *lambda, double M0, double E0, + double N0, double a, double b) { - double a2; - double b2; - double e2; - double e4; - double e6; - double p2; - double po2; - double c0; - double c1; - double c2; - double c3; - double A1; - double A0; - double A2; - double A3; - double E1; - double E2; - double E3; - double E4; - double j; - double om0; - double som0; - - double dx; - double dy; - double mu; - double mu2s; - double mu4s; - double mu6s; - double mu8s; - double phis; - - - M0 = GPS_Math_Deg_To_Rad(M0); - - po2 = (double)GPS_PI / (double)2.0; - p2 = (double)GPS_PI * (double)2.0; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e4*e2; - - j = (double)45.*e6/(double)1024.; - c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* - e6/(double)256.; - c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; - c2 = (double)15.*e4/(double)256.+j; - c3 = (double)35.*e6/(double)3072.; - om0 = (double)1. - e2; - som0 = pow(om0,(double).5); - E1 = ((double)1.-som0)/((double)1.+som0); - E2 = E1*E1; - E3 = E1*E2; - E4 = E1*E3; - A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - A2 = (double)151.*E3/(double)96.; - A3 = (double)1097.*E4/(double)512.; - - - dx = E - E0; - dy = N - N0; - - mu = dy/(c0*a); - mu2s = A0 * sin((double)2.*mu); - mu4s = A1 * sin((double)4.*mu); - mu6s = A2 * sin((double)6.*mu); - mu8s = A3 * sin((double)8.*mu); - *phi = mu + mu2s + mu4s + mu6s + mu8s; - - if(*phi>po2) - *phi=po2; - else if (*phi<-po2) - *phi=-po2; - - if((((po2-(double)1.0e-8)GPS_PI) - *lambda-=p2; - if(*lambda<-GPS_PI) - *lambda+=p2; - - if(*lambda>GPS_PI) - *lambda=GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double a2; + double b2; + double e2; + double e4; + double e6; + double p2; + double po2; + double c0; + double c1; + double c2; + double c3; + double A1; + double A0; + double A2; + double A3; + double E1; + double E2; + double E3; + double E4; + double j; + double om0; + double som0; + + double dx; + double dy; + double mu; + double mu2s; + double mu4s; + double mu6s; + double mu8s; + double phis; + + + M0 = GPS_Math_Deg_To_Rad(M0); + + po2 = (double)GPS_PI / (double)2.0; + p2 = (double)GPS_PI * (double)2.0; + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e4*e2; + + j = (double)45.*e6/(double)1024.; + c0 = (double)1.-e2/(double)4.-(double)3.*e4/(double)64.-(double)5.* + e6/(double)256.; + c1 = (double)3.*e2/(double)8.+(double)3.*e4/(double)32.+j; + c2 = (double)15.*e4/(double)256.+j; + c3 = (double)35.*e6/(double)3072.; + om0 = (double)1. - e2; + som0 = pow(om0,(double).5); + E1 = ((double)1.-som0)/((double)1.+som0); + E2 = E1*E1; + E3 = E1*E2; + E4 = E1*E3; + A0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + A1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + A2 = (double)151.*E3/(double)96.; + A3 = (double)1097.*E4/(double)512.; + + + dx = E - E0; + dy = N - N0; + + mu = dy/(c0*a); + mu2s = A0 * sin((double)2.*mu); + mu4s = A1 * sin((double)4.*mu); + mu6s = A2 * sin((double)6.*mu); + mu8s = A3 * sin((double)8.*mu); + *phi = mu + mu2s + mu4s + mu6s + mu8s; + + if (*phi>po2) { + *phi=po2; + } else if (*phi<-po2) { + *phi=-po2; + } + + if ((((po2-(double)1.0e-8)GPS_PI) { + *lambda-=p2; + } + if (*lambda<-GPS_PI) { + *lambda+=p2; + } + + if (*lambda>GPS_PI) { + *lambda=GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -3672,175 +3741,175 @@ void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b) + double *N, double phi0, double M0, double E0, + double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double AM0; - double qp; - double om; - double oo; - double c0; - double c1; - double c2; - double c3; - double b0; - double b1; - double B2; - double b3; - double A0; - double A1; - double A2; - double sf; - double x; - double som; - double phis; - double j; - double te4; - double lat; - double phi0s2; - double phi0s4; - double phi0s6; - double E1; - double E2; - double E3; - double E4; - - double dlam; - double qq; - double qqo; - double bt; - double btc; - double PHI; - double PHIs2; - double PHIs4; - double PHIs6; - double bts2; - double bts4; - double bts6; - double PHIc; - double PHIcs; - double Mc; - - - - sf = (double)1.0; /* scale factor */ - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - om = (double)1.-e2; - som = pow(om,(double).5); - oo = (double)1./((double)2.*e); - - phis = sin(po2); - x = e * phis; - qp = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - - A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - A2 = (double)761.*e6/(double)45360.; - - E1 = ((double)1.0-som) / ((double)1.0+som); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - B2 = (double)151.*E3/(double)96.; - b3 = (double)1097.*E4/(double)512.; - - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - dlam = lambda - M0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - phis = sin(phi); - - if(phi==po2) - { - qq = qp; - qqo = (double)1.; - } - else - { - x = e * phis; - qq = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - qqo = qq/qp; - } - - if(qqo>(double)1.) - qqo = (double)1.; - else if(qqo<(double)-1.) - qqo = (double)-1.; - - bt = asin(qqo); - btc = atan(tan(bt)/cos(dlam)); - - if((fabs(btc)-po2)>(double)1.0e-8) - PHIc = btc; - else - { - bts2 = A0 * sin((double)2.0*btc); - bts4 = A1 * sin((double)4.0*btc); - bts6 = A2 * sin((double)6.0*btc); - PHIc = btc + bts2 + bts4 + bts6; - } - - PHIcs = sin(PHIc); - *E = a*cos(bt)*cos(PHIc)*sin(dlam)/(sf*cos(btc)* - pow((double)1.-e2*PHIcs*PHIcs, - (double).5)) + E0; - PHI = c0 * PHIc; - PHIs2 = c1 * sin((double)2.0*PHIc); - PHIs4 = c2 * sin((double)4.0*PHIc); - PHIs6 = c3 * sin((double)6.0*PHIc); - Mc = a*(PHI-PHIs2+PHIs4-PHIs6); - - *N = sf * (Mc-AM0) + N0; - - return; + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dlam; + double qq; + double qqo; + double bt; + double btc; + double PHI; + double PHIs2; + double PHIs4; + double PHIs6; + double bts2; + double bts4; + double bts6; + double PHIc; + double PHIcs; + double Mc; + + + + sf = (double)1.0; /* scale factor */ + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + dlam = lambda - M0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + phis = sin(phi); + + if (phi==po2) { + qq = qp; + qqo = (double)1.; + } else { + x = e * phis; + qq = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + qqo = qq/qp; + } + + if (qqo>(double)1.) { + qqo = (double)1.; + } else if (qqo<(double)-1.) { + qqo = (double)-1.; + } + + bt = asin(qqo); + btc = atan(tan(bt)/cos(dlam)); + + if ((fabs(btc)-po2)>(double)1.0e-8) { + PHIc = btc; + } else { + bts2 = A0 * sin((double)2.0*btc); + bts4 = A1 * sin((double)4.0*btc); + bts6 = A2 * sin((double)6.0*btc); + PHIc = btc + bts2 + bts4 + bts6; + } + + PHIcs = sin(PHIc); + *E = a*cos(bt)*cos(PHIc)*sin(dlam)/(sf*cos(btc)* + pow((double)1.-e2*PHIcs*PHIcs, + (double).5)) + E0; + PHI = c0 * PHIc; + PHIs2 = c1 * sin((double)2.0*PHIc); + PHIs4 = c2 * sin((double)4.0*PHIc); + PHIs6 = c3 * sin((double)6.0*PHIc); + Mc = a*(PHI-PHIs2+PHIs4-PHIs6); + + *N = sf * (Mc-AM0) + N0; + + return; } @@ -3865,182 +3934,189 @@ void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e; - double e2; - double e4; - double e6; - double AM0; - double qp; - double om; - double oo; - double c0; - double c1; - double c2; - double c3; - double b0; - double b1; - double B2; - double b3; - double A0; - double A1; - double A2; - double sf; - double x; - double som; - double phis; - double j; - double te4; - double lat; - double phi0s2; - double phi0s4; - double phi0s6; - double E1; - double E2; - double E3; - double E4; - - double dx; - double dy; - double bt; - double btc; - double btp; - double btcc; - double Mc; - double Muc; - double mus2; - double mus4; - double mus6; - double mus8; - double bts2; - double bts4; - double bts6; - double PHIc; - double Qc; - double Qco; - double t; - - - sf = (double)1.0; /* scale factor */ - - phi0 = GPS_Math_Deg_To_Rad(phi0); - M0 = GPS_Math_Deg_To_Rad(M0); - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(M0>GPS_PI) - M0 -= p2; - a2 = a*a; - b2 = b*b; - e2 = (a2-b2)/a2; - e4 = e2*e2; - e6 = e2*e4; - e = pow(e2,(double).5); - om = (double)1.-e2; - som = pow(om,(double).5); - oo = (double)1./((double)2.*e); - - phis = sin(po2); - x = e * phis; - qp = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - - A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* - e6/(double)5040.; - A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; - A2 = (double)761.*e6/(double)45360.; - - E1 = ((double)1.0-som) / ((double)1.0+som); - E2 = E1*E1; - E3 = E2*E1; - E4 = E3*E1; - - b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; - b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; - B2 = (double)151.*E3/(double)96.; - b3 = (double)1097.*E4/(double)512.; - - - j = (double)45.0*e6/(double)1024.0; - te4 = (double)3.0 * e4; - c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ - (double)256.0; - c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; - c2 = (double)15.0*e4/(double)256.0+j; - c3 = (double)35.0*e6/(double)3072.0; - - lat = c0 * phi0; - - phi0s2 = c1 * sin((double)2.0*phi0); - phi0s4 = c2 * sin((double)4.0*phi0); - phi0s6 = c3 * sin((double)6.0*phi0); - AM0 = a*(lat-phi0s2+phi0s4-phi0s6); - - - - dx = E - E0; - dy = N - N0; - Mc = AM0 + dy/sf; - Muc = Mc / (c0*a); - - mus2 = b0 * sin((double)2.0*Muc); - mus4 = b1 * sin((double)4.0*Muc); - mus6 = B2 * sin((double)6.0*Muc); - mus8 = b3 * sin((double)6.0*Muc); - PHIc = Muc + mus2 + mus4 + mus6 + mus8; - - phis = sin(PHIc); - x = e * phis; - Qc = om*(phis/((double)1.-e2*phis*phis)-oo* - log(((double)1.-x)/((double)1.+x))); - Qco = Qc/qp; - - if(Qco>(double)1.) - Qco = (double)1.; - else if(Qco<(double)-1.) - Qco = (double)-1.; - - btc = asin(Qco); - btcc = cos(btc); - t = sf*dx*btcc*pow((double)1.-e2*phis*phis,(double).5)/(a*cos(PHIc)); - if(t>(double)1.) - t=(double)1.; - else if(t<(double)-1.) - t=(double)-1.; - btp = -asin(t); - bt = asin(cos(btp)*sin(btc)); - - bts2 = A0 * sin((double)2.0*bt); - bts4 = A1 * sin((double)4.0*bt); - bts6 = A2 * sin((double)6.0*bt); - *phi = bt + bts2 + bts4 + bts6; - *lambda = M0 - atan(tan(btp)/btcc); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e; + double e2; + double e4; + double e6; + double AM0; + double qp; + double om; + double oo; + double c0; + double c1; + double c2; + double c3; + double b0; + double b1; + double B2; + double b3; + double A0; + double A1; + double A2; + double sf; + double x; + double som; + double phis; + double j; + double te4; + double lat; + double phi0s2; + double phi0s4; + double phi0s6; + double E1; + double E2; + double E3; + double E4; + + double dx; + double dy; + double bt; + double btc; + double btp; + double btcc; + double Mc; + double Muc; + double mus2; + double mus4; + double mus6; + double mus8; + double bts2; + double bts4; + double bts6; + double PHIc; + double Qc; + double Qco; + double t; + + + sf = (double)1.0; /* scale factor */ + + phi0 = GPS_Math_Deg_To_Rad(phi0); + M0 = GPS_Math_Deg_To_Rad(M0); + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (M0>GPS_PI) { + M0 -= p2; + } + a2 = a*a; + b2 = b*b; + e2 = (a2-b2)/a2; + e4 = e2*e2; + e6 = e2*e4; + e = pow(e2,(double).5); + om = (double)1.-e2; + som = pow(om,(double).5); + oo = (double)1./((double)2.*e); + + phis = sin(po2); + x = e * phis; + qp = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + + A0 = e2 / (double)3.+(double)31.*e4/(double)180.+(double)517.* + e6/(double)5040.; + A1 = (double)23.*e4/(double)360.+(double)251.*e6/(double)3780.; + A2 = (double)761.*e6/(double)45360.; + + E1 = ((double)1.0-som) / ((double)1.0+som); + E2 = E1*E1; + E3 = E2*E1; + E4 = E3*E1; + + b0 = (double)3.*E1/(double)2.-(double)27.*E3/(double)32.; + b1 = (double)21.*E2/(double)16.-(double)55.*E4/(double)32.; + B2 = (double)151.*E3/(double)96.; + b3 = (double)1097.*E4/(double)512.; + + + j = (double)45.0*e6/(double)1024.0; + te4 = (double)3.0 * e4; + c0 = (double)1.0-e2/(double)4.0-te4/(double)64.0-(double)5.0*e6/ + (double)256.0; + c1 = (double)3.0*e2/(double)8.0+te4/(double)32.0+j; + c2 = (double)15.0*e4/(double)256.0+j; + c3 = (double)35.0*e6/(double)3072.0; + + lat = c0 * phi0; + + phi0s2 = c1 * sin((double)2.0*phi0); + phi0s4 = c2 * sin((double)4.0*phi0); + phi0s6 = c3 * sin((double)6.0*phi0); + AM0 = a*(lat-phi0s2+phi0s4-phi0s6); + + + + dx = E - E0; + dy = N - N0; + Mc = AM0 + dy/sf; + Muc = Mc / (c0*a); + + mus2 = b0 * sin((double)2.0*Muc); + mus4 = b1 * sin((double)4.0*Muc); + mus6 = B2 * sin((double)6.0*Muc); + mus8 = b3 * sin((double)6.0*Muc); + PHIc = Muc + mus2 + mus4 + mus6 + mus8; + + phis = sin(PHIc); + x = e * phis; + Qc = om*(phis/((double)1.-e2*phis*phis)-oo* + log(((double)1.-x)/((double)1.+x))); + Qco = Qc/qp; + + if (Qco>(double)1.) { + Qco = (double)1.; + } else if (Qco<(double)-1.) { + Qco = (double)-1.; + } + + btc = asin(Qco); + btcc = cos(btc); + t = sf*dx*btcc*pow((double)1.-e2*phis*phis,(double).5)/(a*cos(PHIc)); + if (t>(double)1.) { + t=(double)1.; + } else if (t<(double)-1.) { + t=(double)-1.; + } + btp = -asin(t); + bt = asin(cos(btp)*sin(btc)); + + bts2 = A0 * sin((double)2.0*bt); + bts4 = A1 * sin((double)4.0*bt); + bts6 = A2 * sin((double)6.0*bt); + *phi = bt + bts2 + bts4 + bts6; + *lambda = M0 - atan(tan(btp)/btcc); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -4065,83 +4141,87 @@ void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b) + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e3; - double e; - double es; - double ab; - double bb; - double cb; - double db; - double ml; - double phi0s; - double sf; - - double dlam; - double ct; - double ex; - double tt; - double pt; - - - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - ml = ((double)GPS_PI*(double)89.5)/(double)180.; - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - es = (a2-b2)/a2; - e2 = es*es; - e3 = e2*es; - e4 = e3*es; - - e = pow(es,(double).5); - phi0s = sin(phi0); - sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); - - ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* - e4/(double)360.; - bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ - (double)811.*e4/(double)11520.; - cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; - db = (double)4279.*e4/(double)161280.; - - - - if(lambda>(double)GPS_PI) - lambda -= p2; - - dlam = lambda - lambda0; - if(dlam>GPS_PI) - dlam -= p2; - if(dlam<-GPS_PI) - dlam += p2; - - - ex = e * sin(phi); - tt = tan((double)GPS_PI/(double)4.+phi/(double)2.); - pt = pow((((double)1.-ex)/((double)1.+ex)),(e/(double)2.)); - - ct = tt * pt; - *N = sf * a * log(ct) + N0; - *E = sf * a * dlam + E0; - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dlam; + double ct; + double ex; + double tt; + double pt; + + + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + + + if (lambda>(double)GPS_PI) { + lambda -= p2; + } + + dlam = lambda - lambda0; + if (dlam>GPS_PI) { + dlam -= p2; + } + if (dlam<-GPS_PI) { + dlam += p2; + } + + + ex = e * sin(phi); + tt = tan((double)GPS_PI/(double)4.+phi/(double)2.); + pt = pow((((double)1.-ex)/((double)1.+ex)),(e/(double)2.)); + + ct = tt * pt; + *N = sf * a * log(ct) + N0; + *E = sf * a * dlam + E0; + + return; } @@ -4166,85 +4246,90 @@ void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, - double lambda0, double E0, double N0, - double a, double b) + double *lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b) { - double p2; - double po2; - double a2; - double b2; - double e2; - double e4; - double e3; - double e; - double es; - double ab; - double bb; - double cb; - double db; - double ml; - double phi0s; - double sf; - - double dx; - double dy; - double x; - - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - - ml = ((double)GPS_PI*(double)89.5)/(double)180.; - - p2 = (double)GPS_PI * (double)2.0; - po2 = (double)GPS_PI / (double)2.0; - if(lambda0>GPS_PI) - lambda0 -= p2; - a2 = a*a; - b2 = b*b; - es = (a2-b2)/a2; - e2 = es*es; - e3 = e2*es; - e4 = e3*es; - - e = pow(es,(double).5); - phi0s = sin(phi0); - sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); - - ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* - e4/(double)360.; - bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ - (double)811.*e4/(double)11520.; - cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; - db = (double)4279.*e4/(double)161280.; - - dx = E - E0; - dy = N - N0; - *lambda = lambda0 + dx / (sf*a); - x = (double)GPS_PI / (double)2. - - (double)2.*atan((double)1./exp(dy/(sf*a))); - *phi = x+ab*sin((double)2.*x)+bb*sin((double)4.*x)+cb*sin((double)6.*x) - + db*sin((double)8.*x); - - if(*phi>po2) - *phi = po2; - else if(*phi<-po2) - *phi = -po2; - - if(*lambda>GPS_PI) - *lambda -= p2; - if(*lambda<-GPS_PI) - *lambda += p2; - - if(*lambda>GPS_PI) - *lambda = GPS_PI; - else if(*lambda<-GPS_PI) - *lambda=-GPS_PI; - - *lambda = GPS_Math_Rad_To_Deg(*lambda); - *phi = GPS_Math_Rad_To_Deg(*phi); - - return; + double p2; + double po2; + double a2; + double b2; + double e2; + double e4; + double e3; + double e; + double es; + double ab; + double bb; + double cb; + double db; + double ml; + double phi0s; + double sf; + + double dx; + double dy; + double x; + + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + + ml = ((double)GPS_PI*(double)89.5)/(double)180.; + + p2 = (double)GPS_PI * (double)2.0; + po2 = (double)GPS_PI / (double)2.0; + if (lambda0>GPS_PI) { + lambda0 -= p2; + } + a2 = a*a; + b2 = b*b; + es = (a2-b2)/a2; + e2 = es*es; + e3 = e2*es; + e4 = e3*es; + + e = pow(es,(double).5); + phi0s = sin(phi0); + sf = (double)1. / (pow((double)1.-es*phi0s*phi0s,(double).5)/cos(phi0)); + + ab = es/(double)2.+(double)5.*e2/(double)24.+e3/(double)12.+(double)13.* + e4/(double)360.; + bb = (double)7.*e2/(double)48.+(double)29.*e3/(double)240.+ + (double)811.*e4/(double)11520.; + cb = (double)7.*e3/(double)120.+(double)81.*e4/(double)1120.; + db = (double)4279.*e4/(double)161280.; + + dx = E - E0; + dy = N - N0; + *lambda = lambda0 + dx / (sf*a); + x = (double)GPS_PI / (double)2. - + (double)2.*atan((double)1./exp(dy/(sf*a))); + *phi = x+ab*sin((double)2.*x)+bb*sin((double)4.*x)+cb*sin((double)6.*x) + + db*sin((double)8.*x); + + if (*phi>po2) { + *phi = po2; + } else if (*phi<-po2) { + *phi = -po2; + } + + if (*lambda>GPS_PI) { + *lambda -= p2; + } + if (*lambda<-GPS_PI) { + *lambda += p2; + } + + if (*lambda>GPS_PI) { + *lambda = GPS_PI; + } else if (*lambda<-GPS_PI) { + *lambda=-GPS_PI; + } + + *lambda = GPS_Math_Rad_To_Deg(*lambda); + *phi = GPS_Math_Rad_To_Deg(*phi); + + return; } @@ -4270,13 +4355,13 @@ void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ************************************************************************/ void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b) + double *N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) { - GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + GPS_Math_LatLon_To_EN(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -4302,13 +4387,13 @@ void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, ** @return [void] ************************************************************************/ void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b) + double *lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b) { - GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); - - return; + GPS_Math_EN_To_LatLon(E,N,phi,lambda,N0,E0,phi0,lambda0,F0,a,b); + + return; } @@ -4332,64 +4417,64 @@ void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, ** @return [void] ***************************************************************************/ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b) + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double c; - double ephi0p; - double phip; - double sphip; - double phid; - double slambda2; - double lambda1; - double lambda2; - double K; - double po4; - double w; - double R; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - lambda = GPS_Math_Deg_To_Rad(lambda); - phi = GPS_Math_Deg_To_Rad(phi); - - po4=GPS_PI/(double)4.0; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); - - ephi0p = asin(sin(phi0)/c); - - K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - lambda1 = c*(lambda-lambda0); - w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; - - - phip = (double)2. * (atan(exp(w)) - po4); - - sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); - phid = asin(sphip); - - slambda2 = cos(phip)*sin(lambda1) / cos(phid); - lambda2 = asin(slambda2); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - *N = R*log(tan(po4 + phid/(double)2.)) + N0; - *E = R*lambda2 + E0; - return; + double a2; + double b2; + double esq; + double e; + double c; + double ephi0p; + double phip; + double sphip; + double phid; + double slambda2; + double lambda1; + double lambda2; + double K; + double po4; + double w; + double R; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + lambda = GPS_Math_Deg_To_Rad(lambda); + phi = GPS_Math_Deg_To_Rad(phi); + + po4=GPS_PI/(double)4.0; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + c = sqrt(1+((esq*pow(cos(phi0),(double)4.))/((double)1.-esq))); + + ephi0p = asin(sin(phi0)/c); + + K = log(tan(po4+ephi0p/(double)2.)) - c*(log(tan(po4+phi0/(double)2.)) - + e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + lambda1 = c*(lambda-lambda0); + w = c*(log(tan(po4+phi/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi)) / ((double)1.-e*sin(phi)))) + K; + + + phip = (double)2. * (atan(exp(w)) - po4); + + sphip = cos(ephi0p) * sin(phip) - sin(ephi0p) * cos(phip) * cos(lambda1); + phid = asin(sphip); + + slambda2 = cos(phip)*sin(lambda1) / cos(phid); + lambda2 = asin(slambda2); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + *N = R*log(tan(po4 + phid/(double)2.)) + N0; + *E = R*lambda2 + E0; + return; } @@ -4414,72 +4499,70 @@ void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, *************************************************************************/ void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b) + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b) { - double a2; - double b2; - double esq; - double e; - double R; - double c; - double po4; - double phid; - double phi1; - double lambdad; - double lambda1; - double slambda1; - double ephi0p; - double sphip; - double tol; - double cr; - double C; - double K; - - lambda0 = GPS_Math_Deg_To_Rad(lambda0); - phi0 = GPS_Math_Deg_To_Rad(phi0); - - po4=GPS_PI/(double)4.0; - tol=(double)0.00001; - - a2 = a*a; - b2 = b*b; - esq = (a2-b2)/a2; - e = pow(esq,(double)0.5); - - R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); - - phid = (double)2.*(atan(exp((N - N0)/R)) - po4); - lambdad = (E - E0)/R; - - c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / - ((double)1.-esq))); - ephi0p = asin(sin(phi0) / c); - - sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); - phi1 = asin(sphip); - - slambda1 = cos(phid)*sin(lambdad)/cos(phi1); - lambda1 = asin(slambda1); - - *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); - - K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) - - e/(double)2. * log(((double)1.+e*sin(phi0)) / - ((double)1.-e*sin(phi0)))); - C = (K - log(tan(po4 + phi1/(double)2.)))/c; - - do - { - cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * - log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * - ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / - ((double)1.-esq)); - phi1 -= cr; - } - while (fabs(cr) > tol); - - *phi = GPS_Math_Rad_To_Deg(phi1); - - return; + double a2; + double b2; + double esq; + double e; + double R; + double c; + double po4; + double phid; + double phi1; + double lambdad; + double lambda1; + double slambda1; + double ephi0p; + double sphip; + double tol; + double cr; + double C; + double K; + + lambda0 = GPS_Math_Deg_To_Rad(lambda0); + phi0 = GPS_Math_Deg_To_Rad(phi0); + + po4=GPS_PI/(double)4.0; + tol=(double)0.00001; + + a2 = a*a; + b2 = b*b; + esq = (a2-b2)/a2; + e = pow(esq,(double)0.5); + + R = a*sqrt((double)1.-esq) / ((double)1.-esq*sin(phi0) * sin(phi0)); + + phid = (double)2.*(atan(exp((N - N0)/R)) - po4); + lambdad = (E - E0)/R; + + c = sqrt((double)1.+((esq * pow(cos(phi0), (double)4.)) / + ((double)1.-esq))); + ephi0p = asin(sin(phi0) / c); + + sphip = cos(ephi0p)*sin(phid) + sin(ephi0p)*cos(phid)*cos(lambdad); + phi1 = asin(sphip); + + slambda1 = cos(phid)*sin(lambdad)/cos(phi1); + lambda1 = asin(slambda1); + + *lambda = GPS_Math_Rad_To_Deg((lambda1/c + lambda0)); + + K = log(tan(po4 + ephi0p/(double)2.)) -c*(log(tan(po4 + phi0/(double)2.)) + - e/(double)2. * log(((double)1.+e*sin(phi0)) / + ((double)1.-e*sin(phi0)))); + C = (K - log(tan(po4 + phi1/(double)2.)))/c; + + do { + cr = (C + log(tan(po4 + phi1/(double)2.)) - e/(double)2. * + log(((double)1.+e*sin(phi1)) / ((double)1.-e*sin(phi1)))) * + ((((double)1.-esq*sin(phi1)*sin(phi1)) * cos(phi1)) / + ((double)1.-esq)); + phi1 -= cr; + } while (fabs(cr) > tol); + + *phi = GPS_Math_Rad_To_Deg(phi1); + + return; } diff --git a/gpsbabel/jeeps/gpsproj.h b/gpsbabel/jeeps/gpsproj.h index 6922a47e0..2da86bb4e 100644 --- a/gpsbabel/jeeps/gpsproj.h +++ b/gpsbabel/jeeps/gpsproj.h @@ -9,146 +9,146 @@ extern "C" #include "gps.h" -void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); - - -void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double phi2, - double phi0, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b); -void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, double N0, - double a, double b); -void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi1, double lambda1, - double E0, double N0, double a, double b); -void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi1, double lambda1, - double E0, double N0, double a, double b); - -void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); - -void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, - double E0, double N0, double a, double b); -void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double M0, double E0, - double N0, double a, double b); -void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double M0, double E0, - double N0, double a, double b); - -void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double M0, double E0, - double N0, double a, double b); -void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double M0, - double E0, double N0, double a, double b); - -void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, - double lambda0, double E0, double N0, - double a, double b); - -void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, - double *N, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b); -void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double F0, - double a, double b); - -void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, - double *N,double phi0,double lambda0, - double E0, double N0, double a, double b); -void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, - double *lambda, double phi0, double lambda0, - double E0, double N0, double a, double b); + void GPS_Math_Albers_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Albers_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + + + void GPS_Math_LambertCC_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_LambertCC_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double phi2, + double phi0, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Miller_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Miller_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Bonne_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Bonne_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Cassini_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Cassini_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Cylea_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Cylea_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_EckertIV_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b); + void GPS_Math_EckertIV_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_EckertVI_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, double N0, + double a, double b); + void GPS_Math_EckertVI_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Cyled_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Cyled_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_VderGrinten_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_VderGrinten_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_PolarSt_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi1, double lambda1, + double E0, double N0, double a, double b); + void GPS_Math_PolarSt_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi1, double lambda1, + double E0, double N0, double a, double b); + + void GPS_Math_Mollweide_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Mollweide_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_Orthog_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Orthog_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); + + void GPS_Math_Polycon_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, + double E0, double N0, double a, double b); + void GPS_Math_Polycon_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Sinusoid_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double M0, double E0, + double N0, double a, double b); + void GPS_Math_Sinusoid_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double M0, double E0, + double N0, double a, double b); + + void GPS_Math_TCylEA_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double M0, double E0, + double N0, double a, double b); + void GPS_Math_TCylEA_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double M0, + double E0, double N0, double a, double b); + + void GPS_Math_Mercator_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Mercator_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, + double lambda0, double E0, double N0, + double a, double b); + + void GPS_Math_TMerc_LatLon_To_EN(double phi, double lambda, double *E, + double *N, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); + void GPS_Math_TMerc_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double F0, + double a, double b); + + void GPS_Math_Swiss_LatLon_To_EN(double phi, double lambda, double *E, + double *N,double phi0,double lambda0, + double E0, double N0, double a, double b); + void GPS_Math_Swiss_EN_To_LatLon(double E, double N, double *phi, + double *lambda, double phi0, double lambda0, + double E0, double N0, double a, double b); #endif diff --git a/gpsbabel/jeeps/gpsprot.c b/gpsbabel/jeeps/gpsprot.c index 93bf9c971..c935aae78 100644 --- a/gpsbabel/jeeps/gpsprot.c +++ b/gpsbabel/jeeps/gpsprot.c @@ -2,21 +2,21 @@ ** @source JEEPS protocol table lookup functions (GPS' without A001) ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -34,212 +34,264 @@ static int32 gps_n_tag_unknown = 0; -struct COMMANDDATA COMMAND_ID[2]= -{ - /* Device Command Protocol 1 (A010) */ - { - 0,1,2,3,4,5,6,7,8,49,50,92,117,121,450,451,452,453,454,561,562,563,564,565 - } - , - /* Device Command Protocol 2 (A011) */ - { - 0,4,0,17,8,20,0,21,26,0,0 - } +struct COMMANDDATA COMMAND_ID[2]= { + /* Device Command Protocol 1 (A010) */ + { + 0,1,2,3,4,5,6,7,8,49,50,92,117,121,450,451,452,453,454,561,562,563,564,565 + } + , + /* Device Command Protocol 2 (A011) */ + { + 0,4,0,17,8,20,0,21,26,0,0 + } }; -struct LINKDATA LINK_ID[3]= -{ - /* Basic Link Protocol (L000) */ - { - 253,254,255,248, - 6,0,0,0,0,0,21,0,0,0,0, - 0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } - , - /* Link Protocol 1 (L001) */ - { - 253,254,255,248, - 6,10,12,14,17,19,21,27,29,30,31, - 34,35,51,98,99, - 134,149,152,990,991,992,993,994,1061,1062,1063,1064,1065,1066,222 - } - , - /* Link Protocol 2 (L002) */ - { - 253,254,255,248, - 6,11,12,20,24,0,21,35,37,39,4, - 0,43,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } +struct LINKDATA LINK_ID[3]= { + /* Basic Link Protocol (L000) */ + { + 253,254,255,248, + 6,0,0,0,0,0,21,0,0,0,0, + 0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + , + /* Link Protocol 1 (L001) */ + { + 253,254,255,248, + 6,10,12,14,17,19,21,27,29,30,31, + 34,35,51,98,99, + 134,149,152,990,991,992,993,994,1061,1062,1063,1064,1065,1066,222 + } + , + /* Link Protocol 2 (L002) */ + { + 253,254,255,248, + 6,11,12,20,24,0,21,35,37,39,4, + 0,43,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } }; -struct GPS_MODEL_PROTOCOL GPS_MP[]= -{ - { 7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1, - pA500,pD500 - }, - { 13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 14,pL001,pA010,pA100,pD100,pA200,pD200,pD100,-1,-1,pA400,pD400, - pA500,pD500 - }, - { 15,pL001,pA010,pA100,pD151,pA200,pD200,pD151,-1,-1,pA400,pD151, - pA500,pD500 - }, - { 18,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 20,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 22,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, - pA500,pD500 - }, - { 23,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 24,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 25,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 29,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, - pA500,pD500 - }, - { 929,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD500 - }, - { 31,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 33,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 34,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 35,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 36,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, - pA500,pD500 - }, - { 936,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 39,pL001,pA010,pA100,pD151,pA200,pD201,pD151,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 41,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 42,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, - pA500,pD500 - }, - { 44,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, - pA500,pD500 - }, - { 45,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 47,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 48,pL001,pA010,pA100,pD154,pA200,pD201,pD154,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 49,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 50,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 52,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD550 - }, - { 53,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 55,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 56,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 59,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 61,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 62,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 64,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD551 - }, - { 71,pL001,pA010,pA100,pD155,pA200,pD201,pD155,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 72,pL001,pA010,pA100,pD104,pA200,pD201,pD104,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 73,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 74,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, - pA500,pD500 - }, - { 76,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 77,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,pA400,pD400, - pA500,pD501 - }, - { 777,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 877,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 977,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 87,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 88,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, - pA500,pD501 - }, - { 95,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 96,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 97,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 98,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, - pA500,pD551 - }, - { 100,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 105,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 106,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, - pA500,pD501 - }, - { 112,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, - pA500,pD501 - }, - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 - } +struct GPS_MODEL_PROTOCOL GPS_MP[]= { + { + 7,pL001,pA010,pA100,pD100,pA200,pD200,-1,-1,-1,-1,-1, + pA500,pD500 + }, + { + 13,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 14,pL001,pA010,pA100,pD100,pA200,pD200,pD100,-1,-1,pA400,pD400, + pA500,pD500 + }, + { + 15,pL001,pA010,pA100,pD151,pA200,pD200,pD151,-1,-1,pA400,pD151, + pA500,pD500 + }, + { + 18,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 20,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 22,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { + 23,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 24,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 25,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 29,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { + 929,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD500 + }, + { + 31,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 33,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 34,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 35,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 36,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,pA400,pD152, + pA500,pD500 + }, + { + 936,pL001,pA010,pA100,pD152,pA200,pD200,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 39,pL001,pA010,pA100,pD151,pA200,pD201,pD151,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 41,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 42,pL001,pA010,pA100,pD100,pA200,pD200,pD100,pA300,pD300,pA400,pD400, + pA500,pD500 + }, + { + 44,pL001,pA010,pA100,pD101,pA200,pD201,pD101,pA300,pD300,pA400,pD101, + pA500,pD500 + }, + { + 45,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 47,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 48,pL001,pA010,pA100,pD154,pA200,pD201,pD154,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 49,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 50,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 52,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD550 + }, + { + 53,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 55,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 56,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 59,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 61,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 62,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 64,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { + 71,pL001,pA010,pA100,pD155,pA200,pD201,pD155,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 72,pL001,pA010,pA100,pD104,pA200,pD201,pD104,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 73,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 74,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,-1,-1, + pA500,pD500 + }, + { + 76,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 77,pL001,pA010,pA100,pD100,pA200,pD201,pD100,pA300,pD300,pA400,pD400, + pA500,pD501 + }, + { + 777,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 877,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 977,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 87,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 88,pL001,pA010,pA100,pD102,pA200,pD201,pD102,pA300,pD300,pA400,pD102, + pA500,pD501 + }, + { + 95,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 96,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 97,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 98,pL002,pA011,pA100,pD150,pA200,pD201,pD150,-1,-1,pA400,pD450, + pA500,pD551 + }, + { + 100,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 105,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 106,pL001,pA010,pA100,pD103,pA200,pD201,pD103,pA300,pD300,pA400,pD403, + pA500,pD501 + }, + { + 112,pL001,pA010,pA100,pD152,pA200,pD201,pD152,pA300,pD300,-1,-1, + pA500,pD501 + }, + { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } }; @@ -253,28 +305,30 @@ struct GPS_MODEL_PROTOCOL GPS_MP[]= ** ** @return [void] ************************************************************************/ - + US GPS_Protocol_Version_Change(US id, US version) { - if(id==29) - if(version>=400) - id = 929; - - if(id==36) - if(version>=300) - id = 936; - - if(id==77) - { - if(version>=301 && version<350) - id = 777; - else if(version>=350 && version<361) - id = 877; - else if(version>=361) - id = 977; + if (id==29) + if (version>=400) { + id = 929; + } + + if (id==36) + if (version>=300) { + id = 936; + } + + if (id==77) { + if (version>=301 && version<350) { + id = 777; + } else if (version>=350 && version<361) { + id = 877; + } else if (version>=361) { + id = 977; } + } - return id; + return id; } @@ -291,38 +345,36 @@ US GPS_Protocol_Version_Change(US id, US version) int32 GPS_Protocol_Table_Set(US id) { - int32 i; - US v; - char s[GPS_ARB_LEN]; - - i=0; - while((v=GPS_MP[i].id)) - { - if(v==id) - { - gps_link_type = GPS_MP[i].link; - gps_device_command = GPS_MP[i].command-10; - gps_waypt_transfer = GPS_MP[i].wayptt; - gps_waypt_type = GPS_MP[i].wayptd; - gps_route_transfer = GPS_MP[i].rtea; - gps_rte_hdr_type = GPS_MP[i].rted0; - gps_rte_type = GPS_MP[i].rted1; - gps_trk_transfer = GPS_MP[i].trka; - gps_trk_type = GPS_MP[i].trkd; - gps_prx_waypt_transfer = GPS_MP[i].prxa; - gps_prx_waypt_type = GPS_MP[i].prxd; - gps_almanac_transfer = GPS_MP[i].alma; - gps_almanac_type = GPS_MP[i].almd; - return 1; - } - ++i; + int32 i; + US v; + char s[GPS_ARB_LEN]; + + i=0; + while ((v=GPS_MP[i].id)) { + if (v==id) { + gps_link_type = GPS_MP[i].link; + gps_device_command = GPS_MP[i].command-10; + gps_waypt_transfer = GPS_MP[i].wayptt; + gps_waypt_type = GPS_MP[i].wayptd; + gps_route_transfer = GPS_MP[i].rtea; + gps_rte_hdr_type = GPS_MP[i].rted0; + gps_rte_type = GPS_MP[i].rted1; + gps_trk_transfer = GPS_MP[i].trka; + gps_trk_type = GPS_MP[i].trkd; + gps_prx_waypt_transfer = GPS_MP[i].prxa; + gps_prx_waypt_type = GPS_MP[i].prxd; + gps_almanac_transfer = GPS_MP[i].alma; + gps_almanac_type = GPS_MP[i].almd; + return 1; } + ++i; + } - (void)sprintf(s,"INIT: No table entry for ID %d\n",id); - GPS_Error(s); + (void)sprintf(s,"INIT: No table entry for ID %d\n",id); + GPS_Error(s); - return GPS_UNSUPPORTED; + return GPS_UNSUPPORTED; } @@ -336,21 +388,20 @@ int32 GPS_Protocol_Table_Set(US id) ** ** @return [void] ************************************************************************/ - + void GPS_Protocol_Error(US tag, US data) { - char s[GPS_ARB_LEN]; + char s[GPS_ARB_LEN]; - (void) sprintf(s,"PROTOCOL ERROR: Unknown tag/data [%c/%d]\n",tag,data); - GPS_Error(s); + (void) sprintf(s,"PROTOCOL ERROR: Unknown tag/data [%c/%d]\n",tag,data); + GPS_Error(s); - if(gps_n_tag_unknown < GPS_TAGUNK) - { - gps_tag_unknown[gps_n_tag_unknown] = tag; - gps_tag_data_unknown[gps_n_tag_unknown++] = data; - } - - return; + if (gps_n_tag_unknown < GPS_TAGUNK) { + gps_tag_unknown[gps_n_tag_unknown] = tag; + gps_tag_data_unknown[gps_n_tag_unknown++] = data; + } + + return; } @@ -362,18 +413,19 @@ void GPS_Protocol_Error(US tag, US data) ** ** @return [void] ************************************************************************/ - + void GPS_Unknown_Protocol_Print(void) { - int32 i; + int32 i; - (void) fprintf(stdout,"\nUnknown protocols: "); - if(!gps_n_tag_unknown) - (void) fprintf(stdout,"None"); - (void) fprintf(stdout,"\n"); + (void) fprintf(stdout,"\nUnknown protocols: "); + if (!gps_n_tag_unknown) { + (void) fprintf(stdout,"None"); + } + (void) fprintf(stdout,"\n"); - for(i=0; idata; - - start = GPS_Time_Now(); - GPS_Diag("Rx Data:"); - while(GPS_Time_Now() < start+GPS_TIME_OUT) - { - if((n=GPS_Serial_Chars_Ready(fd))) - { - if(GPS_Serial_Read(fd,&u,1)==-1) - { - perror("read"); - GPS_Error("GPS_Packet_Read: Read error"); - gps_errno = FRAMING_ERROR; - return 0; - } - - GPS_Diag("%02x ", u); - - if(!len) - { - if(u != DLE) - { - (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); - (void) fflush(stderr); - return 0; - } - ++len; - continue; - } - - if(len==1) - { - (*packet)->type = u; - ++len; - continue; - } - - if(u == DLE) - { - if(isDLE) - { - isDLE = gpsFalse; - continue; - } - isDLE = gpsTrue; - } - - if(len == 2) - { - (*packet)->n = u; - len = -1; - continue; - } - - if(u == ETX) - if(isDLE) - { - if(p-(*packet)->data-2 != (*packet)->n) - { - GPS_Error("GPS_Packet_Read: Bad count"); - gps_errno = FRAMING_ERROR; - return 0; - } - chk_read = *(p-2); - - for(i=0,p=(*packet)->data;i<(*packet)->n;++i) - chk -= *p++; - chk -= (*packet)->type; - chk -= (*packet)->n; - if(chk != chk_read) - { - GPS_Error("CHECKSUM: Read error\n"); - gps_errno = FRAMING_ERROR; - return 0; - } - - m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); - if (gps_show_bytes) { - GPS_Diag(" "); - for (i = 0; i < (*packet)->n; i++) { - char c = (*packet)->data[i]; - GPS_Diag("%c", isalnum(c) ? c : '.'); - } - GPS_Diag(" "); - } - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - return (*packet)->n; - } - - if (p - (*packet)->data >= MAX_GPS_PACKET_SIZE) - { - GPS_Error("GPS_Serial_Packet_Read: Bad payload size/no ETX found"); - gps_errno = FRAMING_ERROR; - return 0; - } - *p++ = u; - } + time_t start; + int32 n; + int32 len; + UC u; + int32 isDLE; + UC *p; + int32 i; + UC chk=0, chk_read; + const char *m1; + const char *m2; + + len = 0; + isDLE = gpsFalse; + p = (*packet)->data; + + start = GPS_Time_Now(); + GPS_Diag("Rx Data:"); + while (GPS_Time_Now() < start+GPS_TIME_OUT) { + if ((n=GPS_Serial_Chars_Ready(fd))) { + if (GPS_Serial_Read(fd,&u,1)==-1) { + perror("read"); + GPS_Error("GPS_Packet_Read: Read error"); + gps_errno = FRAMING_ERROR; + return 0; + } + + GPS_Diag("%02x ", u); + + if (!len) { + if (u != DLE) { + (void) fprintf(stderr,"GPS_Packet_Read: No DLE. Data received, but probably not a garmin packet.\n"); + (void) fflush(stderr); + return 0; + } + ++len; + continue; + } + + if (len==1) { + (*packet)->type = u; + ++len; + continue; + } + + if (u == DLE) { + if (isDLE) { + isDLE = gpsFalse; + continue; + } + isDLE = gpsTrue; + } + + if (len == 2) { + (*packet)->n = u; + len = -1; + continue; + } + + if (u == ETX) + if (isDLE) { + if (p-(*packet)->data-2 != (*packet)->n) { + GPS_Error("GPS_Packet_Read: Bad count"); + gps_errno = FRAMING_ERROR; + return 0; + } + chk_read = *(p-2); + + for (i=0,p=(*packet)->data; i<(*packet)->n; ++i) { + chk -= *p++; + } + chk -= (*packet)->type; + chk -= (*packet)->n; + if (chk != chk_read) { + GPS_Error("CHECKSUM: Read error\n"); + gps_errno = FRAMING_ERROR; + return 0; + } + + m1 = Get_Pkt_Type((*packet)->type, (*packet)->data[0], &m2); + if (gps_show_bytes) { + GPS_Diag(" "); + for (i = 0; i < (*packet)->n; i++) { + char c = (*packet)->data[i]; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } + GPS_Diag(" "); + } + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + return (*packet)->n; + } + + if (p - (*packet)->data >= MAX_GPS_PACKET_SIZE) { + GPS_Error("GPS_Serial_Packet_Read: Bad payload size/no ETX found"); + gps_errno = FRAMING_ERROR; + return 0; + } + *p++ = u; } - - - GPS_Error("GPS_Packet_Read: Timeout. No data received."); - gps_errno = SERIAL_ERROR; + } - return 0; + + GPS_Error("GPS_Packet_Read: Timeout. No data received."); + gps_errno = SERIAL_ERROR; + + return 0; } @@ -204,20 +191,19 @@ int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet) int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) { - if(!GPS_Serial_Packet_Read(fd, rec)) - return 0; + if (!GPS_Serial_Packet_Read(fd, rec)) { + return 0; + } - if(LINK_ID[0].Pid_Ack_Byte != (*rec)->type) - { - gps_error = FRAMING_ERROR; -/* rjl return 0; */ - } - - if(*(*rec)->data != (*tra)->type) - { - gps_error = FRAMING_ERROR; - return 0; - } + if (LINK_ID[0].Pid_Ack_Byte != (*rec)->type) { + gps_error = FRAMING_ERROR; + /* rjl return 0; */ + } + + if (*(*rec)->data != (*tra)->type) { + gps_error = FRAMING_ERROR; + return 0; + } - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpsread.h b/gpsbabel/jeeps/gpsread.h index 17f3bd852..781d3c53e 100644 --- a/gpsbabel/jeeps/gpsread.h +++ b/gpsbabel/jeeps/gpsread.h @@ -9,9 +9,9 @@ extern "C" #include "gps.h" -time_t GPS_Time_Now(void); -int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); -int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + time_t GPS_Time_Now(void); + int32 GPS_Serial_Packet_Read(gpsdevh *fd, GPS_PPacket *packet); + int32 GPS_Serial_Get_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); #endif diff --git a/gpsbabel/jeeps/gpsrqst.c b/gpsbabel/jeeps/gpsrqst.c index 7203313c6..6947c844f 100644 --- a/gpsbabel/jeeps/gpsrqst.c +++ b/gpsbabel/jeeps/gpsrqst.c @@ -2,21 +2,21 @@ ** @source JEEPS time/position request from GPS functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -26,7 +26,7 @@ static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time); -static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); +static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); @@ -42,20 +42,19 @@ static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon); int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) { - time_t ret=0; - - switch(gps_date_time_transfer) - { - case pA600: - ret = GPS_A600_Rqst(fd, Time); - break; - default: - GPS_Error("Rqst_Send_Time: Unknown date/time protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + time_t ret=0; + + switch (gps_date_time_transfer) { + case pA600: + ret = GPS_A600_Rqst(fd, Time); + break; + default: + GPS_Error("Rqst_Send_Time: Unknown date/time protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -70,32 +69,34 @@ int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time) ************************************************************************/ static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) { - GPS_PPacket tra; - GPS_PPacket rec; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - switch(gps_date_time_type) - { - case pD600: - GPS_D600_Send(&tra,Time); - break; - default: - GPS_Error("A600_Rqst: Unknown data/time protocol"); - return PROTOCOL_ERROR; - } - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - - return 1; + GPS_PPacket tra; + GPS_PPacket rec; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + + switch (gps_date_time_type) { + case pD600: + GPS_D600_Send(&tra,Time); + break; + default: + GPS_Error("A600_Rqst: Unknown data/time protocol"); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); + + return 1; } @@ -113,20 +114,19 @@ static int32 GPS_A600_Rqst(gpsdevh *fd, time_t Time) int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) { - int32 ret=0; - - switch(gps_position_transfer) - { - case pA700: - ret = GPS_A700_Rqst(fd, lat, lon); - break; - default: - GPS_Error("Rqst_Send_Position: Unknown position protocol"); - return PROTOCOL_ERROR; - } - - return ret; -} + int32 ret=0; + + switch (gps_position_transfer) { + case pA700: + ret = GPS_A700_Rqst(fd, lat, lon); + break; + default: + GPS_Error("Rqst_Send_Position: Unknown position protocol"); + return PROTOCOL_ERROR; + } + + return ret; +} @@ -142,35 +142,37 @@ int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon) ************************************************************************/ static int32 GPS_A700_Rqst(gpsdevh *fd, double lat, double lon) { - GPS_PPacket tra; - GPS_PPacket rec; - - if(!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) - return MEMORY_ERROR; - - - switch(gps_position_type) - { - case pD700: - GPS_D700_Send(&tra,lat,lon); - break; - default: - GPS_Error("A700_Rqst: Unknown position protocol"); - GPS_Packet_Del(&tra); - GPS_Packet_Del(&rec); - return PROTOCOL_ERROR; - } - - if(!GPS_Write_Packet(fd,tra)) - return gps_errno; - - if(!GPS_Get_Ack(fd, &tra, &rec)) - return gps_errno; - + GPS_PPacket tra; + GPS_PPacket rec; + + if (!(tra = GPS_Packet_New()) || !(rec = GPS_Packet_New())) { + return MEMORY_ERROR; + } + + switch (gps_position_type) { + case pD700: + GPS_D700_Send(&tra,lat,lon); + break; + default: + GPS_Error("A700_Rqst: Unknown position protocol"); GPS_Packet_Del(&tra); GPS_Packet_Del(&rec); + return PROTOCOL_ERROR; + } + + if (!GPS_Write_Packet(fd,tra)) { + return gps_errno; + } + + if (!GPS_Get_Ack(fd, &tra, &rec)) { + return gps_errno; + } + + + GPS_Packet_Del(&tra); + GPS_Packet_Del(&rec); - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpsrqst.h b/gpsbabel/jeeps/gpsrqst.h index ec0169586..f2606d938 100644 --- a/gpsbabel/jeeps/gpsrqst.h +++ b/gpsbabel/jeeps/gpsrqst.h @@ -9,8 +9,8 @@ extern "C" #include "gps.h" -int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time); -int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon); + int32 GPS_Rqst_Send_Time(gpsdevh *fd, time_t Time); + int32 GPS_Rqst_Send_Position(gpsdevh *fd, double lat, double lon); #endif diff --git a/gpsbabel/jeeps/gpssend.c b/gpsbabel/jeeps/gpssend.c index 80801a0c7..d757c5a2c 100644 --- a/gpsbabel/jeeps/gpssend.c +++ b/gpsbabel/jeeps/gpssend.c @@ -2,21 +2,21 @@ ** @source JEEPS packet construction, sending and ack functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -42,79 +42,75 @@ static US Build_Serial_Packet(GPS_PPacket in, GPS_Serial_PPacket out) { - UC *p; - UC *q; - - int32 i; - UC chk=0; - US bytes=0; - - p = in->data; - q = out->data; - - out->dle = DLE; - out->edle = DLE; - out->etx = ETX; - out->n = in->n; - out->type = in->type; - - chk -= in->type; - - if(in->n == DLE) - { - ++bytes; - *q++ = DLE; - } - - chk -= in->n; - - for(i = 0; i < in->n; ++i) - { - if(*p == DLE) - { - ++bytes; - *q++ = DLE; - } - chk -= *p; - *q++ = *p++; - ++bytes; - } + UC *p; + UC *q; + + int32 i; + UC chk=0; + US bytes=0; + + p = in->data; + q = out->data; + + out->dle = DLE; + out->edle = DLE; + out->etx = ETX; + out->n = in->n; + out->type = in->type; - if(chk == DLE) - { - *q++ = DLE; - ++bytes; + chk -= in->type; + + if (in->n == DLE) { + ++bytes; + *q++ = DLE; + } + + chk -= in->n; + + for (i = 0; i < in->n; ++i) { + if (*p == DLE) { + ++bytes; + *q++ = DLE; } - - out->chk = chk; - - return bytes; + chk -= *p; + *q++ = *p++; + ++bytes; + } + + if (chk == DLE) { + *q++ = DLE; + ++bytes; + } + + out->chk = chk; + + return bytes; } void Diag(void *buf, size_t sz) { - unsigned char *cbuf = (unsigned char *) buf; - while (sz--) { - GPS_Diag("%02x ", *cbuf++); - } + unsigned char *cbuf = (unsigned char *) buf; + while (sz--) { + GPS_Diag("%02x ", *cbuf++); + } } -void +void DiagS(void *buf, size_t sz) { - unsigned char *cbuf = (unsigned char *) buf; + unsigned char *cbuf = (unsigned char *) buf; - while (sz--) { - unsigned char c = *cbuf++; - GPS_Diag("%c", isalnum(c) ? c : '.'); - } + while (sz--) { + unsigned char c = *cbuf++; + GPS_Diag("%c", isalnum(c) ? c : '.'); + } } /* @func GPS_Write_Packet *********************************************** ** -** Forms a complete packet to send +** Forms a complete packet to send ** ** @param [w] fd [int32] file descriptor ** @param [r] packet [GPS_PPacket] packet @@ -124,70 +120,64 @@ DiagS(void *buf, size_t sz) int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) { - size_t ret; - const char *m1, *m2; - GPS_Serial_OPacket ser_pkt; - UC ser_pkt_data[MAX_GPS_PACKET_SIZE * sizeof(UC)]; - US bytes; - - if (packet->type >= 0xff || packet->n >= 0xff) { - GPS_Error("SEND: Unsupported packet type/size for serial protocol"); - return 0; - } - - ser_pkt.data = ser_pkt_data; - bytes = Build_Serial_Packet(packet, &ser_pkt); - - GPS_Diag("Tx Data:"); - Diag(&ser_pkt.dle, 3); - if((ret=GPS_Serial_Write(fd,(const void *) &ser_pkt.dle,(size_t)3)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=3) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - Diag(ser_pkt.data, bytes); - if((ret=GPS_Serial_Write(fd,(const void *)ser_pkt.data,(size_t)bytes)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=bytes) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - - Diag(&ser_pkt.chk, 3); - - GPS_Diag(": "); - DiagS(ser_pkt.data, bytes); - DiagS(&ser_pkt.chk, 3); - m1 = Get_Pkt_Type(ser_pkt.type, ser_pkt.data[0], &m2); - GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); - - if((ret=GPS_Serial_Write(fd,(const void *)&ser_pkt.chk,(size_t)3)) == -1) - { - perror("write"); - GPS_Error("SEND: Write to GPS failed"); - return 0; - } - if(ret!=3) - { - GPS_Error("SEND: Incomplete write to GPS"); - return 0; - } - - - return 1; + size_t ret; + const char *m1, *m2; + GPS_Serial_OPacket ser_pkt; + UC ser_pkt_data[MAX_GPS_PACKET_SIZE * sizeof(UC)]; + US bytes; + + if (packet->type >= 0xff || packet->n >= 0xff) { + GPS_Error("SEND: Unsupported packet type/size for serial protocol"); + return 0; + } + + ser_pkt.data = ser_pkt_data; + bytes = Build_Serial_Packet(packet, &ser_pkt); + + GPS_Diag("Tx Data:"); + Diag(&ser_pkt.dle, 3); + if ((ret=GPS_Serial_Write(fd,(const void *) &ser_pkt.dle,(size_t)3)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=3) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + Diag(ser_pkt.data, bytes); + if ((ret=GPS_Serial_Write(fd,(const void *)ser_pkt.data,(size_t)bytes)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=bytes) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + Diag(&ser_pkt.chk, 3); + + GPS_Diag(": "); + DiagS(ser_pkt.data, bytes); + DiagS(&ser_pkt.chk, 3); + m1 = Get_Pkt_Type(ser_pkt.type, ser_pkt.data[0], &m2); + GPS_Diag("(%-8s%s)\n", m1, m2 ? m2 : ""); + + if ((ret=GPS_Serial_Write(fd,(const void *)&ser_pkt.chk,(size_t)3)) == -1) { + perror("write"); + GPS_Error("SEND: Write to GPS failed"); + return 0; + } + if (ret!=3) { + GPS_Error("SEND: Incomplete write to GPS"); + return 0; + } + + + return 1; } @@ -204,16 +194,15 @@ int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet) int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec) { - UC data[2]; - - GPS_Util_Put_Short(data,(US)(*rec)->type); - GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); - if(!GPS_Write_Packet(fd,*tra)) - { - GPS_Error("Error acknowledging packet"); - gps_errno = SERIAL_ERROR; - return 0; - } + UC data[2]; + + GPS_Util_Put_Short(data,(US)(*rec)->type); + GPS_Make_Packet(tra,LINK_ID[0].Pid_Ack_Byte,data,2); + if (!GPS_Write_Packet(fd,*tra)) { + GPS_Error("Error acknowledging packet"); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + return 1; } diff --git a/gpsbabel/jeeps/gpssend.h b/gpsbabel/jeeps/gpssend.h index 2b6fc9115..5276a14fa 100644 --- a/gpsbabel/jeeps/gpssend.h +++ b/gpsbabel/jeeps/gpssend.h @@ -11,10 +11,10 @@ extern "C" #define GPS_ARB_LEN 1024 -int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); + int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -void GPS_Make_Packet(GPS_PPacket *packet, US type, UC *data, uint32 n); + void GPS_Make_Packet(GPS_PPacket *packet, US type, UC *data, uint32 n); #endif diff --git a/gpsbabel/jeeps/gpsserial.c b/gpsbabel/jeeps/gpsserial.c index 29ae1ede1..cd0c38089 100644 --- a/gpsbabel/jeeps/gpsserial.c +++ b/gpsbabel/jeeps/gpsserial.c @@ -7,17 +7,17 @@ ** @modified June 29th 2000 Alan Bleasby. NMEA additions ** @modified Copyright (C) 2006 Robert Lipe ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -36,23 +36,23 @@ #if 0 #define GARMULATOR 1 char *rxdata[] = { - "10 06 02 fe 00 fa 10 03", - "10 ff 7d 97 00 0e 01 53 74 72 65 65 74 50 69 6c 6f 74 20 33 20 53 6f 66 74 77 61 72 65 20 56 65 72 73 69 6f 6e 20 32 2e 37 30 00 56 45 52 42 4d 41 50 20 41 6d 65 72 69 63 61 73 20 41 75 74 6f 72 6f 75 74 65 20 31 2e 30 30 00 56 45 52 41 55 44 20 45 6e 67 6c 69 73 68 20 33 2e 30 31 00 56 45 52 53 50 4c 53 43 52 4e 20 53 70 6c 61 73 68 20 53 63 72 65 65 6e 20 4d 69 73 73 69 6e 67 00 f1 10 03", - "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03", - - /* Guessing from here down */ - "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */ - "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 1b 02 09 00 da 10 03", /* RECORD */ - "10 06 02 0a 00 ee 10 03", /* Ack */ - "10 23 5f 01 00 ff 70 3f 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a6 1b aa 19 6e 78 5c c2 00 00 00 00 51 59 04 69 00 00 00 00 00 00 00 00 ff ff ff ff 47 43 31 41 33 37 00 54 68 65 20 54 72 6f 6c 6c 20 62 79 20 61 31 38 32 70 69 6c 6f 74 20 26 20 46 61 6d 69 6c 79 00 00 00 00 00 59 10 03" - "10 0c 02 07 00 eb 10 03" /* XFERCMP */ + "10 06 02 fe 00 fa 10 03", + "10 ff 7d 97 00 0e 01 53 74 72 65 65 74 50 69 6c 6f 74 20 33 20 53 6f 66 74 77 61 72 65 20 56 65 72 73 69 6f 6e 20 32 2e 37 30 00 56 45 52 42 4d 41 50 20 41 6d 65 72 69 63 61 73 20 41 75 74 6f 72 6f 75 74 65 20 31 2e 30 30 00 56 45 52 41 55 44 20 45 6e 67 6c 69 73 68 20 33 2e 30 31 00 56 45 52 53 50 4c 53 43 52 4e 20 53 70 6c 61 73 68 20 53 63 72 65 65 6e 20 4d 69 73 73 69 6e 67 00 f1 10 03", + "10 f8 0e 56 45 52 53 4d 41 50 31 20 4e 6f 6e 65 00 fb 10 03", + + /* Guessing from here down */ + "10 06 02 fe 00 fa 10 03", /* Ack the unknown packet */ + "10 fd 24 50 00 00 4c 01 00 41 0a 00 41 64 00 44 6d 00 41 c9 00 44 ca 00 44 6d 00 44 d2 00 41 2d 01 44 36 01 44 2d 01 66 10 03", /* PTR Array */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 0e 08 06 04 d4 07 00 17 3a 30 84 10 03", /* DATTIME */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 1b 02 09 00 da 10 03", /* RECORD */ + "10 06 02 0a 00 ee 10 03", /* Ack */ + "10 23 5f 01 00 ff 70 3f 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 a6 1b aa 19 6e 78 5c c2 00 00 00 00 51 59 04 69 00 00 00 00 00 00 00 00 ff ff ff ff 47 43 31 41 33 37 00 54 68 65 20 54 72 6f 6c 6c 20 62 79 20 61 31 38 32 70 69 6c 6f 74 20 26 20 46 61 6d 69 6c 79 00 00 00 00 00 59 10 03" + "10 0c 02 07 00 eb 10 03" /* XFERCMP */ }; #endif -/* +/* * termio on Cygwin is apparently broken, so we revert to Windows serial. */ #if defined (__WIN32__) || defined (__CYGWIN__) @@ -60,7 +60,7 @@ char *rxdata[] = { #include typedef struct { - HANDLE comport; + HANDLE comport; } win_serial_data; /* @@ -68,158 +68,158 @@ typedef struct { */ void GPS_Serial_Error(const char *mb, ...) { - va_list ap; - char msg[200]; - char *s; - int b; - - va_start(ap, mb); - b = vsnprintf(msg, sizeof(msg), mb, ap); - s = msg + b; - *s++ = ':'; - *s++ = ' '; - - FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, - GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); - GPS_Error(msg); + va_list ap; + char msg[200]; + char *s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, + GetLastError(), 0, s, sizeof(msg) - b - 2, 0); + GPS_Error(msg); } int32 GPS_Serial_On(const char *port, gpsdevh **dh) { - DCB tio; - COMMTIMEOUTS timeout; - HANDLE comport; - const char *xname = fix_win_serial_name(port); - win_serial_data *wsd = xcalloc(sizeof (win_serial_data), 1); - *dh = (gpsdevh*) wsd; - GPS_Diag("Opening %s\n", xname); - comport = CreateFileA(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, - OPEN_EXISTING, 0, NULL); - - if (comport == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("CreateFile on '%s' failed", xname); - gps_errno = SERIAL_ERROR; - return 0; - } - - tio.DCBlength = sizeof(DCB); - GetCommState (comport, &tio); - tio.BaudRate = CBR_9600; - tio.fBinary = TRUE; - tio.fParity = TRUE; - tio.fOutxCtsFlow = FALSE; - tio.fOutxDsrFlow = FALSE; - tio.fDtrControl = DTR_CONTROL_ENABLE; - tio.fDsrSensitivity = FALSE; - tio.fTXContinueOnXoff = TRUE; - tio.fOutX = FALSE; - tio.fInX = FALSE; - tio.fErrorChar = FALSE; - tio.fNull = FALSE; - tio.fRtsControl = RTS_CONTROL_ENABLE; - tio.fAbortOnError = FALSE; - tio.ByteSize = 8; - tio.Parity = NOPARITY; - tio.StopBits = ONESTOPBIT; - - if (!SetCommState (comport, &tio)) { - GPS_Serial_Error("SetCommState on port '%s' failed", port); - CloseHandle(comport); - comport = INVALID_HANDLE_VALUE; - gps_errno = SERIAL_ERROR; - return 0; - } - - /* - * The timeouts are kind of fictional as we always end up doing - * single byte reads. At 9600bps (the default) the individual - * character time is 104Millisecs, so these are mostly "dead-man" - * (i.e. cable unplugged, unit not turned on) values. - */ - GetCommTimeouts (comport, &timeout); - - timeout.ReadIntervalTimeout = 1000; /*like vtime. In MS. */ - timeout.ReadTotalTimeoutMultiplier = 1000; - timeout.ReadTotalTimeoutConstant = 1000; - timeout.WriteTotalTimeoutMultiplier = 1000; - timeout.WriteTotalTimeoutConstant = 1000; - if (!SetCommTimeouts (comport, &timeout)) { - GPS_Serial_Error("SetCommTimeouts"); - CloseHandle (comport); - comport = INVALID_HANDLE_VALUE; - gps_errno = SERIAL_ERROR; - return 0; - } - wsd->comport = comport; - return 1; + DCB tio; + COMMTIMEOUTS timeout; + HANDLE comport; + const char *xname = fix_win_serial_name(port); + win_serial_data *wsd = xcalloc(sizeof(win_serial_data), 1); + *dh = (gpsdevh*) wsd; + GPS_Diag("Opening %s\n", xname); + comport = CreateFileA(xname, GENERIC_READ|GENERIC_WRITE, 0, NULL, + OPEN_EXISTING, 0, NULL); + + if (comport == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("CreateFile on '%s' failed", xname); + gps_errno = SERIAL_ERROR; + return 0; + } + + tio.DCBlength = sizeof(DCB); + GetCommState(comport, &tio); + tio.BaudRate = CBR_9600; + tio.fBinary = TRUE; + tio.fParity = TRUE; + tio.fOutxCtsFlow = FALSE; + tio.fOutxDsrFlow = FALSE; + tio.fDtrControl = DTR_CONTROL_ENABLE; + tio.fDsrSensitivity = FALSE; + tio.fTXContinueOnXoff = TRUE; + tio.fOutX = FALSE; + tio.fInX = FALSE; + tio.fErrorChar = FALSE; + tio.fNull = FALSE; + tio.fRtsControl = RTS_CONTROL_ENABLE; + tio.fAbortOnError = FALSE; + tio.ByteSize = 8; + tio.Parity = NOPARITY; + tio.StopBits = ONESTOPBIT; + + if (!SetCommState(comport, &tio)) { + GPS_Serial_Error("SetCommState on port '%s' failed", port); + CloseHandle(comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + + /* + * The timeouts are kind of fictional as we always end up doing + * single byte reads. At 9600bps (the default) the individual + * character time is 104Millisecs, so these are mostly "dead-man" + * (i.e. cable unplugged, unit not turned on) values. + */ + GetCommTimeouts(comport, &timeout); + + timeout.ReadIntervalTimeout = 1000; /*like vtime. In MS. */ + timeout.ReadTotalTimeoutMultiplier = 1000; + timeout.ReadTotalTimeoutConstant = 1000; + timeout.WriteTotalTimeoutMultiplier = 1000; + timeout.WriteTotalTimeoutConstant = 1000; + if (!SetCommTimeouts(comport, &timeout)) { + GPS_Serial_Error("SetCommTimeouts"); + CloseHandle(comport); + comport = INVALID_HANDLE_VALUE; + gps_errno = SERIAL_ERROR; + return 0; + } + wsd->comport = comport; + return 1; } int32 GPS_Serial_Off(gpsdevh *dh) { - win_serial_data *wsd = (win_serial_data*)dh; - CloseHandle(wsd->comport); - wsd->comport = INVALID_HANDLE_VALUE; - xfree(wsd); - return 1; + win_serial_data *wsd = (win_serial_data*)dh; + CloseHandle(wsd->comport); + wsd->comport = INVALID_HANDLE_VALUE; + xfree(wsd); + return 1; } int32 GPS_Serial_Chars_Ready(gpsdevh *dh) { - COMSTAT lpStat; - DWORD lpErrors; - win_serial_data *wsd = (win_serial_data*)dh; + COMSTAT lpStat; + DWORD lpErrors; + win_serial_data *wsd = (win_serial_data*)dh; - ClearCommError(wsd->comport, &lpErrors, &lpStat); - return (lpStat.cbInQue > 0); + ClearCommError(wsd->comport, &lpErrors, &lpStat); + return (lpStat.cbInQue > 0); } int32 GPS_Serial_Wait(gpsdevh *fd) { - /* Wait a short time before testing if data is ready. - * The GPS II, in particular, has a noticable time responding - * with a response to the device inquiry and if we give up on this - * too soon, we fail to read the response to the A001 packet and - * blow our state machines when it starts streaming the capabiilties - * response packet. - */ - Sleep(usecDELAY / 1000); - return GPS_Serial_Chars_Ready(fd); + /* Wait a short time before testing if data is ready. + * The GPS II, in particular, has a noticable time responding + * with a response to the device inquiry and if we give up on this + * too soon, we fail to read the response to the A001 packet and + * blow our state machines when it starts streaming the capabiilties + * response packet. + */ + Sleep(usecDELAY / 1000); + return GPS_Serial_Chars_Ready(fd); } int32 GPS_Serial_Flush(gpsdevh *fd) { - return 1; + return 1; } int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) { - win_serial_data *wsd = (win_serial_data*)dh; - DWORD len; - - /* - * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows - * Certified driver", will crash the OS on a write of zero bytes. - * We get such writes from upstream when there are zero payload - * bytes. SO we trap those here to stop Keyspan & Windows from - * nuking the system. - */ - if (size == 0) { - return 0; - } - WriteFile (wsd->comport, obuf, size, &len, NULL); - if (len != (DWORD) size) { - fatal ("Write error. Wrote %d of %d bytes.\n", (int)len, size); - } - return len; + win_serial_data *wsd = (win_serial_data*)dh; + DWORD len; + + /* + * Unbelievably, the Keyspan PDA serial driver 3.2, a "Windows + * Certified driver", will crash the OS on a write of zero bytes. + * We get such writes from upstream when there are zero payload + * bytes. SO we trap those here to stop Keyspan & Windows from + * nuking the system. + */ + if (size == 0) { + return 0; + } + WriteFile(wsd->comport, obuf, size, &len, NULL); + if (len != (DWORD) size) { + fatal("Write error. Wrote %d of %d bytes.\n", (int)len, size); + } + return len; } int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) { - DWORD cnt = 0; - win_serial_data *wsd = (win_serial_data*)dh; + DWORD cnt = 0; + win_serial_data *wsd = (win_serial_data*)dh; - ReadFile(wsd->comport, ibuf, size, &cnt, NULL); - return cnt; + ReadFile(wsd->comport, ibuf, size, &cnt, NULL); + return cnt; } #else @@ -230,8 +230,8 @@ int32 GPS_Serial_Read(gpsdevh * dh, void *ibuf, int size) #include typedef struct { - int fd; /* File descriptor */ - struct termios gps_ttysave; + int fd; /* File descriptor */ + struct termios gps_ttysave; } posix_serial_data; /* @func GPS_Serial_Open *********************************************** @@ -246,48 +246,45 @@ typedef struct { int32 GPS_Serial_Open(gpsdevh *dh, const char *port) { - struct termios tty; - posix_serial_data *psd = (posix_serial_data *)dh; - - /* - * This originally had O_NDELAY | O_NOCTTY in here, but this - * causes problems with Linux USB ttys (observed on PL2303 and MCT) - * and the rest of the code doesn't _REALLY_ handle the partial - * write/retry case anyway. - robertl - */ - if((psd->fd = open(port, O_RDWR))==-1) - { - GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); - gps_errno = SERIAL_ERROR; - return 0; - } - - if(tcgetattr(psd->fd,&psd->gps_ttysave)==-1) - { - gps_errno = HARDWARE_ERROR; - GPS_Serial_Error("SERIAL: tcgetattr error"); - return 0; - } - tty = psd->gps_ttysave; - - tty.c_cflag &= ~(CSIZE); - tty.c_cflag |= (CREAD | CS8 | CLOCAL); - cfsetospeed(&tty,B9600); - cfsetispeed(&tty,B9600); - - tty.c_lflag &= 0x0; - tty.c_iflag &= 0x0; - tty.c_oflag &= 0x0; - tty.c_cc[VMIN] = 1; - tty.c_cc[VTIME] = 0; - - if(tcsetattr(psd->fd,TCSANOW|TCSAFLUSH,&tty)==-1) - { - GPS_Serial_Error("SERIAL: tcsetattr error"); - return 0; - } + struct termios tty; + posix_serial_data *psd = (posix_serial_data *)dh; + + /* + * This originally had O_NDELAY | O_NOCTTY in here, but this + * causes problems with Linux USB ttys (observed on PL2303 and MCT) + * and the rest of the code doesn't _REALLY_ handle the partial + * write/retry case anyway. - robertl + */ + if ((psd->fd = open(port, O_RDWR))==-1) { + GPS_Serial_Error("XSERIAL: Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + if (tcgetattr(psd->fd,&psd->gps_ttysave)==-1) { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcgetattr error"); + return 0; + } + tty = psd->gps_ttysave; + + tty.c_cflag &= ~(CSIZE); + tty.c_cflag |= (CREAD | CS8 | CLOCAL); + cfsetospeed(&tty,B9600); + cfsetispeed(&tty,B9600); + + tty.c_lflag &= 0x0; + tty.c_iflag &= 0x0; + tty.c_oflag &= 0x0; + tty.c_cc[VMIN] = 1; + tty.c_cc[VTIME] = 0; + + if (tcsetattr(psd->fd,TCSANOW|TCSAFLUSH,&tty)==-1) { + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + return 1; } /* @@ -295,56 +292,60 @@ int32 GPS_Serial_Open(gpsdevh *dh, const char *port) */ void GPS_Serial_Error(const char *mb, ...) { - va_list ap; - char msg[200]; - char *s; - int b; - - va_start(ap, mb); - b = vsnprintf(msg, sizeof(msg), mb, ap); - s = msg + b; - *s++ = ':'; - *s++ = ' '; - *s++ = '\0'; - -// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, + va_list ap; + char msg[200]; + char *s; + int b; + + va_start(ap, mb); + b = vsnprintf(msg, sizeof(msg), mb, ap); + s = msg + b; + *s++ = ':'; + *s++ = ' '; + *s++ = '\0'; + +// FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, // GetLastError(), 0, s, sizeof(msg) - b - 2, 0 ); - strcat(msg, strerror(errno)); - GPS_Error(msg); + strcat(msg, strerror(errno)); + GPS_Error(msg); } int32 GPS_Serial_Read(gpsdevh *dh, void *ibuf, int size) { - posix_serial_data *psd = (posix_serial_data *)dh; + posix_serial_data *psd = (posix_serial_data *)dh; #if GARMULATOR - static int l; - static char *rp; - char **rxp = &rxdata[l]; - char *hex; - char *rx = *rxp; - char *ib = ibuf; - - if (!rp) rp = rxdata[0]; - - /* Skip over nulls in our pasted strings */ - if (*rp == 0) { - rp = rxdata[++l]; - } - - *ib = strtoul(rp, &rp, 16); - if (*rp) rp++; - fprintf(stderr, "."); - return 1; + static int l; + static char *rp; + char **rxp = &rxdata[l]; + char *hex; + char *rx = *rxp; + char *ib = ibuf; + + if (!rp) { + rp = rxdata[0]; + } + + /* Skip over nulls in our pasted strings */ + if (*rp == 0) { + rp = rxdata[++l]; + } + + *ib = strtoul(rp, &rp, 16); + if (*rp) { + rp++; + } + fprintf(stderr, "."); + return 1; #else - return read(psd->fd, ibuf, size); + return read(psd->fd, ibuf, size); #endif } int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) { - posix_serial_data *psd = (posix_serial_data *)dh; - return write(psd->fd, obuf, size); + posix_serial_data *psd = (posix_serial_data *)dh; + return write(psd->fd, obuf, size); } @@ -358,16 +359,15 @@ int32 GPS_Serial_Write(gpsdevh *dh, const void *obuf, int size) ************************************************************************/ int32 GPS_Serial_Flush(gpsdevh *fd) { - posix_serial_data *psd = (posix_serial_data *)fd; + posix_serial_data *psd = (posix_serial_data *)fd; - if(tcflush(psd->fd,TCIOFLUSH)) - { - GPS_Serial_Error("SERIAL: tcflush error"); - gps_errno = SERIAL_ERROR; - return 0; - } + if (tcflush(psd->fd,TCIOFLUSH)) { + GPS_Serial_Error("SERIAL: tcflush error"); + gps_errno = SERIAL_ERROR; + return 0; + } - return 1; + return 1; } @@ -384,23 +384,21 @@ int32 GPS_Serial_Flush(gpsdevh *fd) int32 GPS_Serial_Close(gpsdevh *fd) { - posix_serial_data *psd = (posix_serial_data *)fd; - - if(tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) - { - gps_errno = HARDWARE_ERROR; - GPS_Serial_Error("SERIAL: tcsetattr error"); - return 0; - } - - if(close(psd->fd)==-1) - { - GPS_Serial_Error("SERIAL: Error closing serial port"); - gps_errno = SERIAL_ERROR; - return 0; - } - - return 1; + posix_serial_data *psd = (posix_serial_data *)fd; + + if (tcsetattr(psd->fd, TCSAFLUSH, &psd->gps_ttysave)==-1) { + gps_errno = HARDWARE_ERROR; + GPS_Serial_Error("SERIAL: tcsetattr error"); + return 0; + } + + if (close(psd->fd)==-1) { + GPS_Serial_Error("SERIAL: Error closing serial port"); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; } @@ -415,30 +413,32 @@ int32 GPS_Serial_Close(gpsdevh *fd) int32 GPS_Serial_Chars_Ready(gpsdevh *dh) { - fd_set rec; - struct timeval t; - posix_serial_data *psd = (posix_serial_data *)dh; - int32 fd = psd->fd; + fd_set rec; + struct timeval t; + posix_serial_data *psd = (posix_serial_data *)dh; + int32 fd = psd->fd; #if GARMULATOR - static foo; - /* Return sporadic reads just to torment the rest of the code. */ - if ((foo++ & 0xf) == 0) - return 1; - else - return 0; + static foo; + /* Return sporadic reads just to torment the rest of the code. */ + if ((foo++ & 0xf) == 0) { + return 1; + } else { + return 0; + } #endif - FD_ZERO(&rec); - FD_SET(fd,&rec); + FD_ZERO(&rec); + FD_SET(fd,&rec); - t.tv_sec = 0; - t.tv_usec = 1000; - (void) select(fd+1,&rec,NULL,NULL,&t); - if(FD_ISSET(fd,&rec)) - return 1; + t.tv_sec = 0; + t.tv_usec = 1000; + (void) select(fd+1,&rec,NULL,NULL,&t); + if (FD_ISSET(fd,&rec)) { + return 1; + } - return 0; + return 0; } @@ -447,7 +447,7 @@ int32 GPS_Serial_Chars_Ready(gpsdevh *dh) ** ** Wait 80 milliseconds before testing for input. The GPS delay ** appears to be around 40-50 milliseconds. Doubling the value is to -** allow some leeway. +** allow some leeway. ** ** @param [r] fd [int32 ] file descriptor ** @@ -456,21 +456,22 @@ int32 GPS_Serial_Chars_Ready(gpsdevh *dh) int32 GPS_Serial_Wait(gpsdevh *dh) { - fd_set rec; - struct timeval t; - posix_serial_data *psd = (posix_serial_data *)dh; + fd_set rec; + struct timeval t; + posix_serial_data *psd = (posix_serial_data *)dh; - FD_ZERO(&rec); - FD_SET(psd->fd,&rec); + FD_ZERO(&rec); + FD_SET(psd->fd,&rec); - t.tv_sec = 0; - t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ + t.tv_sec = 0; + t.tv_usec = 180000; /* Microseconds before GPS sends A001 */ - (void) select(psd->fd+1,&rec,NULL,NULL,&t); - if(FD_ISSET(psd->fd,&rec)) - return 1; + (void) select(psd->fd+1,&rec,NULL,NULL,&t); + if (FD_ISSET(psd->fd,&rec)) { + return 1; + } - return 0; + return 0; } @@ -487,17 +488,16 @@ int32 GPS_Serial_Wait(gpsdevh *dh) int32 GPS_Serial_On(const char *port, gpsdevh **dh) { - posix_serial_data *psd = xcalloc(sizeof (posix_serial_data), 1); - *dh = (gpsdevh*) psd; - - if(!GPS_Serial_Open((gpsdevh *) psd,port)) - { - GPS_Error("Cannot open serial port '%s'", port); - gps_errno = SERIAL_ERROR; - return 0; - } + posix_serial_data *psd = xcalloc(sizeof(posix_serial_data), 1); + *dh = (gpsdevh*) psd; - return 1; + if (!GPS_Serial_Open((gpsdevh *) psd,port)) { + GPS_Error("Cannot open serial port '%s'", port); + gps_errno = SERIAL_ERROR; + return 0; + } + + return 1; } @@ -515,15 +515,14 @@ int32 GPS_Serial_On(const char *port, gpsdevh **dh) int32 GPS_Serial_Off(gpsdevh *dh) { - if(!GPS_Serial_Close(dh)) - { - GPS_Error("Error Closing port"); - gps_errno = HARDWARE_ERROR; - return 0; - } - dh = NULL; - - return 1; + if (!GPS_Serial_Close(dh)) { + GPS_Error("Error Closing port"); + gps_errno = HARDWARE_ERROR; + return 0; + } + dh = NULL; + + return 1; } #endif /* __WIN32__ */ diff --git a/gpsbabel/jeeps/gpsserial.h b/gpsbabel/jeeps/gpsserial.h index bf245105e..cb29d66a2 100644 --- a/gpsbabel/jeeps/gpsserial.h +++ b/gpsbabel/jeeps/gpsserial.h @@ -11,22 +11,22 @@ extern "C" #define usecDELAY 180000 /* Microseconds before GPS sends A001 */ -int32 GPS_Serial_Chars_Ready(gpsdevh * fd); + int32 GPS_Serial_Chars_Ready(gpsdevh * fd); // int32 GPS_Serial_Close(int32 fd, const char *port); // int32 GPS_Serial_Open(int32 *fd, const char *port); // int32 GPS_Serial_Open_NMEA(int32 *fd, const char *port); // int32 GPS_Serial_Restoretty(const char *port); // int32 GPS_Serial_Savetty(const char *port); -int32 GPS_Serial_On(const char *port, gpsdevh **fd); -int32 GPS_Serial_Off(gpsdevh *fd); -int32 GPS_Serial_Wait(gpsdevh *fd); -int32 GPS_Serial_Flush(gpsdevh *fd); + int32 GPS_Serial_On(const char *port, gpsdevh **fd); + int32 GPS_Serial_Off(gpsdevh *fd); + int32 GPS_Serial_Wait(gpsdevh *fd); + int32 GPS_Serial_Flush(gpsdevh *fd); // int32 GPS_Serial_On_NMEA(const char *port, gpsdevh **fd); -int32 GPS_Serial_Read(gpsdevh *fd, void *ibuf, int size); -int32 GPS_Serial_Write(gpsdevh *fd, const void *obuf, int size); -int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); -int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); -void GPS_Serial_Error(const char *hdr, ...); + int32 GPS_Serial_Read(gpsdevh *fd, void *ibuf, int size); + int32 GPS_Serial_Write(gpsdevh *fd, const void *obuf, int size); + int32 GPS_Serial_Write_Packet(gpsdevh *fd, GPS_PPacket packet); + int32 GPS_Serial_Send_Ack(gpsdevh *fd, GPS_PPacket *tra, GPS_PPacket *rec); + void GPS_Serial_Error(const char *hdr, ...); #endif diff --git a/gpsbabel/jeeps/gpsusbcommon.c b/gpsbabel/jeeps/gpsusbcommon.c index 26d1264c3..63a299f63 100644 --- a/gpsbabel/jeeps/gpsusbcommon.c +++ b/gpsbabel/jeeps/gpsusbcommon.c @@ -30,8 +30,8 @@ */ enum { - rs_fromintr, - rs_frombulk + rs_fromintr, + rs_frombulk } receive_state; static gusb_llops_t *gusb_llops; @@ -43,229 +43,236 @@ static gusb_llops_t *gusb_llops; void gusb_register_ll(gusb_llops_t *p) { - gusb_llops = p; + gusb_llops = p; } int gusb_close(gpsdevh *dh) { - garmin_usb_packet scratch; + garmin_usb_packet scratch; - memset(&scratch, 0, sizeof(scratch)); + memset(&scratch, 0, sizeof(scratch)); - switch (receive_state) { - case rs_frombulk: - gusb_cmd_get(&scratch, sizeof(scratch)); - break; - default: - break; - } + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(&scratch, sizeof(scratch)); + break; + default: + break; + } - gusb_llops->llop_close(dh); - return 1; + gusb_llops->llop_close(dh); + return 1; #if BOOGER - garmin_usb_packet scratch = {0}; -abort(); - switch (receive_state) { - case rs_frombulk: - gusb_cmd_get(dh, &scratch, sizeof(scratch)); - break; - } - - return 1; + garmin_usb_packet scratch = {0}; + abort(); + switch (receive_state) { + case rs_frombulk: + gusb_cmd_get(dh, &scratch, sizeof(scratch)); + break; + } + + return 1; #endif } -int +int gusb_cmd_get(garmin_usb_packet *ibuf, size_t sz) { - int rv; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; - int orig_receive_state; - unsigned short pkt_id; + int rv; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int orig_receive_state; + unsigned short pkt_id; top: - orig_receive_state = receive_state; - switch (receive_state) { - case rs_fromintr: - rv = gusb_llops->llop_get_intr(ibuf, sz); - break; - case rs_frombulk: - rv = gusb_llops->llop_get_bulk(ibuf, sz); - break; - default: - fatal("Unknown receiver state %d\n", receive_state); - } - - pkt_id = le_read16(&ibuf->gusb_pkt.pkt_id); - if (gps_show_bytes) { - int i; - const char *m1, *m2; - unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); - - GPS_Diag("RX (%s) [%d]:", - receive_state == rs_fromintr ? "intr" : "bulk", rv); - - for(i=0;i 0) && (pkt_id == GUSB_REQUEST_BULK)) { - receive_state = rs_frombulk; - goto top; - } - /* - * If we were reading from the bulk pipe and we just got - * a zero request, adjust our internal state. - * It's tempting to retry the read here to hide this "stray" - * packet from our callers, but that only works when you know - * there's another packet coming. That works in every case - * except the A000 discovery sequence. - */ - if ((receive_state == rs_frombulk) && (rv <= 0)) { - receive_state = rs_fromintr; - } - - return rv; + orig_receive_state = receive_state; + switch (receive_state) { + case rs_fromintr: + rv = gusb_llops->llop_get_intr(ibuf, sz); + break; + case rs_frombulk: + rv = gusb_llops->llop_get_bulk(ibuf, sz); + break; + default: + fatal("Unknown receiver state %d\n", receive_state); + } + + pkt_id = le_read16(&ibuf->gusb_pkt.pkt_id); + if (gps_show_bytes) { + int i; + const char *m1, *m2; + unsigned short pkttype = le_read16(&ibuf->gusb_pkt.databuf[0]); + + GPS_Diag("RX (%s) [%d]:", + receive_state == rs_fromintr ? "intr" : "bulk", rv); + + for (i=0; i 0) && (pkt_id == GUSB_REQUEST_BULK)) { + receive_state = rs_frombulk; + goto top; + } + /* + * If we were reading from the bulk pipe and we just got + * a zero request, adjust our internal state. + * It's tempting to retry the read here to hide this "stray" + * packet from our callers, but that only works when you know + * there's another packet coming. That works in every case + * except the A000 discovery sequence. + */ + if ((receive_state == rs_frombulk) && (rv <= 0)) { + receive_state = rs_fromintr; + } + + return rv; } -int +int gusb_cmd_send(const garmin_usb_packet *opkt, size_t sz) { - unsigned int rv, i; + unsigned int rv, i; - unsigned char *obuf = (unsigned char *) &opkt->dbuf; - const char *m1, *m2; + unsigned char *obuf = (unsigned char *) &opkt->dbuf; + const char *m1, *m2; - rv = gusb_llops->llop_send(opkt, sz); + rv = gusb_llops->llop_send(opkt, sz); - if (gps_show_bytes) { - const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); - const unsigned short pkt_id = le_read16(&opkt->gusb_pkt.pkt_id); - GPS_Diag("TX [%d]:", sz); + if (gps_show_bytes) { + const unsigned short pkttype = le_read16(&opkt->gusb_pkt.databuf[0]); + const unsigned short pkt_id = le_read16(&opkt->gusb_pkt.pkt_id); + GPS_Diag("TX [%d]:", sz); - for(i=0;imax_tx_size)) { - gusb_cmd_send(opkt, 0); - } + if (sz && !(sz % gusb_llops->max_tx_size)) { + gusb_cmd_send(opkt, 0); + } - return (rv); + return (rv); } void gusb_list_units() { - int i; - - for (i = 0; i < GUSB_MAX_UNITS; i++) { - if (garmin_unit_info[i].serial_number) { - printf("%d %lu %lu %s\n", i, - garmin_unit_info[i].serial_number, - garmin_unit_info[i].unit_id, - garmin_unit_info[i].product_identifier - ); - } - } + int i; + + for (i = 0; i < GUSB_MAX_UNITS; i++) { + if (garmin_unit_info[i].serial_number) { + printf("%d %lu %lu %s\n", i, + garmin_unit_info[i].serial_number, + garmin_unit_info[i].unit_id, + garmin_unit_info[i].product_identifier + ); + } + } } void -gusb_id_unit(struct garmin_unit_info *gu) +gusb_id_unit(struct garmin_unit_info *gu) { - static const char oid[12] = - {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int i; - - gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); - - for (i = 0; i < 25; i++) { - iresp.gusb_pkt.type = 0; - if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { - return; - } - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { - gu->product_identifier = xstrdup((char *) iresp.gusb_pkt.databuf+4); - gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); - gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); - } - /* - * My goodnesss, this is fragile. During command syncup, - * we need to know if we're at the end. The 0xfd packet - * is promised by Garmin engineering to be the last. - */ - if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) return; - } - fatal("Unable to sync with Garmin USB device in %d attempts.", i); -} + static const char oid[12] = + {20, 0, 0, 0, 0xfe, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + gusb_cmd_send((garmin_usb_packet *)oid, sizeof(oid)); + + for (i = 0; i < 25; i++) { + iresp.gusb_pkt.type = 0; + if (gusb_cmd_get(&iresp, sizeof(iresp)) < 0) { + return; + } + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xff) { + gu->product_identifier = xstrdup((char *) iresp.gusb_pkt.databuf+4); + gu->unit_id = le_read16(iresp.gusb_pkt.databuf+0); + gu->unit_version = le_read16(iresp.gusb_pkt.databuf+2); + } + /* + * My goodnesss, this is fragile. During command syncup, + * we need to know if we're at the end. The 0xfd packet + * is promised by Garmin engineering to be the last. + */ + if (le_read16(iresp.gusb_pkt.pkt_id) == 0xfd) { + return; + } + } + fatal("Unable to sync with Garmin USB device in %d attempts.", i); +} void gusb_syncup(void) { - static int unit_number; - static const char oinit[12] = - {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; - garmin_usb_packet iresp; - int i; - - /* - * This is our first communication with the unit. - */ - receive_state = rs_fromintr; - - for(i = 0; i < 25; i++) { - le_write16(&iresp.gusb_pkt.pkt_id, 0); - le_write32(&iresp.gusb_pkt.datasz, 0); - le_write32(&iresp.gusb_pkt.databuf, 0); - - gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); - gusb_cmd_get(&iresp, sizeof(iresp)); - - if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && - (le_read32(iresp.gusb_pkt.datasz) == 4)) { - unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); - garmin_unit_info[unit_number].serial_number = serial_number; - gusb_id_unit(&garmin_unit_info[unit_number]); - - unit_number++; - - return; - } - } - fatal("Unable to establish USB syncup\n"); + static int unit_number; + static const char oinit[12] = + {0, 0, 0, 0, GUSB_SESSION_START, 0, 0, 0, 0, 0, 0, 0}; + garmin_usb_packet iresp; + int i; + + /* + * This is our first communication with the unit. + */ + receive_state = rs_fromintr; + + for (i = 0; i < 25; i++) { + le_write16(&iresp.gusb_pkt.pkt_id, 0); + le_write32(&iresp.gusb_pkt.datasz, 0); + le_write32(&iresp.gusb_pkt.databuf, 0); + + gusb_cmd_send((const garmin_usb_packet *) oinit, sizeof(oinit)); + gusb_cmd_get(&iresp, sizeof(iresp)); + + if ((le_read16(iresp.gusb_pkt.pkt_id) == GUSB_SESSION_ACK) && + (le_read32(iresp.gusb_pkt.datasz) == 4)) { + unsigned serial_number = le_read32(iresp.gusb_pkt.databuf); + garmin_unit_info[unit_number].serial_number = serial_number; + gusb_id_unit(&garmin_unit_info[unit_number]); + + unit_number++; + + return; + } + } + fatal("Unable to establish USB syncup\n"); } diff --git a/gpsbabel/jeeps/gpsusbcommon.h b/gpsbabel/jeeps/gpsusbcommon.h index b0865f5f0..323c843e6 100644 --- a/gpsbabel/jeeps/gpsusbcommon.h +++ b/gpsbabel/jeeps/gpsusbcommon.h @@ -25,14 +25,14 @@ */ typedef int (*gusb_llop_get)(garmin_usb_packet *ibuf, size_t sz); typedef int (*gusb_llop_send)(const garmin_usb_packet *opkt, size_t sz); -typedef int (*gusb_llop_close) (gpsdevh *dh); +typedef int (*gusb_llop_close)(gpsdevh *dh); typedef struct gusb_llops { - gusb_llop_get llop_get_intr; - gusb_llop_get llop_get_bulk; - gusb_llop_send llop_send; - gusb_llop_close llop_close; - int max_tx_size; + gusb_llop_get llop_get_intr; + gusb_llop_get llop_get_bulk; + gusb_llop_send llop_send; + gusb_llop_close llop_close; + int max_tx_size; } gusb_llops_t; /* Provided by the common code. */ diff --git a/gpsbabel/jeeps/gpsusbread.c b/gpsbabel/jeeps/gpsusbread.c index 5db7d36a9..363d5d2f2 100644 --- a/gpsbabel/jeeps/gpsusbread.c +++ b/gpsbabel/jeeps/gpsusbread.c @@ -30,80 +30,79 @@ */ int32 GPS_Packet_Read_usb(gpsdevh *dh, GPS_PPacket *packet, int eat_bulk) { - int32 n; - int32 payload_size; + int32 n; + int32 payload_size; - garmin_usb_packet pkt; + garmin_usb_packet pkt; - memset(&pkt, 0, sizeof(pkt)); + memset(&pkt, 0, sizeof(pkt)); do_over: - n = gusb_cmd_get(&pkt, sizeof(pkt)); + n = gusb_cmd_get(&pkt, sizeof(pkt)); - if ( n < 0 ) { - /* - * We (probably) used to have a GPS and it went away - * while we were speaking with it. Perhaps batteries - * died or it was unplugged or something. - */ - gps_errno = PROTOCOL_ERROR; - return n; - } + if (n < 0) { + /* + * We (probably) used to have a GPS and it went away + * while we were speaking with it. Perhaps batteries + * died or it was unplugged or something. + */ + gps_errno = PROTOCOL_ERROR; + return n; + } - /* - * This is a horrible hack for 276/296. This family sometimes - * switches between bulk and interrupt on EVERY packet. Rather - * than bother all the callers with that bit of unpleasantness, - * silently consume zero byte "switch back to intr" packets here. - * - * The one caller that doesn't want this hidden is device discovery - * in the A000 handler. - */ - if ((n == 0) && eat_bulk) { - goto do_over; - } - - /* We sometimes get corrupted packets during a track log transfer - * where the first byte in a packet is lost, causing all remaining - * bytes in this packet to be shifted. So far, this has only been - * observed on a Forerunner 305 (both on Linux and Windows). The - * cause is unknown, but it seems to be timing dependent. - * We try to detect the corruption mainly by checking reserved bytes - * 3 and 7 which normally should be 0, the remaining comparisons are - * only sanity checks and they alone could also trigger in case of - * valid packets. Note: We can't detect corrupted packets with an ID - * or length that's a multiple of 256, but such corrupted packets - * haven't been observed so far. - */ - if (gps_save_id == 484 - && pkt.gusb_pkt.type == 0 && pkt.gusb_pkt.reserved1 == 0 - && pkt.gusb_pkt.reserved2 == 0 && pkt.gusb_pkt.reserved3 != 0 - && pkt.gusb_pkt.pkt_id[0] <= 4 && pkt.gusb_pkt.pkt_id[1] == 0 - && pkt.gusb_pkt.reserved6 == 0 && pkt.gusb_pkt.reserved7 != 0) { - memmove(&pkt.dbuf[1], &pkt.dbuf[0], sizeof(pkt) - 1); - pkt.gusb_pkt.type = 20; - } - - /* - * Populate members of serial packet from USB packet. The - * copy here seems wasteful, but teaching all the callers about - * a structure with the "data" member being in a different place - * (Since the protocol packets was badly exposed in the core - * design of jeeps) is even more painful. - */ - (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id); - payload_size = le_read32(&pkt.gusb_pkt.datasz); - if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE) - { - /* If you get this, the packet might have been corrupted - * by the unit. Have a look at the corruption detection - * code above. - */ - GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size); - gps_errno = FRAMING_ERROR; - return 0; - } - (*packet)->n = payload_size; - memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); - - return 1; + /* + * This is a horrible hack for 276/296. This family sometimes + * switches between bulk and interrupt on EVERY packet. Rather + * than bother all the callers with that bit of unpleasantness, + * silently consume zero byte "switch back to intr" packets here. + * + * The one caller that doesn't want this hidden is device discovery + * in the A000 handler. + */ + if ((n == 0) && eat_bulk) { + goto do_over; + } + + /* We sometimes get corrupted packets during a track log transfer + * where the first byte in a packet is lost, causing all remaining + * bytes in this packet to be shifted. So far, this has only been + * observed on a Forerunner 305 (both on Linux and Windows). The + * cause is unknown, but it seems to be timing dependent. + * We try to detect the corruption mainly by checking reserved bytes + * 3 and 7 which normally should be 0, the remaining comparisons are + * only sanity checks and they alone could also trigger in case of + * valid packets. Note: We can't detect corrupted packets with an ID + * or length that's a multiple of 256, but such corrupted packets + * haven't been observed so far. + */ + if (gps_save_id == 484 + && pkt.gusb_pkt.type == 0 && pkt.gusb_pkt.reserved1 == 0 + && pkt.gusb_pkt.reserved2 == 0 && pkt.gusb_pkt.reserved3 != 0 + && pkt.gusb_pkt.pkt_id[0] <= 4 && pkt.gusb_pkt.pkt_id[1] == 0 + && pkt.gusb_pkt.reserved6 == 0 && pkt.gusb_pkt.reserved7 != 0) { + memmove(&pkt.dbuf[1], &pkt.dbuf[0], sizeof(pkt) - 1); + pkt.gusb_pkt.type = 20; + } + + /* + * Populate members of serial packet from USB packet. The + * copy here seems wasteful, but teaching all the callers about + * a structure with the "data" member being in a different place + * (Since the protocol packets was badly exposed in the core + * design of jeeps) is even more painful. + */ + (*packet)->type = le_read16(&pkt.gusb_pkt.pkt_id); + payload_size = le_read32(&pkt.gusb_pkt.datasz); + if (payload_size<0 || payload_size>MAX_GPS_PACKET_SIZE) { + /* If you get this, the packet might have been corrupted + * by the unit. Have a look at the corruption detection + * code above. + */ + GPS_Error("GPS_Packet_Read_usb: Bad payload size %d", payload_size); + gps_errno = FRAMING_ERROR; + return 0; + } + (*packet)->n = payload_size; + memcpy((*packet)->data, &pkt.gusb_pkt.databuf, payload_size); + + return 1; } diff --git a/gpsbabel/jeeps/gpsusbsend.c b/gpsbabel/jeeps/gpsusbsend.c index 9aee54c7e..cacb3c54d 100644 --- a/gpsbabel/jeeps/gpsusbsend.c +++ b/gpsbabel/jeeps/gpsusbsend.c @@ -28,18 +28,18 @@ int32 GPS_Write_Packet_usb(gpsdevh *dh, GPS_PPacket packet) { - garmin_usb_packet gp; - memset(&gp, 0, sizeof(gp)); + garmin_usb_packet gp; + memset(&gp, 0, sizeof(gp)); - /* - * Take the "portable" GPS_Packet data and put them into - * the USB packet that we will put on the wire. - */ - gp.gusb_pkt.type = 0x14; - le_write16(&gp.gusb_pkt.pkt_id, packet->type); - le_write32(&gp.gusb_pkt.datasz, packet->n ); - memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n); + /* + * Take the "portable" GPS_Packet data and put them into + * the USB packet that we will put on the wire. + */ + gp.gusb_pkt.type = 0x14; + le_write16(&gp.gusb_pkt.pkt_id, packet->type); + le_write32(&gp.gusb_pkt.datasz, packet->n); + memcpy(&gp.gusb_pkt.databuf, packet->data, packet->n); - return gusb_cmd_send(&gp, packet->n + 12); + return gusb_cmd_send(&gp, packet->n + 12); } diff --git a/gpsbabel/jeeps/gpsusbstub.c b/gpsbabel/jeeps/gpsusbstub.c index 0838c1b5a..5d80e7fec 100644 --- a/gpsbabel/jeeps/gpsusbstub.c +++ b/gpsbabel/jeeps/gpsusbstub.c @@ -26,15 +26,15 @@ #include "../defs.h" -#if !HAVE_LIBUSB +#if !HAVE_LIBUSB const char no_usb[] = "USB support is not available in this build.\n"; int gusb_init(const char *portname) { - fatal(no_usb); - return 0; + fatal(no_usb); + return 0; } #endif /* defined(HAVE_LIBUSB) */ diff --git a/gpsbabel/jeeps/gpsusbwin.c b/gpsbabel/jeeps/gpsusbwin.c index 92fbcd137..dd6bea2bf 100644 --- a/gpsbabel/jeeps/gpsusbwin.c +++ b/gpsbabel/jeeps/gpsusbwin.c @@ -19,9 +19,9 @@ */ -#include -#include -#include +#include +#include +#include #include #include #include @@ -35,11 +35,11 @@ /* Constants from Garmin doc. */ -// {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0} +// {2C9C45C2-8E7D-4C08-A12D-816BBAE722C0} DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0xba, 0xe7, 0x22, 0xc0); -#define GARMIN_USB_API_VERSION 1 -#define GARMIN_USB_MAX_BUFFER_SIZE 4096 +#define GARMIN_USB_API_VERSION 1 +#define GARMIN_USB_MAX_BUFFER_SIZE 4096 #define GARMIN_USB_INTERRUPT_DATA_SIZE 64 #define IOCTL_GARMIN_USB_API_VERSION CTL_CODE \ @@ -50,138 +50,138 @@ DEFINE_GUID(GARMIN_GUID, 0x2c9c45c2L, 0x8e7d, 0x4c08, 0xa1, 0x2d, 0x81, 0x6b, 0x (FILE_DEVICE_UNKNOWN, 0x851, METHOD_BUFFERED, FILE_ANY_ACCESS) typedef struct { - int booger; + int booger; } winusb_unit_data; static HANDLE *usb_handle = INVALID_HANDLE_VALUE; static int usb_tx_packet_size ; static const gdx_info *gdx; -static int +static int gusb_win_close(gpsdevh *handle) { - if (usb_handle != INVALID_HANDLE_VALUE) { - CloseHandle(usb_handle); - usb_handle = INVALID_HANDLE_VALUE; - } + if (usb_handle != INVALID_HANDLE_VALUE) { + CloseHandle(usb_handle); + usb_handle = INVALID_HANDLE_VALUE; + } - return 0; + return 0; } static int gusb_win_get(garmin_usb_packet *ibuf, size_t sz) { - DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; - int tsz=0; - - while (sz) { - /* The driver wrongly (IMO) rejects reads smaller than - * GARMIN_USB_INTERRUPT_DATA_SIZE - */ - if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0, - buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) { - GPS_Serial_Error("Ioctl"); - fatal("ioctl\n"); - } - buf += rxed; - sz -= rxed; - tsz += rxed; - if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) { - break; - } - } - return tsz; + DWORD rxed = GARMIN_USB_INTERRUPT_DATA_SIZE; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int tsz=0; + + while (sz) { + /* The driver wrongly (IMO) rejects reads smaller than + * GARMIN_USB_INTERRUPT_DATA_SIZE + */ + if (!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_INTERRUPT_IN, NULL, 0, + buf, GARMIN_USB_INTERRUPT_DATA_SIZE, &rxed, NULL)) { + GPS_Serial_Error("Ioctl"); + fatal("ioctl\n"); + } + buf += rxed; + sz -= rxed; + tsz += rxed; + if (rxed < GARMIN_USB_INTERRUPT_DATA_SIZE) { + break; + } + } + return tsz; } static int gusb_win_get_bulk(garmin_usb_packet *ibuf, size_t sz) { - int n; - DWORD rsz; - unsigned char *buf = (unsigned char *) &ibuf->dbuf; + int n; + DWORD rsz; + unsigned char *buf = (unsigned char *) &ibuf->dbuf; - n = ReadFile(usb_handle, buf, sz, &rsz, NULL); + n = ReadFile(usb_handle, buf, sz, &rsz, NULL); - return rsz; + return rsz; } static int gusb_win_send(const garmin_usb_packet *opkt, size_t sz) { - DWORD rsz; - unsigned char *obuf = (unsigned char *) &opkt->dbuf; + DWORD rsz; + unsigned char *obuf = (unsigned char *) &opkt->dbuf; - /* The spec warns us about making writes an exact multiple - * of the packet size, but isn't clear whether we can issue - * data in a single call to WriteFile if it spans buffers. - */ - WriteFile(usb_handle, obuf, sz, &rsz, NULL); + /* The spec warns us about making writes an exact multiple + * of the packet size, but isn't clear whether we can issue + * data in a single call to WriteFile if it spans buffers. + */ + WriteFile(usb_handle, obuf, sz, &rsz, NULL); - if (rsz != sz) { - fatal ("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); - } + if (rsz != sz) { + fatal("Error sending %d bytes. Successfully sent %ld\n", sz, rsz); + } - return rsz; + return rsz; } static gusb_llops_t win_llops = { - gusb_win_get, - gusb_win_get_bulk, - gusb_win_send, - gusb_win_close + gusb_win_get, + gusb_win_get_bulk, + gusb_win_send, + gusb_win_close }; static HANDLE * garmin_usb_start(HDEVINFO* hdevinfo, SP_DEVICE_INTERFACE_DATA *infodata) { - DWORD size; - PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; - SP_DEVINFO_DATA devinfo; - - SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, - NULL, 0, &size, NULL); - - pdd = xmalloc(size); - pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); - - devinfo.cbSize = sizeof(SP_DEVINFO_DATA); - if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, - pdd, size, NULL, &devinfo)) { - GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); - return NULL; - } - - /* Whew. All that just to get something we can open... */ - GPS_Diag("Windows GUID for interface is \n\t%s\n", - pdd->DevicePath); - - if (usb_handle != INVALID_HANDLE_VALUE) { - fatal("garmin_usb_start called while device already started.\n"); - } - - usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, - 0, NULL, OPEN_EXISTING, 0, NULL ); - if (usb_handle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_ACCESS_DENIED) { - warning( -"Exclusive access is denied. It's likely that something else such as\n" -"Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); - } - GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); - return NULL; - } - - if(!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, - NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, - &size, NULL)) { - fatal("Couldn't get USB packet size.\n"); - } - win_llops.max_tx_size = usb_tx_packet_size; - - gusb_syncup(); - - return usb_handle; + DWORD size; + PSP_INTERFACE_DEVICE_DETAIL_DATA pdd = NULL; + SP_DEVINFO_DATA devinfo; + + SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + NULL, 0, &size, NULL); + + pdd = xmalloc(size); + pdd->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); + + devinfo.cbSize = sizeof(SP_DEVINFO_DATA); + if (!SetupDiGetDeviceInterfaceDetail(hdevinfo, infodata, + pdd, size, NULL, &devinfo)) { + GPS_Serial_Error("SetupDiGetDeviceInterfaceDetail"); + return NULL; + } + + /* Whew. All that just to get something we can open... */ + GPS_Diag("Windows GUID for interface is \n\t%s\n", + pdd->DevicePath); + + if (usb_handle != INVALID_HANDLE_VALUE) { + fatal("garmin_usb_start called while device already started.\n"); + } + + usb_handle = CreateFile(pdd->DevicePath, GENERIC_READ|GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + if (usb_handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_ACCESS_DENIED) { + warning( + "Exclusive access is denied. It's likely that something else such as\n" + "Nroute, Spanner, Google Earth, or GPSGate already has control of the device\n"); + } + GPS_Serial_Error("(usb) CreateFile on '%s' failed", pdd->DevicePath); + return NULL; + } + + if (!DeviceIoControl(usb_handle, IOCTL_GARMIN_USB_BULK_OUT_PACKET_SIZE, + NULL, 0, &usb_tx_packet_size, GARMIN_USB_INTERRUPT_DATA_SIZE, + &size, NULL)) { + fatal("Couldn't get USB packet size.\n"); + } + win_llops.max_tx_size = usb_tx_packet_size; + + gusb_syncup(); + + return usb_handle; } @@ -196,8 +196,8 @@ static char ** get_garmin_mountpoints(void) dlist[0] = NULL; if (GetLogicalDriveStringsA(BUFSIZE-1, szTemp)) { - while(*p) { - dlist = xrealloc(dlist, sizeof (*dlist ) * (++i + 1)); + while (*p) { + dlist = xrealloc(dlist, sizeof(*dlist) * (++i + 1)); // fprintf(stderr, "Found: %d, %s\n", i, p); dlist[i-1] = xstrdup(p); dlist[i] = NULL; @@ -215,80 +215,82 @@ static char ** get_garmin_mountpoints(void) int gusb_init(const char *pname, gpsdevh **dh) { - int req_unit_number = 0; - int un = 0; - int match; - - HDEVINFO hdevinfo; - SP_DEVICE_INTERFACE_DATA devinterface; - - winusb_unit_data *wud = xcalloc(sizeof (winusb_unit_data), 1); - *dh = (gpsdevh*) wud; - - gusb_register_ll(&win_llops); - - if (strlen(pname) > 4) { - if (0 == strcmp(pname+4, "list")) { - req_unit_number = -1; - } else { - req_unit_number = atoi(pname+4); - } - } - - hdevinfo = SetupDiGetClassDevs( (GUID *) &GARMIN_GUID, NULL, NULL, - DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); - - if (hdevinfo == INVALID_HANDLE_VALUE) { - GPS_Serial_Error("SetupDiGetClassDevs failed"); - warning("Is the Garmin USB driver installed?"); - return 0; - } - - devinterface.cbSize = sizeof(devinterface); - - if (req_unit_number >= 0) { - if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, - (GUID *) &GARMIN_GUID, - req_unit_number, &devinterface)) { - // If there were zero matches, we may be trying to talk to a "GPX Mode" device. - - - char **dlist = get_garmin_mountpoints(); - gdx = gdx_find_file(dlist); - if (gdx) return 1; - - - // Plan C. - GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); - warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.\nAre the Garmin USB drivers installed and functioning with other programs?\nIs it a storage based device like Nuvi, CO, or OR?\n If so, send GPX files to it, don't use this module.\n", un); - return 0; - } - /* We've matched. Now start the specific unit. */ - garmin_usb_start(hdevinfo, &devinterface); - return 1; - } - - /* - * Out unit nunber is less than zero, so loop over all units - * and display them. - */ - for(match = 0;;match++) { - if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, - (GUID *) &GARMIN_GUID, match, &devinterface)) { - if (GetLastError() == ERROR_NO_MORE_ITEMS) { - - break; - } else { - - GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); - warning("Is the Garmin USB unit number %d powered up and connected?", un); - return 0; - } - } - /* We've matched. Now start the specific unit. */ - garmin_usb_start(hdevinfo, &devinterface); - gusb_close(NULL); - } - gusb_list_units(); - exit (0); + int req_unit_number = 0; + int un = 0; + int match; + + HDEVINFO hdevinfo; + SP_DEVICE_INTERFACE_DATA devinterface; + + winusb_unit_data *wud = xcalloc(sizeof(winusb_unit_data), 1); + *dh = (gpsdevh*) wud; + + gusb_register_ll(&win_llops); + + if (strlen(pname) > 4) { + if (0 == strcmp(pname+4, "list")) { + req_unit_number = -1; + } else { + req_unit_number = atoi(pname+4); + } + } + + hdevinfo = SetupDiGetClassDevs((GUID *) &GARMIN_GUID, NULL, NULL, + DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); + + if (hdevinfo == INVALID_HANDLE_VALUE) { + GPS_Serial_Error("SetupDiGetClassDevs failed"); + warning("Is the Garmin USB driver installed?"); + return 0; + } + + devinterface.cbSize = sizeof(devinterface); + + if (req_unit_number >= 0) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, + req_unit_number, &devinterface)) { + // If there were zero matches, we may be trying to talk to a "GPX Mode" device. + + + char **dlist = get_garmin_mountpoints(); + gdx = gdx_find_file(dlist); + if (gdx) { + return 1; + } + + + // Plan C. + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?\nIs it really a USB unit? If it's serial, don't choose USB, choose serial.\nAre the Garmin USB drivers installed and functioning with other programs?\nIs it a storage based device like Nuvi, CO, or OR?\n If so, send GPX files to it, don't use this module.\n", un); + return 0; + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + return 1; + } + + /* + * Out unit nunber is less than zero, so loop over all units + * and display them. + */ + for (match = 0;; match++) { + if (!SetupDiEnumDeviceInterfaces(hdevinfo, NULL, + (GUID *) &GARMIN_GUID, match, &devinterface)) { + if (GetLastError() == ERROR_NO_MORE_ITEMS) { + + break; + } else { + + GPS_Serial_Error("SetupDiEnumDeviceInterfaces"); + warning("Is the Garmin USB unit number %d powered up and connected?", un); + return 0; + } + } + /* We've matched. Now start the specific unit. */ + garmin_usb_start(hdevinfo, &devinterface); + gusb_close(NULL); + } + gusb_list_units(); + exit(0); } diff --git a/gpsbabel/jeeps/gpsutil.c b/gpsbabel/jeeps/gpsutil.c index 4078e2e5e..fa962ea81 100644 --- a/gpsbabel/jeeps/gpsutil.c +++ b/gpsbabel/jeeps/gpsutil.c @@ -2,20 +2,20 @@ ** @source JEEPS utility functions ** ** @author Copyright (C) 1999 Alan Bleasby -** @version 1.0 +** @version 1.0 ** @modified Dec 28 1999 Alan Bleasby. First version ** @@ -** +** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Library General Public ** License as published by the Free Software Foundation; either ** version 2 of the License, or (at your option) any later version. -** +** ** This library is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. -** +** ** You should have received a copy of the GNU Library General Public ** License along with this library; if not, write to the ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, @@ -44,28 +44,27 @@ int32 gps_errno = 0; int32 GPS_Util_Little(void) { - static union lb - { - char chars[sizeof(int32)]; - int32 i; - } - data; - - if(!gps_endian_called) - { - gps_endian_called = 1; - data.i = 0; - *data.chars = '\1'; - if(data.i == 1) - GPS_Little = 1; - else - GPS_Little = 0; + static union lb { + char chars[sizeof(int32)]; + int32 i; + } + data; + + if (!gps_endian_called) { + gps_endian_called = 1; + data.i = 0; + *data.chars = '\1'; + if (data.i == 1) { + GPS_Little = 1; + } else { + GPS_Little = 0; } + } - return GPS_Little; + return GPS_Little; } - + /* @func GPS_Util_Get_Short ******************************************** ** ** Get a short from a string @@ -75,23 +74,20 @@ int32 GPS_Util_Little(void) US GPS_Util_Get_Short(const UC *s) { - static US ret; - UC *p; - - p = (UC *)&ret; - - if(!GPS_Little) - { - *p++ = *(s+1); - *p = *s; - } - else - { - *p++ = *s; - *p = *(s+1); - } + static US ret; + UC *p; + + p = (UC *)&ret; - return ret; + if (!GPS_Little) { + *p++ = *(s+1); + *p = *s; + } else { + *p++ = *s; + *p = *(s+1); + } + + return ret; } @@ -108,22 +104,19 @@ US GPS_Util_Get_Short(const UC *s) void GPS_Util_Put_Short(UC *s, const US v) { - UC *p; - - p = (UC *)&v; - - if(!GPS_Little) - { - *s++ = *(p+1); - *s = *p; - } - else - { - *s++ = *p; - *s = *(p+1); - } + UC *p; - return; + p = (UC *)&v; + + if (!GPS_Little) { + *s++ = *(p+1); + *s = *p; + } else { + *s++ = *p; + *s = *(p+1); + } + + return; } @@ -137,21 +130,23 @@ void GPS_Util_Put_Short(UC *s, const US v) double GPS_Util_Get_Double(const UC *s) { - double ret; - UC *p; - int32 i; + double ret; + UC *p; + int32 i; - p = (UC *)&ret; + p = (UC *)&ret; - - if(!GPS_Little) - for(i=sizeof(double)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(double);++i) - *p++ = s[i]; - return ret; + if (!GPS_Little) + for (i=sizeof(double)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(double); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -168,19 +163,21 @@ double GPS_Util_Get_Double(const UC *s) void GPS_Util_Put_Double(UC *s, const double v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(double)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(double);++i) - s[i] = *p++; + UC *p; + int32 i; - return; + p = (UC *)&v; + + if (!GPS_Little) + for (i=sizeof(double)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(double); ++i) { + s[i] = *p++; + } + + return; } @@ -195,21 +192,23 @@ void GPS_Util_Put_Double(UC *s, const double v) int32 GPS_Util_Get_Int(const UC *s) { - int32 ret; - UC *p; - int32 i; - - p = (UC *)&ret; - - - if(!GPS_Little) - for(i=sizeof(int32)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(int32);++i) - *p++ = s[i]; - - return ret; + int32 ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if (!GPS_Little) + for (i=sizeof(int32)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(int32); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -226,19 +225,21 @@ int32 GPS_Util_Get_Int(const UC *s) void GPS_Util_Put_Int(UC *s, const int32 v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(int32)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(int32);++i) - s[i] = *p++; + UC *p; + int32 i; - return; + p = (UC *)&v; + + if (!GPS_Little) + for (i=sizeof(int32)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(int32); ++i) { + s[i] = *p++; + } + + return; } @@ -252,21 +253,23 @@ void GPS_Util_Put_Int(UC *s, const int32 v) uint32 GPS_Util_Get_Uint(const UC *s) { - uint32 ret; - UC *p; - int32 i; - - p = (UC *)&ret; - - - if(!GPS_Little) - for(i=sizeof(uint32)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(uint32);++i) - *p++ = s[i]; - - return ret; + uint32 ret; + UC *p; + int32 i; + + p = (UC *)&ret; + + + if (!GPS_Little) + for (i=sizeof(uint32)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(uint32); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -283,19 +286,21 @@ uint32 GPS_Util_Get_Uint(const UC *s) void GPS_Util_Put_Uint(UC *s, const uint32 v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(uint32)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(uint32);++i) - s[i] = *p++; + UC *p; + int32 i; - return; + p = (UC *)&v; + + if (!GPS_Little) + for (i=sizeof(uint32)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(uint32); ++i) { + s[i] = *p++; + } + + return; } @@ -309,21 +314,23 @@ void GPS_Util_Put_Uint(UC *s, const uint32 v) float GPS_Util_Get_Float(const UC *s) { - float ret; - UC *p; - int32 i; + float ret; + UC *p; + int32 i; - p = (UC *)&ret; + p = (UC *)&ret; - - if(!GPS_Little) - for(i=sizeof(float)-1;i>-1;--i) - *p++ = s[i]; - else - for(i=0;i<(int32)sizeof(float);++i) - *p++ = s[i]; - return ret; + if (!GPS_Little) + for (i=sizeof(float)-1; i>-1; --i) { + *p++ = s[i]; + } + else + for (i=0; i<(int32)sizeof(float); ++i) { + *p++ = s[i]; + } + + return ret; } @@ -340,19 +347,21 @@ float GPS_Util_Get_Float(const UC *s) void GPS_Util_Put_Float(UC *s, const float v) { - UC *p; - int32 i; - - p = (UC *)&v; - - if(!GPS_Little) - for(i=sizeof(float)-1;i>-1;--i) - s[i] = *p++; - else - for(i=0;i<(int32)sizeof(float);++i) - s[i] = *p++; + UC *p; + int32 i; - return; + p = (UC *)&v; + + if (!GPS_Little) + for (i=sizeof(float)-1; i>-1; --i) { + s[i] = *p++; + } + else + for (i=0; i<(int32)sizeof(float); ++i) { + s[i] = *p++; + } + + return; } #if 0 @@ -369,24 +378,23 @@ void GPS_Util_Put_Float(UC *s, const float v) void GPS_Util_Canon(int32 state) { - static struct termios tty; - static struct termios sv; - - - if(state) - { - tcgetattr(1,&sv); - tcgetattr(1, &tty); - tty.c_cc[VMIN]='\1'; - tty.c_cc[VTIME]='\0'; - tcsetattr(1,TCSANOW,&tty); - tty.c_lflag &= ~(ICANON | ECHO); - tcsetattr(1, TCSANOW, &tty); - } - else - tcsetattr(1, TCSANOW, &sv); - - return; + static struct termios tty; + static struct termios sv; + + + if (state) { + tcgetattr(1,&sv); + tcgetattr(1, &tty); + tty.c_cc[VMIN]='\1'; + tty.c_cc[VTIME]='\0'; + tcsetattr(1,TCSANOW,&tty); + tty.c_lflag &= ~(ICANON | ECHO); + tcsetattr(1, TCSANOW, &tty); + } else { + tcsetattr(1, TCSANOW, &sv); + } + + return; } #endif @@ -398,50 +406,43 @@ void GPS_Util_Canon(int32 state) ** ** @param [r] fd [int32] file descriptor ** @param [r] state [int32] state=true->block state=false->non-block -** +** ** @return [int32] success ** @@ ****************************************************************************/ int32 GPS_Util_Block(int32 fd, int32 state) { - static int32 notcalled=1; - static int32 block; - static int32 noblock; - int32 f; - - gps_errno = HARDWARE_ERROR; - - if(notcalled) - { - notcalled = 0; - if((f=fcntl(fd,F_GETFL,0))==-1) - { - GPS_Error("Util_Block: FCNTL error"); - return 0; - } - block = f & ~O_NDELAY; - noblock = f | O_NDELAY; + static int32 notcalled=1; + static int32 block; + static int32 noblock; + int32 f; + + gps_errno = HARDWARE_ERROR; + + if (notcalled) { + notcalled = 0; + if ((f=fcntl(fd,F_GETFL,0))==-1) { + GPS_Error("Util_Block: FCNTL error"); + return 0; } - - if(state) - { - if(fcntl(fd,F_SETFL,block)==-1) - { - GPS_Error("Util_Block: Error blocking"); - return 0; - } + block = f & ~O_NDELAY; + noblock = f | O_NDELAY; + } + + if (state) { + if (fcntl(fd,F_SETFL,block)==-1) { + GPS_Error("Util_Block: Error blocking"); + return 0; } - else - { - if(fcntl(fd,F_SETFL,noblock)==-1) - { - GPS_Error("Util_Block: Error unblocking"); - return 0; - } + } else { + if (fcntl(fd,F_SETFL,noblock)==-1) { + GPS_Error("Util_Block: Error unblocking"); + return 0; } + } - return 1; + return 1; } #endif @@ -458,13 +459,14 @@ int32 GPS_Util_Block(int32 fd, int32 state) void GPS_Warning(char *s) { - if(!gps_warning) - return; - - fprintf(stderr,"[WARNING] %s\n",s); - fflush(stderr); - + if (!gps_warning) { return; + } + + fprintf(stderr,"[WARNING] %s\n",s); + fflush(stderr); + + return; } @@ -482,9 +484,9 @@ void GPS_Warning(char *s) void GPS_Fatal(char *s) { - fprintf(stderr,"[FATAL] %s\n",s); - exit(0); - return; + fprintf(stderr,"[FATAL] %s\n",s); + exit(0); + return; } @@ -501,19 +503,20 @@ void GPS_Fatal(char *s) void GPS_Error(char *fmt, ...) { - va_list argp; - va_start(argp, fmt); + va_list argp; + va_start(argp, fmt); - if(!gps_error) - return; + if (!gps_error) { + return; + } - fprintf(stderr, "[ERROR] "); - vfprintf(stderr, fmt, argp); - fprintf(stderr, "\n"); + fprintf(stderr, "[ERROR] "); + vfprintf(stderr, fmt, argp); + fprintf(stderr, "\n"); - va_end(argp); - return; + va_end(argp); + return; } @@ -527,8 +530,8 @@ void GPS_Error(char *fmt, ...) void GPS_Enable_Error(void) { - gps_error = 1; - return; + gps_error = 1; + return; } @@ -543,8 +546,8 @@ void GPS_Enable_Error(void) void GPS_Enable_Warning(void) { - gps_warning = 1; - return; + gps_warning = 1; + return; } @@ -559,8 +562,8 @@ void GPS_Enable_Warning(void) void GPS_Disable_Error(void) { - gps_error = 0; - return; + gps_error = 0; + return; } @@ -575,8 +578,8 @@ void GPS_Disable_Error(void) void GPS_Disable_Warning(void) { - gps_warning = 0; - return; + gps_warning = 0; + return; } @@ -593,15 +596,15 @@ void GPS_Disable_Warning(void) void GPS_User(const char *fmt, ...) { - va_list argp; - va_start (argp, fmt); + va_list argp; + va_start(argp, fmt); - if (gps_user) { - vfprintf(stdout, fmt, argp); - fflush(stdout); - } - - va_end(argp); + if (gps_user) { + vfprintf(stdout, fmt, argp); + fflush(stdout); + } + + va_end(argp); } /* @func GPS_Disable_User *********************************************** @@ -614,8 +617,8 @@ void GPS_User(const char *fmt, ...) void GPS_Disable_User(void) { - gps_user = 0; - return; + gps_user = 0; + return; } @@ -629,8 +632,8 @@ void GPS_Disable_User(void) void GPS_Enable_User(void) { - gps_user = 1; - return; + gps_user = 1; + return; } @@ -646,25 +649,26 @@ void GPS_Enable_User(void) void GPS_Diagnose(int32 c) { - if(!gps_show_bytes) - return; - - fprintf(stdout,"%d\n",(int)c); - fflush(stdout); - + if (!gps_show_bytes) { return; + } + + fprintf(stdout,"%d\n",(int)c); + fflush(stdout); + + return; } void GPS_Diag(const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); + va_list argp; + va_start(argp, fmt); - if(gps_show_bytes) { - vfprintf(stdout, fmt, argp); - } - va_end(argp); - return; + if (gps_show_bytes) { + vfprintf(stdout, fmt, argp); + } + va_end(argp); + return; } @@ -678,8 +682,8 @@ void GPS_Diag(const char *fmt, ...) void GPS_Enable_Diagnose(void) { - gps_show_bytes = 1; - return; + gps_show_bytes = 1; + return; } @@ -694,6 +698,6 @@ void GPS_Enable_Diagnose(void) void GPS_Disable_Diagnose(void) { - gps_show_bytes = 0; - return; + gps_show_bytes = 0; + return; } diff --git a/gpsbabel/jeeps/gpsutil.h b/gpsbabel/jeeps/gpsutil.h index faf1e0f06..d9469b264 100644 --- a/gpsbabel/jeeps/gpsutil.h +++ b/gpsbabel/jeeps/gpsutil.h @@ -9,37 +9,37 @@ extern "C" #include "gps.h" -int32 GPS_Util_Little(void); - -US GPS_Util_Get_Short(const UC *s); -void GPS_Util_Put_Short(UC *s, const US v); -int32 GPS_Util_Get_Int(const UC *s); -void GPS_Util_Put_Int(UC *s, const int32 v); -double GPS_Util_Get_Double(const UC *s); -void GPS_Util_Put_Double(UC *s, const double v); -float GPS_Util_Get_Float(const UC *s); -void GPS_Util_Put_Float(UC *s, const float v); -void GPS_Util_Canon(int32 state); -int32 GPS_Util_Block(int32 fd, int32 state); -void GPS_Util_Put_Uint(UC *s, const uint32 v); -uint32 GPS_Util_Get_Uint(const UC *s); - -void GPS_Warning(char *s); -void GPS_Error(char *fmt, ...); -void GPS_Serial_Error(const char *hdr, ...); -void GPS_Fatal(char *s); -void GPS_Enable_Error(void); -void GPS_Enable_Warning(void); -void GPS_Disable_Error(void); -void GPS_Disable_Warning(void); -void GPS_User(const char *fmt, ...); -void GPS_Disable_User(void); -void GPS_Enable_User(void); -void GPS_Diagnose(int32 c); -void GPS_Diag(const char *fmt, ...); - -void GPS_Enable_Diagnose(void); -void GPS_Disable_Diagnose(void); + int32 GPS_Util_Little(void); + + US GPS_Util_Get_Short(const UC *s); + void GPS_Util_Put_Short(UC *s, const US v); + int32 GPS_Util_Get_Int(const UC *s); + void GPS_Util_Put_Int(UC *s, const int32 v); + double GPS_Util_Get_Double(const UC *s); + void GPS_Util_Put_Double(UC *s, const double v); + float GPS_Util_Get_Float(const UC *s); + void GPS_Util_Put_Float(UC *s, const float v); + void GPS_Util_Canon(int32 state); + int32 GPS_Util_Block(int32 fd, int32 state); + void GPS_Util_Put_Uint(UC *s, const uint32 v); + uint32 GPS_Util_Get_Uint(const UC *s); + + void GPS_Warning(char *s); + void GPS_Error(char *fmt, ...); + void GPS_Serial_Error(const char *hdr, ...); + void GPS_Fatal(char *s); + void GPS_Enable_Error(void); + void GPS_Enable_Warning(void); + void GPS_Disable_Error(void); + void GPS_Disable_Warning(void); + void GPS_User(const char *fmt, ...); + void GPS_Disable_User(void); + void GPS_Enable_User(void); + void GPS_Diagnose(int32 c); + void GPS_Diag(const char *fmt, ...); + + void GPS_Enable_Diagnose(void); + void GPS_Disable_Diagnose(void); #endif diff --git a/gpsbabel/jeeps/main.c b/gpsbabel/jeeps/main.c index a8488248b..263b2fbbb 100644 --- a/gpsbabel/jeeps/main.c +++ b/gpsbabel/jeeps/main.c @@ -3,29 +3,29 @@ main() { - int n; - GPS_PWay *way; - GPS_PWay *array; + int n; + GPS_PWay *way; + GPS_PWay *array; - if (GPS_Init("/dev/ttyS0") < 0) { - fprintf(stderr, "Can't init\n"); - } - - if((n=GPS_Command_Get_Waypoint("/dev/ttyS0", &way))<0) { - fprintf(stderr, "can't get\n"); - return; - } + if (GPS_Init("/dev/ttyS0") < 0) { + fprintf(stderr, "Can't init\n"); + } + + if ((n=GPS_Command_Get_Waypoint("/dev/ttyS0", &way))<0) { + fprintf(stderr, "can't get\n"); + return; + } // fprintf(stdout," Done\n"); - GPS_Fmt_Print_Waypoint(way, n, stdout); + GPS_Fmt_Print_Waypoint(way, n, stdout); - array = (GPS_PWay *) calloc(1, sizeof(GPS_PWay)); - array[0] = GPS_Way_New(); - strcpy(array[0]->ident,"lower @#$%^&* rocks"); - strcpy(array[0]->cmnt,"COMMENTCOMMENTCOMMENTCOMMENTCOMMENT"); - array[0]->wpt_class = 0; - array[0]->lat = 1.234; - array[0]->lon = 1.234; -GPS_Command_Send_Waypoint("/dev/ttyS0", array, 1); + array = (GPS_PWay *) calloc(1, sizeof(GPS_PWay)); + array[0] = GPS_Way_New(); + strcpy(array[0]->ident,"lower @#$%^&* rocks"); + strcpy(array[0]->cmnt,"COMMENTCOMMENTCOMMENTCOMMENTCOMMENT"); + array[0]->wpt_class = 0; + array[0]->lat = 1.234; + array[0]->lon = 1.234; + GPS_Command_Send_Waypoint("/dev/ttyS0", array, 1); } diff --git a/gpsbabel/jogmap.c b/gpsbabel/jogmap.c index 9273f5249..48407d1bb 100644 --- a/gpsbabel/jogmap.c +++ b/gpsbabel/jogmap.c @@ -1,4 +1,4 @@ -/* +/* Support for XML files from jogmap.de @@ -27,9 +27,8 @@ static route_head *trk; -static arglist_t jogmap_args[] = -{ - ARG_TERMINATOR +static arglist_t jogmap_args[] = { + ARG_TERMINATOR }; #define MYNAME "xol" @@ -38,7 +37,7 @@ static arglist_t jogmap_args[] = void jogmap_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); } void @@ -58,72 +57,75 @@ jogmap_read(void) static void jogmap_markers(const char *args, const char **attrv) { - trk = route_head_alloc(); - track_add_head(trk); + trk = route_head_alloc(); + track_add_head(trk); } static void jogmap_marker(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - waypoint *wpt = waypt_new(); - - while (*avp) { - if (strcmp(avp[0], "lat") == 0) { - sscanf(avp[1], "%lf", - &wpt->latitude); - } else - if (strcmp(avp[0], "lng") == 0) { - sscanf(avp[1], "%lf", - &wpt->longitude); - } - - avp+=2; - } - - if (trk) track_add_wpt(trk, wpt); + const char **avp = &attrv[0]; + waypoint *wpt = waypt_new(); + + while (*avp) { + if (strcmp(avp[0], "lat") == 0) { + sscanf(avp[1], "%lf", + &wpt->latitude); + } else if (strcmp(avp[0], "lng") == 0) { + sscanf(avp[1], "%lf", + &wpt->longitude); + } + + avp+=2; + } + + if (trk) { + track_add_wpt(trk, wpt); + } } static xg_tag_mapping jogmap_map[] = { - { jogmap_markers, cb_start, "/markers" }, - { jogmap_marker, cb_start, "/markers/marker" }, - { NULL, 0, NULL } + { jogmap_markers, cb_start, "/markers" }, + { jogmap_marker, cb_start, "/markers/marker" }, + { NULL, 0, NULL } }; -static void +static void jogmap_rd_init(const char *fname) { - trk = NULL; - xml_init(fname, jogmap_map, NULL); + trk = NULL; + xml_init(fname, jogmap_map, NULL); } -static void +static void jogmap_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void jogmap_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } ff_vecs_t jogmap_vecs = { - ff_type_file, - { ff_cap_none, /* waypoints */ - ff_cap_read, /* tracks */ - ff_cap_none }, /* routes */ - jogmap_rd_init, - NULL, - jogmap_rd_deinit, - NULL, - jogmap_read, - NULL, - NULL, - jogmap_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read, /* tracks */ + ff_cap_none + }, /* routes */ + jogmap_rd_init, + NULL, + jogmap_rd_deinit, + NULL, + jogmap_read, + NULL, + NULL, + jogmap_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/jtr.c b/gpsbabel/jtr.c index 2fe5425b3..504946ef3 100644 --- a/gpsbabel/jtr.c +++ b/gpsbabel/jtr.c @@ -32,7 +32,7 @@ static arglist_t jtr_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static gbfile *fin, *fout; @@ -41,38 +41,42 @@ static avltree_t *trkpts; static time_t jtr_parse_time(const char *str, struct tm *tm, int *micro) { - long int hms; - char *dot; - - hms = strtol(str, &dot, 10); - if (hms > 0) { - tm->tm_sec = hms % 100; - hms = hms / 100; - tm->tm_min = hms % 100; - hms = hms / 100; - tm->tm_hour = hms % 100; - - if ((*dot == '.') && (micro != NULL)) *micro = atoi(dot + 1) * 10000; - - return mkgmtime(tm); - } - else return 0; + long int hms; + char *dot; + + hms = strtol(str, &dot, 10); + if (hms > 0) { + tm->tm_sec = hms % 100; + hms = hms / 100; + tm->tm_min = hms % 100; + hms = hms / 100; + tm->tm_hour = hms % 100; + + if ((*dot == '.') && (micro != NULL)) { + *micro = atoi(dot + 1) * 10000; + } + + return mkgmtime(tm); + } else { + return 0; + } } static time_t jtr_parse_date(const char *str, struct tm *tm) { - int dmy = atoi(str); - - if (dmy > 0) { - tm->tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm->tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm->tm_mday = dmy; - return mkgmtime(tm); - } - else return 0; + int dmy = atoi(str); + + if (dmy > 0) { + tm->tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm->tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm->tm_mday = dmy; + return mkgmtime(tm); + } else { + return 0; + } } /******************************************************************************* @@ -82,204 +86,264 @@ jtr_parse_date(const char *str, struct tm *tm) static void jtr_rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); - trkpts = avltree_init(0, MYNAME); + fin = gbfopen(fname, "r", MYNAME); + trkpts = avltree_init(0, MYNAME); } static void jtr_rd_deinit(void) { - avltree_done(trkpts); - gbfclose(fin); + avltree_done(trkpts); + gbfclose(fin); } static void jtr_read(void) { - char *str; - int line = 0; - route_head *trk = NULL; - - while ((str = gbfgetstr(fin))) { - waypoint *wpt; - struct tm tm; - char *tmp; - int column = -1; - char valid = 'V'; - double lat, lon; - float speed, course, mcourse, mvar, mdev; - time_t time = 0; - int micros = 0; - char buf[32]; - char mvardir, mdevdir; - - line++; - - str = lrtrim(str); - if (*str == '\0') continue; - - if (strncmp(str, "GEOTAG2,", 8) != 0) - fatal(MYNAME ": Unknown or unsupported file (missing \"GEOTAG2\")!\n"); - - memset(&tm, 0, sizeof(tm)); - lat = lon = 999; - speed = course = mcourse = mvar = mdev = -1; - mvardir = mdevdir = 0; - - column = -1; - tmp = str; - while ((str = csv_lineparse(tmp, ",", "", column++))) { - tmp = NULL; - - if (*str == '\0') continue; - - switch(column) { - case 0: break; /* GEOTAG2 */ - case 1: jtr_parse_time(str, &tm, µs); break; - case 2: valid = *str; break; - case 3: lat = ddmm2degrees(atof(str)); break; - case 4: if (*str == 'S') lat *= -1; break; - case 5: lon = ddmm2degrees(atof(str)); break; - case 6: if (*str == 'W') lon *= -1; break; - case 7: speed = KNOTS_TO_MPS(atof(str)); break; - case 8: course = atof(str); break; - case 9: jtr_parse_date(str, &tm); break; - case 13: mcourse = atof(str); break; - case 14: mdev = atof(str); break; - case 15: mdevdir = *str; break; - case 16: mvar = atof(str); break; - case 17: mvardir = *str; break; - default: - break; - } - } - - if ((lat == 999) || (lon == 999) || (valid != 'A')) continue; - - if (tm.tm_year > 0) time = mkgmtime(&tm); - else time = 0; - - /* check for duplicates as suggested in format description */ - - snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)time); - if (avltree_find(trkpts, buf, NULL)) continue; - - wpt = waypt_new(); - - wpt->latitude = lat; - wpt->longitude = lon; - wpt->creation_time = time; - wpt->microseconds = micros; - if (speed >= 0) WAYPT_SET(wpt, speed, speed); - if (mcourse >= 0) { - course = mcourse; - if (mvar >= 0) { - if (mvardir == 'W') course += mvar; - else if (mvardir == 'E') course -= mvar; - } - if (mdev >= 0) { - if (mdevdir == 'W') course += mdev; - else if (mdevdir == 'E') course -= mdev; - } - } - if (course >= 0) WAYPT_SET(wpt, course, course); - - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - - avltree_insert(trkpts, buf, wpt); - track_add_wpt(trk, wpt); - } + char *str; + int line = 0; + route_head *trk = NULL; + + while ((str = gbfgetstr(fin))) { + waypoint *wpt; + struct tm tm; + char *tmp; + int column = -1; + char valid = 'V'; + double lat, lon; + float speed, course, mcourse, mvar, mdev; + time_t time = 0; + int micros = 0; + char buf[32]; + char mvardir, mdevdir; + + line++; + + str = lrtrim(str); + if (*str == '\0') { + continue; + } + + if (strncmp(str, "GEOTAG2,", 8) != 0) { + fatal(MYNAME ": Unknown or unsupported file (missing \"GEOTAG2\")!\n"); + } + + memset(&tm, 0, sizeof(tm)); + lat = lon = 999; + speed = course = mcourse = mvar = mdev = -1; + mvardir = mdevdir = 0; + + column = -1; + tmp = str; + while ((str = csv_lineparse(tmp, ",", "", column++))) { + tmp = NULL; + + if (*str == '\0') { + continue; + } + + switch (column) { + case 0: + break; /* GEOTAG2 */ + case 1: + jtr_parse_time(str, &tm, µs); + break; + case 2: + valid = *str; + break; + case 3: + lat = ddmm2degrees(atof(str)); + break; + case 4: + if (*str == 'S') { + lat *= -1; + } + break; + case 5: + lon = ddmm2degrees(atof(str)); + break; + case 6: + if (*str == 'W') { + lon *= -1; + } + break; + case 7: + speed = KNOTS_TO_MPS(atof(str)); + break; + case 8: + course = atof(str); + break; + case 9: + jtr_parse_date(str, &tm); + break; + case 13: + mcourse = atof(str); + break; + case 14: + mdev = atof(str); + break; + case 15: + mdevdir = *str; + break; + case 16: + mvar = atof(str); + break; + case 17: + mvardir = *str; + break; + default: + break; + } + } + + if ((lat == 999) || (lon == 999) || (valid != 'A')) { + continue; + } + + if (tm.tm_year > 0) { + time = mkgmtime(&tm); + } else { + time = 0; + } + + /* check for duplicates as suggested in format description */ + + snprintf(buf, sizeof(buf), "%.6f\01%.6f\01%ld", lat, lon, (long)time); + if (avltree_find(trkpts, buf, NULL)) { + continue; + } + + wpt = waypt_new(); + + wpt->latitude = lat; + wpt->longitude = lon; + wpt->creation_time = time; + wpt->microseconds = micros; + if (speed >= 0) { + WAYPT_SET(wpt, speed, speed); + } + if (mcourse >= 0) { + course = mcourse; + if (mvar >= 0) { + if (mvardir == 'W') { + course += mvar; + } else if (mvardir == 'E') { + course -= mvar; + } + } + if (mdev >= 0) { + if (mdevdir == 'W') { + course += mdev; + } else if (mdevdir == 'E') { + course -= mdev; + } + } + } + if (course >= 0) { + WAYPT_SET(wpt, course, course); + } + + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + + avltree_insert(trkpts, buf, wpt); + track_add_wpt(trk, wpt); + } } static void jtr_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void jtr_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void jtr_trkpt_disp_cb(const waypoint *wpt) { - char *str, *tmp; - char stime[10], sdate[7], scourse[6], sspeed[8]; - struct tm tm; - - if (wpt->creation_time > 0) { - tm = *gmtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon += 1; - snprintf(sdate, sizeof(sdate), "%02d%02d%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 100); - snprintf(stime, sizeof(stime), "%02d%02d%02d.%02d", tm.tm_hour, tm.tm_min, tm.tm_sec, wpt->microseconds / 10000); - if (wpt->microseconds / 10000 == 0) stime[6] = 0; - } - else { - stime[0] = 0; - sdate[0] = 0; - } - if (WAYPT_HAS(wpt, speed) && (wpt->speed >= 0)) - snprintf(sspeed, sizeof(sspeed), "%.1f", MPS_TO_KNOTS(wpt->speed)); - else sspeed[0] = 0; - if (WAYPT_HAS(wpt, course) && (wpt->course >= 0)) - snprintf(scourse, sizeof(scourse), "%.1f", wpt->course); - else scourse[0] = 0; - - xasprintf(&str, "GEOTAG2,%s,%c,%09.4f,%c,%010.4f,%c,%s,%s,%s,,E,A", - stime, - time > 0 ? 'A' : 'V', - fabs(degrees2ddmm(wpt->latitude)), - wpt->latitude < 0 ? 'S' : 'N', - fabs(degrees2ddmm(wpt->longitude)), - wpt->longitude < 0 ? 'W' : 'E', - sspeed, - scourse, - sdate); - - xasprintf(&tmp, "%s*%02X", str, nmea_cksum(str)); - xfree(str); - str = tmp; - - xasprintf(&tmp, "%s,,,E,,E*%02X\r", str, nmea_cksum(str)); - xfree(str); - str = tmp; - - gbfputs(str, fout); - xfree(str); + char *str, *tmp; + char stime[10], sdate[7], scourse[6], sspeed[8]; + struct tm tm; + + if (wpt->creation_time > 0) { + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon += 1; + snprintf(sdate, sizeof(sdate), "%02d%02d%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 100); + snprintf(stime, sizeof(stime), "%02d%02d%02d.%02d", tm.tm_hour, tm.tm_min, tm.tm_sec, wpt->microseconds / 10000); + if (wpt->microseconds / 10000 == 0) { + stime[6] = 0; + } + } else { + stime[0] = 0; + sdate[0] = 0; + } + if (WAYPT_HAS(wpt, speed) && (wpt->speed >= 0)) { + snprintf(sspeed, sizeof(sspeed), "%.1f", MPS_TO_KNOTS(wpt->speed)); + } else { + sspeed[0] = 0; + } + if (WAYPT_HAS(wpt, course) && (wpt->course >= 0)) { + snprintf(scourse, sizeof(scourse), "%.1f", wpt->course); + } else { + scourse[0] = 0; + } + + xasprintf(&str, "GEOTAG2,%s,%c,%09.4f,%c,%010.4f,%c,%s,%s,%s,,E,A", + stime, + time > 0 ? 'A' : 'V', + fabs(degrees2ddmm(wpt->latitude)), + wpt->latitude < 0 ? 'S' : 'N', + fabs(degrees2ddmm(wpt->longitude)), + wpt->longitude < 0 ? 'W' : 'E', + sspeed, + scourse, + sdate); + + xasprintf(&tmp, "%s*%02X", str, nmea_cksum(str)); + xfree(str); + str = tmp; + + xasprintf(&tmp, "%s,,,E,,E*%02X\r", str, nmea_cksum(str)); + xfree(str); + str = tmp; + + gbfputs(str, fout); + xfree(str); } static void jtr_write(void) { - track_disp_all(NULL, NULL, jtr_trkpt_disp_cb); + track_disp_all(NULL, NULL, jtr_trkpt_disp_cb); } /**************************************************************************/ ff_vecs_t jtr_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - jtr_rd_init, - jtr_wr_init, - jtr_rd_deinit, - jtr_wr_deinit, - jtr_read, - jtr_write, - NULL, - jtr_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none /* routes */ + }, + jtr_rd_init, + jtr_wr_init, + jtr_rd_deinit, + jtr_wr_deinit, + jtr_read, + jtr_write, + NULL, + jtr_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/kml.c b/gpsbabel/kml.c index 14c0ffa0d..a4095ba0d 100644 --- a/gpsbabel/kml.c +++ b/gpsbabel/kml.c @@ -101,54 +101,78 @@ static const char kmt_power[] = "power"; static arglist_t kml_args[] = { - {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"lines", &opt_export_lines, - "Export linestrings for tracks and routes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"points", &opt_export_points, - "Export placemarks for tracks and routes", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"line_width", &opt_line_width, - "Width of lines, in pixels", - "6", ARGTYPE_INT, ARG_NOMINMAX }, - {"line_color", &opt_line_color, - "Line color, specified in hex AABBGGRR", - "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX }, - {"floating", &opt_floating, - "Altitudes are absolute and not clamped to ground", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"extrude", &opt_extrude, - "Draw extrusion line from trackpoint to ground", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"track", &opt_export_track, - "Write KML track (default = 0)", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"trackdata", &opt_trackdata, - "Include extended data for trackpoints (default = 1)", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"trackdirection", &opt_trackdirection, - "Indicate direction of travel in track icons (default = 0)", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"units", &opt_units, - "Units used when writing comments ('s'tatute, 'm'etric,' 'n'autical, 'a'viation)", - "s", ARGTYPE_STRING, ARG_NOMINMAX }, - {"labels", &opt_labels, - "Display labels on track and routepoints (default = 1)", - "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"max_position_points", &opt_max_position_points, - "Retain at most this number of position points (0 = unlimited)", - "0", ARGTYPE_INT, ARG_NOMINMAX }, - ARG_TERMINATOR + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "lines", &opt_export_lines, + "Export linestrings for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "points", &opt_export_points, + "Export placemarks for tracks and routes", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "line_width", &opt_line_width, + "Width of lines, in pixels", + "6", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "line_color", &opt_line_color, + "Line color, specified in hex AABBGGRR", + "99ffac59", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "floating", &opt_floating, + "Altitudes are absolute and not clamped to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "extrude", &opt_extrude, + "Draw extrusion line from trackpoint to ground", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "track", &opt_export_track, + "Write KML track (default = 0)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "trackdata", &opt_trackdata, + "Include extended data for trackpoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "trackdirection", &opt_trackdirection, + "Indicate direction of travel in track icons (default = 0)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "units", &opt_units, + "Units used when writing comments ('s'tatute, 'm'etric,' 'n'autical, 'a'viation)", + "s", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "labels", &opt_labels, + "Display labels on track and routepoints (default = 1)", + "1", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "max_position_points", &opt_max_position_points, + "Retain at most this number of position points (0 = unlimited)", + "0", ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static struct { - int freshness; - const char *icon; + int freshness; + const char *icon; } kml_tracking_icons[] = { - { 60, ICON_BASE "youarehere-60.png" }, // Red - { 30, ICON_BASE "youarehere-30.png" }, // Yellow - { 0, ICON_BASE "youarehere-0.png" }, // Green + { 60, ICON_BASE "youarehere-60.png" }, // Red + { 30, ICON_BASE "youarehere-30.png" }, // Yellow + { 0, ICON_BASE "youarehere-0.png" }, // Green }; #define ICON_NOSAT ICON_BASE "youarehere-warning.png"; @@ -164,7 +188,7 @@ struct { static void kml_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded KML support because expat was not installed.\n"); } static void @@ -178,171 +202,183 @@ static xg_callback wpt_name, wpt_desc, wpt_coord, wpt_icon, trk_coord, wpt_time; static xg_tag_mapping kml_map[] = { - { wpt_s, cb_start, "/Placemark" }, - { wpt_e, cb_end, "/Placemark" }, - { wpt_name, cb_cdata, "/Placemark/name" }, - { wpt_desc, cb_cdata, "/Placemark/description" }, - { wpt_time, cb_cdata, "/Placemark/TimeStamp/when" }, - // Alias for above used in KML 2.0 - { wpt_time, cb_cdata, "/Placemark/TimeInstant/timePosition" }, - { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, - { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, - { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/GeometryCollection/LineString/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/Polygon/outerBoundaryIs/LinearRing/coordinates" }, - { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, - { NULL, 0, NULL } + { wpt_s, cb_start, "/Placemark" }, + { wpt_e, cb_end, "/Placemark" }, + { wpt_name, cb_cdata, "/Placemark/name" }, + { wpt_desc, cb_cdata, "/Placemark/description" }, + { wpt_time, cb_cdata, "/Placemark/TimeStamp/when" }, + // Alias for above used in KML 2.0 + { wpt_time, cb_cdata, "/Placemark/TimeInstant/timePosition" }, + { wpt_coord, cb_cdata, "/Placemark/Point/coordinates" }, + { wpt_icon, cb_cdata, "/Placemark/Style/Icon/href" }, + { trk_coord, cb_cdata, "/Placemark/MultiGeometry/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/GeometryCollection/LineString/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/Polygon/outerBoundaryIs/LinearRing/coordinates" }, + { trk_coord, cb_cdata, "/Placemark/LineString/coordinates" }, + { NULL, 0, NULL } }; static const char * kml_tags_to_ignore[] = { - "kml", - "Document", - "Folder", - NULL, + "kml", + "Document", + "Folder", + NULL, }; void wpt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); - wpt_tmp_queued = 0; + wpt_tmp = waypt_new(); + wpt_tmp_queued = 0; } void wpt_e(const char *args, const char **unused) { - if (wpt_tmp_queued) { - waypt_add(wpt_tmp); - } - wpt_tmp_queued = 0; + if (wpt_tmp_queued) { + waypt_add(wpt_tmp); + } + wpt_tmp_queued = 0; } void wpt_name(const char *args, const char **unused) { - if (args) wpt_tmp->shortname = xstrdup(args); + if (args) { + wpt_tmp->shortname = xstrdup(args); + } } void wpt_desc(const char *args, const char **unused) { - if (args) { - char *tmp, *c; - - tmp = xstrdup((char *)args); - c = lrtrim(tmp); - if (*c) { - wpt_tmp->description = xstrappend(wpt_tmp->description, c); - } - xfree(tmp); - } + if (args) { + char *tmp, *c; + + tmp = xstrdup((char *)args); + c = lrtrim(tmp); + if (*c) { + wpt_tmp->description = xstrappend(wpt_tmp->description, c); + } + xfree(tmp); + } } void wpt_time(const char *args, const char **unused) { - wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); + wpt_tmp->creation_time = xml_parse_time(args, &wpt_tmp->microseconds); } void wpt_coord(const char *args, const char **attrv) { - int n = 0; - double lat, lon, alt; - // Alt is actually optional. - n = sscanf(args, "%lf,%lf,%lf", &lon, &lat, &alt); - if (n >= 2) { - wpt_tmp->latitude = lat; - wpt_tmp->longitude = lon; - } - if (n == 3) { - wpt_tmp->altitude = alt; - } - wpt_tmp_queued = 1; + int n = 0; + double lat, lon, alt; + // Alt is actually optional. + n = sscanf(args, "%lf,%lf,%lf", &lon, &lat, &alt); + if (n >= 2) { + wpt_tmp->latitude = lat; + wpt_tmp->longitude = lon; + } + if (n == 3) { + wpt_tmp->altitude = alt; + } + wpt_tmp_queued = 1; } void wpt_icon(const char *args, const char **unused) { - if (wpt_tmp) { - wpt_tmp->icon_descr = xstrdup(args); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - } + if (wpt_tmp) { + wpt_tmp->icon_descr = xstrdup(args); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } } void trk_coord(const char *args, const char **attrv) { - int consumed = 0; - double lat, lon, alt; - waypoint *trkpt; - int n = 0; - - route_head *trk_head = route_head_alloc(); - if (wpt_tmp->shortname) { - trk_head->rte_name = xstrdup(wpt_tmp->shortname); - } - track_add_head(trk_head); + int consumed = 0; + double lat, lon, alt; + waypoint *trkpt; + int n = 0; + + route_head *trk_head = route_head_alloc(); + if (wpt_tmp->shortname) { + trk_head->rte_name = xstrdup(wpt_tmp->shortname); + } + track_add_head(trk_head); - while ((n = sscanf(args, "%lf,%lf,%lf %n", &lon, &lat, &alt, &consumed)) > 0) { + while ((n = sscanf(args, "%lf,%lf,%lf %n", &lon, &lat, &alt, &consumed)) > 0) { - trkpt = waypt_new(); - trkpt->latitude = lat; - trkpt->longitude = lon; + trkpt = waypt_new(); + trkpt->latitude = lat; + trkpt->longitude = lon; - // Line malformed or two-arg format without alt . Rescan. - if (2 == n) { - sscanf(args, "%lf,%lf %n", &lon, &lat, &consumed); - } + // Line malformed or two-arg format without alt . Rescan. + if (2 == n) { + sscanf(args, "%lf,%lf %n", &lon, &lat, &consumed); + } - if (3 == n) { - trkpt->altitude = alt; - } + if (3 == n) { + trkpt->altitude = alt; + } - track_add_wpt(trk_head, trkpt); + track_add_wpt(trk_head, trkpt); - args += consumed; - } + args += consumed; + } } static void kml_rd_init(const char *fname) { - xml_init(fname, kml_map, NULL); - xml_ignore_tags(kml_tags_to_ignore); + xml_init(fname, kml_map, NULL); + xml_ignore_tags(kml_tags_to_ignore); } static void kml_read(void) { - xml_read(); + xml_read(); } #endif static void kml_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void kml_wr_init(const char *fname) { - char u = 's'; - waypt_init_bounds(&kml_bounds); - kml_time_min = 0; - kml_time_max = 0; - - if (opt_units) { - u = tolower(opt_units[0]); - } - - switch(u) { - case 's': fmt_setunits(units_statute); break; - case 'm': fmt_setunits(units_metric); break; - case 'n': fmt_setunits(units_nautical); break; - case 'a': fmt_setunits(units_aviation); break; - default: fatal("Units argument '%s' should be 's' for statute units, 'm' for metric, 'n' for nautical or 'a' for aviation.\n", opt_units); break; - } - /* - * Reduce race conditions with network read link. - */ - ofd = gbfopen(fname, "w", MYNAME); + char u = 's'; + waypt_init_bounds(&kml_bounds); + kml_time_min = 0; + kml_time_max = 0; + + if (opt_units) { + u = tolower(opt_units[0]); + } + + switch (u) { + case 's': + fmt_setunits(units_statute); + break; + case 'm': + fmt_setunits(units_metric); + break; + case 'n': + fmt_setunits(units_nautical); + break; + case 'a': + fmt_setunits(units_aviation); + break; + default: + fatal("Units argument '%s' should be 's' for statute units, 'm' for metric, 'n' for nautical or 'a' for aviation.\n", opt_units); + break; + } + /* + * Reduce race conditions with network read link. + */ + ofd = gbfopen(fname, "w", MYNAME); } /* @@ -352,42 +388,42 @@ kml_wr_init(const char *fname) static void kml_wr_position_init(const char *fname) { - posnfilename = fname; - posnfilenametmp = xstrappend(xstrdup(fname), "-"); - realtime_positioning = 1; + posnfilename = fname; + posnfilenametmp = xstrappend(xstrdup(fname), "-"); + realtime_positioning = 1; - /* - * 30% of our output file is whitespace. Since parse time - * matters in this mode, turn the pretty formatting off. - */ - do_indentation = 0; + /* + * 30% of our output file is whitespace. Since parse time + * matters in this mode, turn the pretty formatting off. + */ + do_indentation = 0; - max_position_points = atoi(opt_max_position_points); + max_position_points = atoi(opt_max_position_points); } static void kml_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); - if (posnfilenametmp) { + if (posnfilenametmp) { #if __WIN32__ - MoveFileExA(posnfilenametmp, posnfilename, - MOVEFILE_REPLACE_EXISTING); + MoveFileExA(posnfilenametmp, posnfilename, + MOVEFILE_REPLACE_EXISTING); #endif - rename(posnfilenametmp, posnfilename); - } - ofd = NULL; + rename(posnfilenametmp, posnfilename); + } + ofd = NULL; } static void kml_wr_position_deinit(void) { // kml_wr_deinit(); - if (posnfilenametmp) { - xfree(posnfilenametmp); - posnfilenametmp = NULL; - } + if (posnfilenametmp) { + xfree(posnfilenametmp); + posnfilenametmp = NULL; + } } /* @@ -399,23 +435,27 @@ kml_wr_position_deinit(void) static void kml_write_xml(int indent, const char *fmt, ...) { - va_list args; - int i; - va_start(args, fmt); + va_list args; + int i; + va_start(args, fmt); - if (indent < 0) indent_level--; + if (indent < 0) { + indent_level--; + } - if (fmt[1] != '!' && do_indentation) { - for (i = 0; i < indent_level; i++) { - gbfputs(" ", ofd); - } - } + if (fmt[1] != '!' && do_indentation) { + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + } - gbvfprintf(ofd, fmt, args); + gbvfprintf(ofd, fmt, args); - if (indent > 0) indent_level++; + if (indent > 0) { + indent_level++; + } - va_end(args); + va_end(args); } /* @@ -425,29 +465,35 @@ kml_write_xml(int indent, const char *fmt, ...) static void kml_write_xmle(const char *tag, const char *fmt, ...) { - va_list args; - int i; - va_start(args, fmt); - - if (fmt && *fmt) { - char *tmp_ent = xml_entitize(fmt); - int needs_escaping = 0; - for (i = 0; i < indent_level; i++) { - gbfputs(" ", ofd); - } - if (strspn(tmp_ent, "&'<>\"")) - needs_escaping = 1; - gbfprintf(ofd, "<%s>", tag); - if (needs_escaping) gbfprintf(ofd, ""); - gbfprintf(ofd, "\n", tag); - xfree(tmp_ent); - } + va_list args; + int i; + va_start(args, fmt); + + if (fmt && *fmt) { + char *tmp_ent = xml_entitize(fmt); + int needs_escaping = 0; + for (i = 0; i < indent_level; i++) { + gbfputs(" ", ofd); + } + if (strspn(tmp_ent, "&'<>\"")) { + needs_escaping = 1; + } + gbfprintf(ofd, "<%s>", tag); + if (needs_escaping) { + gbfprintf(ofd, ""); + } + gbfprintf(ofd, "\n", tag); + xfree(tmp_ent); + } } void -kml_output_linestyle(char *color, int width) { +kml_output_linestyle(char *color, int width) +{ // Style settings for line strings kml_write_xml(1, "\n"); kml_write_xml(0, "%s\n", opt_line_color); @@ -458,45 +504,45 @@ kml_output_linestyle(char *color, int width) { #define hovertag(h) h ? 'h' : 'n' static void kml_write_bitmap_style_(const char *style, const char * bitmap, - int highlighted, int force_heading) + int highlighted, int force_heading) { - int is_track = !strncmp(style, "track", 5); - int is_multitrack = !strncmp(style, "multiTrack", 5); - - kml_write_xml(0, "\n", - highlighted ? "Highlighted" : "Normal", style); - kml_write_xml(1, "\n"); + kml_write_xml(-1, "\n"); } /* A wrapper for the above function to emit both a highlighted @@ -504,44 +550,57 @@ static void kml_write_bitmap_style_(const char *style, const char * bitmap, * to magnify slightly on a rollover. */ static void kml_write_bitmap_style(kml_point_type pt_type, const char *bitmap, - const char *customstyle) + const char *customstyle) { - int force_heading = 0; - const char *style; - switch (pt_type) { - case kmlpt_track: style = "track"; break; - case kmlpt_route: style = "route"; break; - case kmlpt_waypoint: style = "waypoint"; break; - case kmlpt_multitrack: style = "multiTrack"; break; - case kmlpt_other: style = customstyle; force_heading = 1; break; - default: fatal("kml_output_point: unknown point type"); break; - } - - kml_write_bitmap_style_(style, bitmap, 0, force_heading); - kml_write_bitmap_style_(style, bitmap, 1, force_heading); - - kml_write_xml(1, "\n", style); - kml_write_xml(1, "\n"); - kml_write_xml(0, "normal\n"); - kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); - kml_write_xml(-1, "\n"); - kml_write_xml(1, "\n"); - kml_write_xml(0, "highlight\n"); - kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); + int force_heading = 0; + const char *style; + switch (pt_type) { + case kmlpt_track: + style = "track"; + break; + case kmlpt_route: + style = "route"; + break; + case kmlpt_waypoint: + style = "waypoint"; + break; + case kmlpt_multitrack: + style = "multiTrack"; + break; + case kmlpt_other: + style = customstyle; + force_heading = 1; + break; + default: + fatal("kml_output_point: unknown point type"); + break; + } + + kml_write_bitmap_style_(style, bitmap, 0, force_heading); + kml_write_bitmap_style_(style, bitmap, 1, force_heading); + + kml_write_xml(1, "\n", style); + kml_write_xml(1, "\n"); + kml_write_xml(0, "normal\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(0)); + kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "highlight\n"); + kml_write_xml(0, "#%s_%c\n",style, hovertag(1)); + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); } static void kml_output_timestamp(const waypoint *waypointp) { - char time_string[64]; - if (waypointp->creation_time) { - xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); - if (time_string[0]) { - kml_write_xml(0, "%s\n", - time_string); - } - } + char time_string[64]; + if (waypointp->creation_time) { + xml_fill_in_time(time_string, waypointp->creation_time, waypointp->microseconds, XML_LONG_TIME); + if (time_string[0]) { + kml_write_xml(0, "%s\n", + time_string); + } + } } /* @@ -550,141 +609,141 @@ static void kml_output_timestamp(const waypoint *waypointp) static void kml_output_trkdescription(const route_head *header, computed_trkdata *td) { - char *max_alt_units; - double max_alt; - char *min_alt_units; - double min_alt; - char *distance_units; - double distance; - - if (!td || !trackdata) { - return; - } - - max_alt = fmt_altitude(td->max_alt, &max_alt_units); - min_alt = fmt_altitude(td->min_alt, &min_alt_units); - distance = fmt_distance(td->distance_meters, &distance_units); - - kml_write_xml(0, "\n"); - - kml_write_xml(1, "\n"); - kml_write_xml(1, "\n"); - - if (header->rte_desc) { - TD("Description %s", header->rte_desc); - } - TD2("Distance %.1f %s", distance, distance_units); - if (td->min_alt != -unknown_alt) { - TD2("Min Alt %.3f %s", min_alt, min_alt_units); - } - if (td->max_alt != unknown_alt) { - TD2("Max Alt %.3f %s", max_alt, max_alt_units); - } - if (td->min_spd) { - char *spd_units; - double spd = fmt_speed(td->min_spd, &spd_units); - TD2("Min Speed %.1f %s", spd, spd_units); - } - if (td->max_spd) { - char *spd_units; - double spd = fmt_speed(td->max_spd, &spd_units); - TD2("Max Speed %.1f %s", spd, spd_units); - } - if (td->max_spd && td->start && td->end) { - char *spd_units; - time_t elapsed = td->end - td->start; - double spd = fmt_speed(td->distance_meters / elapsed, &spd_units); - if (spd > 1.0) { - TD2("Avg Speed %.1f %s", spd, spd_units); - } - } - if (td->avg_hrt) { - TD("Avg Heart Rate %.1f bpm", td->avg_hrt); - } - if (td->min_hrt < td->max_hrt) { - TD("Min Heart Rate %d bpm", td->min_hrt); - } - if (td->max_hrt) { - TD("Max Heart Rate %d bpm", td->max_hrt); - } - if (td->avg_cad) { - TD("Avg Cadence %.1f rpm", td->avg_cad); - } - if (td->max_cad) { - TD("Max Cadence %d rpm", td->max_cad); - } - if (td->start && td->end) { - char time_string[64]; - - xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); - TD("Start Time %s ", time_string); - xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); - TD("End Time %s ", time_string); - } - - kml_write_xml(-1, "]]>\n"); - kml_write_xml(-1, "\n"); - - /* We won't always have times. Garmin saved tracks, for example... */ - if (td->start && td->end) { - char time_string[64]; - kml_write_xml(1, "\n"); - xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); - kml_write_xml(0, "%s\n", time_string); - xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); - kml_write_xml(0, "%s\n", time_string); - kml_write_xml(-1, "\n"); - } + char *max_alt_units; + double max_alt; + char *min_alt_units; + double min_alt; + char *distance_units; + double distance; + + if (!td || !trackdata) { + return; + } + + max_alt = fmt_altitude(td->max_alt, &max_alt_units); + min_alt = fmt_altitude(td->min_alt, &min_alt_units); + distance = fmt_distance(td->distance_meters, &distance_units); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(1, "\n"); + + if (header->rte_desc) { + TD("Description %s", header->rte_desc); + } + TD2("Distance %.1f %s", distance, distance_units); + if (td->min_alt != -unknown_alt) { + TD2("Min Alt %.3f %s", min_alt, min_alt_units); + } + if (td->max_alt != unknown_alt) { + TD2("Max Alt %.3f %s", max_alt, max_alt_units); + } + if (td->min_spd) { + char *spd_units; + double spd = fmt_speed(td->min_spd, &spd_units); + TD2("Min Speed %.1f %s", spd, spd_units); + } + if (td->max_spd) { + char *spd_units; + double spd = fmt_speed(td->max_spd, &spd_units); + TD2("Max Speed %.1f %s", spd, spd_units); + } + if (td->max_spd && td->start && td->end) { + char *spd_units; + time_t elapsed = td->end - td->start; + double spd = fmt_speed(td->distance_meters / elapsed, &spd_units); + if (spd > 1.0) { + TD2("Avg Speed %.1f %s", spd, spd_units); + } + } + if (td->avg_hrt) { + TD("Avg Heart Rate %.1f bpm", td->avg_hrt); + } + if (td->min_hrt < td->max_hrt) { + TD("Min Heart Rate %d bpm", td->min_hrt); + } + if (td->max_hrt) { + TD("Max Heart Rate %d bpm", td->max_hrt); + } + if (td->avg_cad) { + TD("Avg Cadence %.1f rpm", td->avg_cad); + } + if (td->max_cad) { + TD("Max Cadence %d rpm", td->max_cad); + } + if (td->start && td->end) { + char time_string[64]; + + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + TD("Start Time %s ", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + TD("End Time %s ", time_string); + } + + kml_write_xml(-1, "]]>\n"); + kml_write_xml(-1, "\n"); + + /* We won't always have times. Garmin saved tracks, for example... */ + if (td->start && td->end) { + char time_string[64]; + kml_write_xml(1, "\n"); + xml_fill_in_time(time_string, td->start, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + xml_fill_in_time(time_string, td->end, 0, XML_LONG_TIME); + kml_write_xml(0, "%s\n", time_string); + kml_write_xml(-1, "\n"); + } } static void kml_output_header(const route_head *header, computed_trkdata*td) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - } - kml_write_xmle("name", header->rte_name); - kml_output_trkdescription(header, td); - - if (export_points && header->rte_waypt_ct > 0) { - // Put the points in a subfolder - kml_write_xml(1, "\n"); - kml_write_xml(0, "Points\n"); - } + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + } + kml_write_xmle("name", header->rte_name); + kml_output_trkdescription(header, td); + + if (export_points && header->rte_waypt_ct > 0) { + // Put the points in a subfolder + kml_write_xml(1, "\n"); + kml_write_xml(0, "Points\n"); + } } static int kml_altitude_known(const waypoint *waypoint) { - if (waypoint->altitude == unknown_alt) { - return 0; - } - // We see way more data that's sourceed at 'zero' than is actually - // precisely at 0 MSL. - if (fabs(waypoint->altitude) < .01) { - return 0; - } - return 1; + if (waypoint->altitude == unknown_alt) { + return 0; + } + // We see way more data that's sourceed at 'zero' than is actually + // precisely at 0 MSL. + if (fabs(waypoint->altitude) < .01) { + return 0; + } + return 1; } static void kml_write_coordinates(const waypoint *waypointp) { - if (kml_altitude_known(waypointp)) { - kml_write_xml(0, "" - COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT - "\n", - waypointp->longitude, - waypointp->latitude, - waypointp->altitude); - } else { - kml_write_xml(0, "" - COORD_FORMAT "," COORD_FORMAT - "\n", - waypointp->longitude, - waypointp->latitude); - } + if (kml_altitude_known(waypointp)) { + kml_write_xml(0, "" + COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT + "\n", + waypointp->longitude, + waypointp->latitude, + waypointp->altitude); + } else { + kml_write_xml(0, "" + COORD_FORMAT "," COORD_FORMAT + "\n", + waypointp->longitude, + waypointp->latitude); + } } /* Rather than a default "top down" view, view from the side to highlight @@ -692,75 +751,86 @@ void kml_write_coordinates(const waypoint *waypointp) */ static void kml_output_lookat(const waypoint *waypointp) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "%f\n", waypointp->longitude); - kml_write_xml(0, "%f\n", waypointp->latitude); - kml_write_xml(0, "66\n"); - kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "66\n"); + kml_write_xml(-1, "\n"); } static void kml_output_positioning(void) { - if (floating) { - kml_write_xml(0, "absolute\n"); - } + if (floating) { + kml_write_xml(0, "absolute\n"); + } - if (extrude) { - kml_write_xml(0, "1\n"); - } + if (extrude) { + kml_write_xml(0, "1\n"); + } } /* Output something interesing when we can for route and trackpoints */ static void kml_output_description(const waypoint *pt) { - char *alt_units; - double alt; - - if (!trackdata) { - return; - } - - alt = fmt_altitude(pt->altitude, &alt_units); - - kml_write_xml(1, "\n"); - - TD("Longitude: %f", pt->longitude); - TD("Latitude: %f", pt->latitude); - if (kml_altitude_known(pt)) TD2("Altitude: %.3f %s", alt, alt_units); - if (pt->heartrate) TD("Heart rate: %d", pt->heartrate); - if (pt->cadence) TD("Cadence: %d", pt->cadence); - /* Which unit is this temp in? C? F? K? */ - if WAYPT_HAS(pt, temperature) TD("Temperature: %.1f", pt->temperature); - if WAYPT_HAS(pt, depth) { - char *depth_units; - double depth = fmt_distance(pt->depth, &depth_units); - TD2("Depth: %.1f %s", depth, depth_units); - } - if WAYPT_HAS(pt, speed) { - char *spd_units; - double spd = fmt_speed(pt->speed, &spd_units); - TD2("Speed: %.1f %s", spd, spd_units); - } - if WAYPT_HAS(pt, course) TD("Heading: %.1f", pt->course); - /* This really shouldn't be here, but as of this writing, - * Earth can't edit/display the TimeStamp. - */ - if (pt->creation_time) { - char time_string[64]; - - xml_fill_in_time(time_string, pt->creation_time, - pt->microseconds, XML_LONG_TIME); - if (time_string[0]) { - TD("Time: %s", time_string); - } - } - - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "]]>\n"); + char *alt_units; + double alt; + + if (!trackdata) { + return; + } + + alt = fmt_altitude(pt->altitude, &alt_units); + + kml_write_xml(1, "\n"); + + TD("Longitude: %f", pt->longitude); + TD("Latitude: %f", pt->latitude); + if (kml_altitude_known(pt)) { + TD2("Altitude: %.3f %s", alt, alt_units); + } + if (pt->heartrate) { + TD("Heart rate: %d", pt->heartrate); + } + if (pt->cadence) { + TD("Cadence: %d", pt->cadence); + } + /* Which unit is this temp in? C? F? K? */ + if WAYPT_HAS(pt, temperature) { + TD("Temperature: %.1f", pt->temperature); + } + if WAYPT_HAS(pt, depth) { + char *depth_units; + double depth = fmt_distance(pt->depth, &depth_units); + TD2("Depth: %.1f %s", depth, depth_units); + } + if WAYPT_HAS(pt, speed) { + char *spd_units; + double spd = fmt_speed(pt->speed, &spd_units); + TD2("Speed: %.1f %s", spd, spd_units); + } + if WAYPT_HAS(pt, course) { + TD("Heading: %.1f", pt->course); + } + /* This really shouldn't be here, but as of this writing, + * Earth can't edit/display the TimeStamp. + */ + if (pt->creation_time) { + char time_string[64]; + + xml_fill_in_time(time_string, pt->creation_time, + pt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + TD("Time: %s", time_string); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "]]>\n"); } -static void kml_recompute_time_bounds(const waypoint *waypointp) { +static void kml_recompute_time_bounds(const waypoint *waypointp) +{ if (waypointp->creation_time && (waypointp->creation_time < kml_time_min)) { kml_time_min = waypointp->creation_time; } @@ -772,69 +842,83 @@ static void kml_recompute_time_bounds(const waypoint *waypointp) { } } -static void kml_add_to_bounds(const waypoint *waypointp) { +static void kml_add_to_bounds(const waypoint *waypointp) +{ waypt_add_to_bounds(&kml_bounds, waypointp); kml_recompute_time_bounds(waypointp); } -static void kml_output_point(const waypoint *waypointp, kml_point_type pt_type) { +static void kml_output_point(const waypoint *waypointp, kml_point_type pt_type) +{ const char *style; switch (pt_type) { - case kmlpt_track: style = "#track"; break; - case kmlpt_route: style = "#route"; break; - default: fatal("kml_output_point: unknown point type"); break; + case kmlpt_track: + style = "#track"; + break; + case kmlpt_route: + style = "#route"; + break; + default: + fatal("kml_output_point: unknown point type"); + break; } switch (pt_type) { - case kmlpt_track: style = "#track"; break; - case kmlpt_route: style = "#route"; break; - default: fatal("kml_output_point: unknown point type"); break; + case kmlpt_track: + style = "#track"; + break; + case kmlpt_route: + style = "#route"; + break; + default: + fatal("kml_output_point: unknown point type"); + break; } if (export_points) { - kml_write_xml(1, "\n"); - if (atoi(opt_labels)) { - kml_write_xmle("name", waypointp->shortname); - } - kml_write_xml(0, "\n"); - kml_output_description(waypointp); - kml_output_lookat(waypointp); - kml_output_timestamp(waypointp); - - - if (opt_deficon) { - kml_write_xml(1, "\n"); - } else { - if (trackdirection && (pt_type == kmlpt_track)) { - char buf[100]; - if (waypointp->speed < 1) - snprintf(buf, sizeof(buf), "%s-none", style); - else - snprintf(buf, sizeof(buf), "%s-%d", style, - (int) (waypointp->course / 22.5 + .5) % 16); - kml_write_xml(0, "%s\n", buf); - } else { - kml_write_xml(0, "%s\n", style); - } - } + kml_write_xml(1, "\n"); + if (atoi(opt_labels)) { + kml_write_xmle("name", waypointp->shortname); + } + kml_write_xml(0, "\n"); + kml_output_description(waypointp); + kml_output_lookat(waypointp); + kml_output_timestamp(waypointp); - kml_write_xml(1, "\n"); - kml_output_positioning(); - if (extrude) { - kml_write_xml(0, "1\n"); - } - kml_write_coordinates(waypointp); - kml_write_xml(-1, "\n"); + if (opt_deficon) { + kml_write_xml(1, "\n"); + } else { + if (trackdirection && (pt_type == kmlpt_track)) { + char buf[100]; + if (waypointp->speed < 1) { + snprintf(buf, sizeof(buf), "%s-none", style); + } else + snprintf(buf, sizeof(buf), "%s-%d", style, + (int)(waypointp->course / 22.5 + .5) % 16); + kml_write_xml(0, "%s\n", buf); + } else { + kml_write_xml(0, "%s\n", style); + } + } + + kml_write_xml(1, "\n"); + kml_output_positioning(); - kml_write_xml(-1, "\n"); + if (extrude) { + kml_write_xml(0, "1\n"); + } + kml_write_coordinates(waypointp); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); } } @@ -855,7 +939,7 @@ static void kml_output_tailer(const route_head *header) if (!first_in_trk && tpt->wpt_flags.new_trkseg) { needs_multigeometry = 1; break; - } + } } kml_write_xml(1, "\n"); kml_write_xml(0, "Path\n"); @@ -866,19 +950,21 @@ static void kml_output_tailer(const route_head *header) if (header->line_color.bbggrr >= 0) kml_write_xml(0, "%02x%06x\n", header->line_color.opacity, header->line_color.bbggrr); - if (header->line_width >= 0) + if (header->line_width >= 0) { kml_write_xml(0, "%d\n",header->line_width); + } kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); } - if (needs_multigeometry) + if (needs_multigeometry) { kml_write_xml(1, "\n"); + } QUEUE_FOR_EACH(&header->waypoint_list, elem, tmp) { waypoint *tpt = (waypoint *) elem; int first_in_trk = tpt->Q.prev == &header->waypoint_list; if (tpt->wpt_flags.new_trkseg) { - if(!first_in_trk) { + if (!first_in_trk) { kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); } @@ -889,17 +975,18 @@ static void kml_output_tailer(const route_head *header) } if (kml_altitude_known(tpt)) { kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "," ALT_FORMAT "\n", - tpt->longitude, tpt->latitude, tpt->altitude); - } else { - kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "\n", - tpt->longitude, - tpt->latitude); - } + tpt->longitude, tpt->latitude, tpt->altitude); + } else { + kml_write_xml(0, COORD_FORMAT "," COORD_FORMAT "\n", + tpt->longitude, + tpt->latitude); + } } kml_write_xml(-1, "\n"); kml_write_xml(-1, "\n"); - if (needs_multigeometry) + if (needs_multigeometry) { kml_write_xml(-1, "\n"); + } kml_write_xml(-1, "\n"); } @@ -914,71 +1001,113 @@ static void kml_output_tailer(const route_head *header) static void kml_gc_make_ballonstyle(void) { - // BalloonStyle for Geocaches. - kml_write_xml(1, "\n"); + // BalloonStyle for Geocaches. + kml_write_xml(1, "\n"); } static char * kml_lookup_gc_icon(const waypoint *waypointp) { - const char *icon; - char *rb; - - /* This could be done so much better in C99 with designated - * initializers... - */ - switch (waypointp->gc_data->type) { - case gt_traditional: icon = "2.png"; break; - case gt_multi: icon = "3.png"; break; - case gt_virtual: icon = "4.png"; break; - case gt_letterbox: icon = "5.png"; break; - case gt_event: icon = "6.png"; break; - case gt_ape: icon = "7.png"; break; - case gt_locationless: icon = "8.png"; break; // No unique icon. - case gt_suprise: icon = "8.png"; break; - case gt_webcam: icon = "11.png"; break; - case gt_cito: icon = "13.png"; break; - case gt_earth: icon = "earthcache.png"; break; - case gt_mega: icon = "453.png"; break; - case gt_wherigo: icon = "1858.png"; break; - default: icon = "8.png"; break; - } - - xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); - return rb; + const char *icon; + char *rb; + + /* This could be done so much better in C99 with designated + * initializers... + */ + switch (waypointp->gc_data->type) { + case gt_traditional: + icon = "2.png"; + break; + case gt_multi: + icon = "3.png"; + break; + case gt_virtual: + icon = "4.png"; + break; + case gt_letterbox: + icon = "5.png"; + break; + case gt_event: + icon = "6.png"; + break; + case gt_ape: + icon = "7.png"; + break; + case gt_locationless: + icon = "8.png"; + break; // No unique icon. + case gt_suprise: + icon = "8.png"; + break; + case gt_webcam: + icon = "11.png"; + break; + case gt_cito: + icon = "13.png"; + break; + case gt_earth: + icon = "earthcache.png"; + break; + case gt_mega: + icon = "453.png"; + break; + case gt_wherigo: + icon = "1858.png"; + break; + default: + icon = "8.png"; + break; + } + + xasprintf(&rb, "http://www.geocaching.com/images/kml/%s", icon); + return rb; } static const char * kml_lookup_gc_container(const waypoint *waypointp) { - const char *cont; - - switch (waypointp->gc_data->container) { - case gc_micro: cont="micro"; break; - case gc_regular: cont="regular"; break; - case gc_large: cont="large"; break; - case gc_small: cont="small"; break; - case gc_virtual: cont="virtual"; break; - case gc_other: cont="other"; break; - default: cont="not_chosen"; break; - } - - return cont; + const char *cont; + + switch (waypointp->gc_data->container) { + case gc_micro: + cont="micro"; + break; + case gc_regular: + cont="regular"; + break; + case gc_large: + cont="large"; + break; + case gc_small: + cont="small"; + break; + case gc_virtual: + cont="virtual"; + break; + case gc_other: + cont="other"; + break; + default: + cont="not_chosen"; + break; + } + + return cont; } // Not thread safe. Return strings are small and it's silly to xasprintf/free @@ -986,90 +1115,90 @@ kml_lookup_gc_container(const waypoint *waypointp) char * kml_gc_mkstar(int rating) { - static char tmp[40]; - if (0 == rating % 10) { - snprintf(tmp, sizeof(tmp), "stars%d", rating / 10); - } else { - snprintf(tmp, sizeof(tmp), "stars%d_%d", rating / 10, rating % 10); - } - - return tmp; + static char tmp[40]; + if (0 == rating % 10) { + snprintf(tmp, sizeof(tmp), "stars%d", rating / 10); + } else { + snprintf(tmp, sizeof(tmp), "stars%d_%d", rating / 10, rating % 10); + } + + return tmp; } static void kml_geocache_pr(const waypoint *waypointp) { - char *p, *is; - - kml_write_xml(1, "\n"); - - kml_write_xml(1, "\n"); - kml_write_xml(0, "\n", waypointp->url_link_text); - kml_write_xml(-1, "\n"); - - // Timestamp - kml_output_timestamp(waypointp); - - kml_write_xml(0, "#geocache\n"); - is = kml_lookup_gc_icon(waypointp); - kml_write_xml(1, "\n"); - - kml_write_xml(1, "\n"); - - if (waypointp->shortname) { - p = xml_entitize(waypointp->shortname); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - if (waypointp->url_link_text) { - p = xml_entitize(waypointp->url_link_text); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - if (waypointp->gc_data->placer) { - p = xml_entitize(waypointp->gc_data->placer); - kml_write_xml(0, "%s\n", p); - xfree(p); - } - - kml_write_xml(0, "%d\n", waypointp->gc_data->placer_id); - - kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->diff)); - kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->terr)); - - kml_write_xml(0, "%s\n", kml_lookup_gc_container(waypointp)); - - // Highlight any issues with the cache, such as temp unavail - // or archived. - kml_write_xml(0, ""); - if (waypointp->gc_data->is_archived == status_true) { - kml_write_xml(0, "<font color=\"red\">This cache has been archived.</font><br/>\n"); - } else if (waypointp->gc_data->is_available == status_false) { - kml_write_xml(0, "<font color=\"red\">This cache is temporarily unavailable.</font><br/>\n"); - } - kml_write_xml(0, "\n"); - - kml_write_xml(0, "%s\n", gs_get_cachetype(waypointp->gc_data->type)); - kml_write_xml(0, "\n", waypointp->gc_data->desc_short.utfstring ? waypointp->gc_data->desc_short.utfstring : ""); - kml_write_xml(0, "\n", waypointp->gc_data->desc_long.utfstring ? waypointp->gc_data->desc_long.utfstring : ""); - - kml_write_xml(-1, "\n"); - - // Location - kml_write_xml(1, "\n"); - kml_write_coordinates(waypointp); - - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); - - xfree(is); + char *p, *is; + + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + kml_write_xml(0, "\n", waypointp->url_link_text); + kml_write_xml(-1, "\n"); + + // Timestamp + kml_output_timestamp(waypointp); + + kml_write_xml(0, "#geocache\n"); + is = kml_lookup_gc_icon(waypointp); + kml_write_xml(1, "\n"); + + kml_write_xml(1, "\n"); + + if (waypointp->shortname) { + p = xml_entitize(waypointp->shortname); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + if (waypointp->url_link_text) { + p = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + if (waypointp->gc_data->placer) { + p = xml_entitize(waypointp->gc_data->placer); + kml_write_xml(0, "%s\n", p); + xfree(p); + } + + kml_write_xml(0, "%d\n", waypointp->gc_data->placer_id); + + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->diff)); + kml_write_xml(0, "%s\n", kml_gc_mkstar(waypointp->gc_data->terr)); + + kml_write_xml(0, "%s\n", kml_lookup_gc_container(waypointp)); + + // Highlight any issues with the cache, such as temp unavail + // or archived. + kml_write_xml(0, ""); + if (waypointp->gc_data->is_archived == status_true) { + kml_write_xml(0, "<font color=\"red\">This cache has been archived.</font><br/>\n"); + } else if (waypointp->gc_data->is_available == status_false) { + kml_write_xml(0, "<font color=\"red\">This cache is temporarily unavailable.</font><br/>\n"); + } + kml_write_xml(0, "\n"); + + kml_write_xml(0, "%s\n", gs_get_cachetype(waypointp->gc_data->type)); + kml_write_xml(0, "\n", waypointp->gc_data->desc_short.utfstring ? waypointp->gc_data->desc_short.utfstring : ""); + kml_write_xml(0, "\n", waypointp->gc_data->desc_long.utfstring ? waypointp->gc_data->desc_long.utfstring : ""); + + kml_write_xml(-1, "\n"); + + // Location + kml_write_xml(1, "\n"); + kml_write_coordinates(waypointp); + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); + + xfree(is); } /* @@ -1078,71 +1207,72 @@ static void kml_geocache_pr(const waypoint *waypointp) static void kml_waypt_pr(const waypoint *waypointp) { - const char *icon; + const char *icon; #if 0 // Experimental - if(realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "%f\n", waypointp->longitude); - kml_write_xml(0, "%f\n", waypointp->latitude); - kml_write_xml(0, "1000\n"); - kml_write_xml(-1, "\n"); - } + if (realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "%f\n", waypointp->longitude); + kml_write_xml(0, "%f\n", waypointp->latitude); + kml_write_xml(0, "1000\n"); + kml_write_xml(-1, "\n"); + } #endif - if (waypointp->gc_data->diff && waypointp->gc_data->terr) { - kml_geocache_pr(waypointp); - return; - } - - kml_write_xml(1, "\n"); - - kml_write_xmle("name", waypointp->shortname); - - // Description - if (waypointp->url && waypointp->url[0]) { - char * odesc = xml_entitize(waypointp->url); - kml_write_xml(0, "\n"); - kml_write_xml(0, "\n"); - if (waypointp->url_link_text && waypointp->url_link_text[0]) { - char *olink = xml_entitize(waypointp->url_link_text); - kml_write_xml(0, "%s]]>", odesc, olink); - xfree(olink); - } else { - gbfputs(odesc, ofd); - } - - kml_write_xml(0, "\n"); - xfree(odesc); - } else { - if (strcmp(waypointp->shortname, waypointp->description)) - kml_write_xmle("description", waypointp->description); - } - - // Timestamp - kml_output_timestamp(waypointp); - - // Icon - but only if it looks like a URL. - icon = opt_deficon ? opt_deficon : waypointp->icon_descr; - if (icon && strstr(icon, "://")) { - kml_write_xml(1, "\n"); - } else { - kml_write_xml(0, "#waypoint\n"); - } - - // Location - kml_write_xml(1, "\n"); - kml_output_positioning(); - kml_write_coordinates(waypointp); - kml_write_xml(-1, "\n"); - - kml_write_xml(-1, "\n"); + if (waypointp->gc_data->diff && waypointp->gc_data->terr) { + kml_geocache_pr(waypointp); + return; + } + + kml_write_xml(1, "\n"); + + kml_write_xmle("name", waypointp->shortname); + + // Description + if (waypointp->url && waypointp->url[0]) { + char * odesc = xml_entitize(waypointp->url); + kml_write_xml(0, "\n"); + kml_write_xml(0, "\n"); + if (waypointp->url_link_text && waypointp->url_link_text[0]) { + char *olink = xml_entitize(waypointp->url_link_text); + kml_write_xml(0, "%s]]>", odesc, olink); + xfree(olink); + } else { + gbfputs(odesc, ofd); + } + + kml_write_xml(0, "\n"); + xfree(odesc); + } else { + if (strcmp(waypointp->shortname, waypointp->description)) { + kml_write_xmle("description", waypointp->description); + } + } + + // Timestamp + kml_output_timestamp(waypointp); + + // Icon - but only if it looks like a URL. + icon = opt_deficon ? opt_deficon : waypointp->icon_descr; + if (icon && strstr(icon, "://")) { + kml_write_xml(1, "\n"); + } else { + kml_write_xml(0, "#waypoint\n"); + } + + // Location + kml_write_xml(1, "\n"); + kml_output_positioning(); + kml_write_coordinates(waypointp); + kml_write_xml(-1, "\n"); + + kml_write_xml(-1, "\n"); } /* @@ -1151,24 +1281,24 @@ static void kml_waypt_pr(const waypoint *waypointp) static void kml_track_hdr(const route_head *header) { - computed_trkdata *td; - track_recompute(header, &td); - if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { - kml_output_header(header, td); - } - xfree(td); + computed_trkdata *td; + track_recompute(header, &td); + if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { + kml_output_header(header, td); + } + xfree(td); } static void kml_track_disp(const waypoint *waypointp) { - kml_output_point(waypointp, kmlpt_track); + kml_output_point(waypointp, kmlpt_track); } static void kml_track_tlr(const route_head *header) { - if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { - kml_output_tailer(header); - } + if (header->rte_waypt_ct > 0 && (export_lines || export_points)) { + kml_output_tailer(header); + } } /* @@ -1198,34 +1328,34 @@ static void kml_mt_simple_array(const route_head *header, char *datap = (char*) elem + offset; - switch(type) { - case sl_char: { - char data = *(char *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_uchar: { - unsigned char data = *(unsigned char *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_int: { - int data = *(int *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_float: { - float data = *(float *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - case sl_double: { - double data = *(double *) datap; - kml_write_xmle("gx:value", fmt_string, data); - } - break; - default: - fatal(MYNAME ": invalid type passed to kml_mt_simple_array.\n"); + switch (type) { + case sl_char: { + char data = *(char *) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_uchar: { + unsigned char data = *(unsigned char *) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_int: { + int data = *(int *) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_float: { + float data = *(float *) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + case sl_double: { + double data = *(double *) datap; + kml_write_xmle("gx:value", fmt_string, data); + } + break; + default: + fatal(MYNAME ": invalid type passed to kml_mt_simple_array.\n"); } } kml_write_xml(-1, "\n"); @@ -1241,8 +1371,9 @@ static int track_has_time(const route_head *header) if (tpt->creation_time) { points_with_time++; - if (points_with_time >= 2) + if (points_with_time >= 2) { return 1; + } } } return 0; @@ -1291,7 +1422,7 @@ static void kml_mt_hdr(const route_head *header) xml_fill_in_time(time_string, tpt->creation_time, tpt->microseconds, XML_LONG_TIME); if (time_string[0]) { - kml_write_xmle("when", time_string); + kml_write_xmle("when", time_string); } } else { kml_write_xml(0, "\n"); @@ -1304,27 +1435,32 @@ static void kml_mt_hdr(const route_head *header) if (kml_altitude_known(tpt)) { kml_write_xmle("gx:coord", COORD_FORMAT " " COORD_FORMAT " " ALT_FORMAT, - tpt->longitude, tpt->latitude,tpt->altitude); + tpt->longitude, tpt->latitude,tpt->altitude); } else { kml_write_xmle("gx:coord", COORD_FORMAT " " COORD_FORMAT, - tpt->longitude, tpt->latitude); + tpt->longitude, tpt->latitude); } // Capture interesting traits to see if we need to do an ExtendedData // section later. - if (tpt->cadence) + if (tpt->cadence) { has_cadence = 1; - if (WAYPT_HAS(tpt, depth)) + } + if (WAYPT_HAS(tpt, depth)) { has_depth = 1; - if (tpt->heartrate) + } + if (tpt->heartrate) { has_heartrate = 1; - if (WAYPT_HAS(tpt, temperature)) + } + if (WAYPT_HAS(tpt, temperature)) { has_temperature = 1; - if (tpt->power) + } + if (tpt->power) { has_power = 1; + } } - if (has_cadence || has_depth || has_heartrate || has_temperature || + if (has_cadence || has_depth || has_heartrate || has_temperature || has_power) { kml_write_xml(1, "\n"); kml_write_xml(1, "\n"); @@ -1368,23 +1504,24 @@ static void kml_mt_tlr(const route_head *header) static void kml_route_hdr(const route_head *header) { - kml_output_header(header, NULL); + kml_output_header(header, NULL); } static void kml_route_disp(const waypoint *waypointp) { - kml_output_point(waypointp, kmlpt_route); + kml_output_point(waypointp, kmlpt_route); } static void kml_route_tlr(const route_head *header) { - kml_output_tailer(header); + kml_output_tailer(header); } // For Earth 5.0, we write a LookAt that encompasses // the bounding box of our entire data set and set the event times // to include all our data. -void kml_write_AbstractView(void) { +void kml_write_AbstractView(void) +{ double bb_size; // Make a pass through all the points to find the bounds. @@ -1428,12 +1565,12 @@ void kml_write_AbstractView(void) { kml_write_xml(-1, "\n"); } - // If our BB spans the antemeridian, flip sign on one. - // This doesn't make our BB optimal, but it at least prevents us from - // zooming to the wrong hemisphere. - if (kml_bounds.min_lon * kml_bounds.max_lon < 0) { - kml_bounds.min_lon = -kml_bounds.max_lon; - } +// If our BB spans the antemeridian, flip sign on one. +// This doesn't make our BB optimal, but it at least prevents us from +// zooming to the wrong hemisphere. + if (kml_bounds.min_lon * kml_bounds.max_lon < 0) { + kml_bounds.min_lon = -kml_bounds.max_lon; + } kml_write_xml(0, "%f\n", (kml_bounds.min_lon + kml_bounds.max_lon) / 2); @@ -1443,7 +1580,7 @@ void kml_write_AbstractView(void) { // It turns out the length of the diagonal of the bounding box gives us a // reasonable guess for setting the camera altitude. bb_size = gcgeodist(kml_bounds.min_lat, kml_bounds.min_lon, - kml_bounds.max_lat, kml_bounds.max_lon); + kml_bounds.max_lat, kml_bounds.max_lon); // Clamp bottom zoom level. Otherwise, a single point zooms to grass. if (bb_size < 1000) { bb_size = 1000; @@ -1455,156 +1592,158 @@ void kml_write_AbstractView(void) { static void kml_mt_array_schema(const char *field_name, const char *display_name, - const char *type) + const char *type) { - kml_write_xml(1, "\n", - field_name, type); - kml_write_xml(0, " %s\n", display_name); - kml_write_xml(-1, "\n"); + kml_write_xml(1, "\n", + field_name, type); + kml_write_xml(0, " %s\n", display_name); + kml_write_xml(-1, "\n"); } void kml_write(void) { - char import_time[100]; - time_t now; - const global_trait* traits = get_traits(); - - // Parse options - export_lines = (0 == strcmp("1", opt_export_lines)); - export_points = (0 == strcmp("1", opt_export_points)); - export_track = (0 == strcmp("1", opt_export_track)); - floating = (!! strcmp("0", opt_floating)); - extrude = (!! strcmp("0", opt_extrude)); - trackdata = (!! strcmp("0", opt_trackdata)); - trackdirection = (!! strcmp("0", opt_trackdirection)); - line_width = atol(opt_line_width); - - kml_write_xml(0, "\n"); - - kml_write_xml(1, kml22_hdr); - - kml_write_xml(1, "\n"); - - now = current_time(); - strftime(import_time, sizeof(import_time), "%c", localtime(&now)); - if (realtime_positioning) - kml_write_xml(0, "GPS position\n"); - else - kml_write_xml(0, "GPS device\n"); - - if (now) { - kml_write_xml(0, "Created %s\n", import_time); - } - - kml_write_AbstractView(); - - // Style settings for bitmaps - if (route_waypt_count()) { - kml_write_bitmap_style(kmlpt_route, ICON_RTE, NULL); - } - - if (track_waypt_count()) { - if (trackdirection) { - int i; - kml_write_bitmap_style(kmlpt_other, ICON_TRK, "track-none"); - for (i = 0; i < 16; i++) { - char buf1[100]; - char buf2[100]; - - sprintf(buf1, "track-%d", i); - sprintf(buf2, ICON_DIR, i); - kml_write_bitmap_style(kmlpt_other, buf2, buf1); - } - } else { - kml_write_bitmap_style(kmlpt_track, ICON_TRK, NULL); - } - if (export_track) - kml_write_bitmap_style(kmlpt_multitrack, ICON_MULTI_TRK, - "track-none"); - } - - kml_write_bitmap_style(kmlpt_waypoint, ICON_WPT, NULL); - - if (track_waypt_count() || route_waypt_count()) { - kml_write_xml(1, "\n"); - } - - if (traits->trait_geocaches) { - kml_gc_make_ballonstyle(); - } - - if(traits->trait_heartrate || - traits->trait_cadence || - traits->trait_power || - traits->trait_temperature || - traits->trait_depth) { - kml_write_xml(1, "\n"); - - if(traits->trait_heartrate) { - kml_mt_array_schema(kmt_heartrate, "Heart Rate", "int"); - } - if(traits->trait_cadence) { - kml_mt_array_schema(kmt_cadence, "Cadence", "int"); - } - if(traits->trait_power) { - kml_mt_array_schema(kmt_power, "Power", "float"); - } - if(traits->trait_temperature) { - kml_mt_array_schema(kmt_temperature, "Temperature", "float"); - } - if(traits->trait_depth) { - kml_mt_array_schema(kmt_depth, "Depth", "float"); - } - kml_write_xml(-1, "\n"); - } - - if (waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Waypoints\n"); - } - - waypt_disp_all(kml_waypt_pr); - - if (!realtime_positioning) { - kml_write_xml(-1, "\n"); - } - } - - // Output trackpoints - if (track_waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Tracks\n"); - } - - if (export_track) - track_disp_all(kml_mt_hdr, kml_mt_tlr, NULL); - - track_disp_all(kml_track_hdr, kml_track_tlr, - kml_track_disp); - - if (!realtime_positioning) { - kml_write_xml(-1, "\n"); - } - } - - // Output routes - if (route_waypt_count()) { - if (!realtime_positioning) { - kml_write_xml(1, "\n"); - kml_write_xml(0, "Routes\n"); - - route_disp_all(kml_route_hdr, - kml_route_tlr, kml_route_disp); - kml_write_xml(-1, "\n"); - } - } + char import_time[100]; + time_t now; + const global_trait* traits = get_traits(); + + // Parse options + export_lines = (0 == strcmp("1", opt_export_lines)); + export_points = (0 == strcmp("1", opt_export_points)); + export_track = (0 == strcmp("1", opt_export_track)); + floating = (!! strcmp("0", opt_floating)); + extrude = (!! strcmp("0", opt_extrude)); + trackdata = (!! strcmp("0", opt_trackdata)); + trackdirection = (!! strcmp("0", opt_trackdirection)); + line_width = atol(opt_line_width); + + kml_write_xml(0, "\n"); + + kml_write_xml(1, kml22_hdr); + + kml_write_xml(1, "\n"); + + now = current_time(); + strftime(import_time, sizeof(import_time), "%c", localtime(&now)); + if (realtime_positioning) { + kml_write_xml(0, "GPS position\n"); + } else { + kml_write_xml(0, "GPS device\n"); + } + + if (now) { + kml_write_xml(0, "Created %s\n", import_time); + } + + kml_write_AbstractView(); - kml_write_xml(-1, "\n"); - kml_write_xml(-1, "\n"); + // Style settings for bitmaps + if (route_waypt_count()) { + kml_write_bitmap_style(kmlpt_route, ICON_RTE, NULL); + } + + if (track_waypt_count()) { + if (trackdirection) { + int i; + kml_write_bitmap_style(kmlpt_other, ICON_TRK, "track-none"); + for (i = 0; i < 16; i++) { + char buf1[100]; + char buf2[100]; + + sprintf(buf1, "track-%d", i); + sprintf(buf2, ICON_DIR, i); + kml_write_bitmap_style(kmlpt_other, buf2, buf1); + } + } else { + kml_write_bitmap_style(kmlpt_track, ICON_TRK, NULL); + } + if (export_track) + kml_write_bitmap_style(kmlpt_multitrack, ICON_MULTI_TRK, + "track-none"); + } + + kml_write_bitmap_style(kmlpt_waypoint, ICON_WPT, NULL); + + if (track_waypt_count() || route_waypt_count()) { + kml_write_xml(1, "\n"); + } + + if (traits->trait_geocaches) { + kml_gc_make_ballonstyle(); + } + + if (traits->trait_heartrate || + traits->trait_cadence || + traits->trait_power || + traits->trait_temperature || + traits->trait_depth) { + kml_write_xml(1, "\n"); + + if (traits->trait_heartrate) { + kml_mt_array_schema(kmt_heartrate, "Heart Rate", "int"); + } + if (traits->trait_cadence) { + kml_mt_array_schema(kmt_cadence, "Cadence", "int"); + } + if (traits->trait_power) { + kml_mt_array_schema(kmt_power, "Power", "float"); + } + if (traits->trait_temperature) { + kml_mt_array_schema(kmt_temperature, "Temperature", "float"); + } + if (traits->trait_depth) { + kml_mt_array_schema(kmt_depth, "Depth", "float"); + } + kml_write_xml(-1, "\n"); + } + + if (waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Waypoints\n"); + } + + waypt_disp_all(kml_waypt_pr); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + } + + // Output trackpoints + if (track_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Tracks\n"); + } + + if (export_track) { + track_disp_all(kml_mt_hdr, kml_mt_tlr, NULL); + } + + track_disp_all(kml_track_hdr, kml_track_tlr, + kml_track_disp); + + if (!realtime_positioning) { + kml_write_xml(-1, "\n"); + } + } + + // Output routes + if (route_waypt_count()) { + if (!realtime_positioning) { + kml_write_xml(1, "\n"); + kml_write_xml(0, "Routes\n"); + + route_disp_all(kml_route_hdr, + kml_route_tlr, kml_route_disp); + kml_write_xml(-1, "\n"); + } + } + + kml_write_xml(-1, "\n"); + kml_write_xml(-1, "\n"); } /* @@ -1614,14 +1753,15 @@ static const char * kml_get_posn_icon(int freshness) { - int i; - int n_stations = sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); - - for (i = 0; i < n_stations ; i++) { - if (freshness >= kml_tracking_icons[i].freshness) - return kml_tracking_icons[i].icon; - } - return ICON_NOSAT; + int i; + int n_stations = sizeof(kml_tracking_icons) / sizeof(kml_tracking_icons[0]); + + for (i = 0; i < n_stations ; i++) { + if (freshness >= kml_tracking_icons[i].freshness) { + return kml_tracking_icons[i].icon; + } + } + return ICON_NOSAT; } @@ -1630,89 +1770,91 @@ static route_head *posn_trk_head = NULL; static void kml_wr_position(waypoint *wpt) { - static time_t last_valid_fix; - - kml_wr_init(posnfilenametmp); - - if (!posn_trk_head) { - posn_trk_head = route_head_alloc(); - track_add_head(posn_trk_head); - } - - if (last_valid_fix == 0) last_valid_fix = current_time(); - - /* We want our waypoint to have a name, but not our trackpoint */ - if (!wpt->shortname) { - if (wpt->fix == fix_none) { - wpt->shortname = xstrdup("ESTIMATED Position"); - } else { - wpt->shortname = xstrdup("Position"); - } - } - - switch (wpt->fix) { - case fix_none: - if (wpt->shortname) { - xfree (wpt->shortname); - } - wpt->shortname = xstrdup("ESTIMATED Position"); - break; - case fix_unknown: - break; - default: - last_valid_fix = wpt->creation_time; - } - - wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); - - - /* In order to avoid clutter while we're sitting still, don't add - track points if we've not moved a minimum distance from the - beginnning of our accumulated track. */ - { - waypoint *newest_posn= (waypoint *) QUEUE_LAST(&posn_trk_head->waypoint_list); - - if(radtometers(gcdist(RAD(wpt->latitude), RAD(wpt->longitude), - RAD(newest_posn->latitude), RAD(newest_posn->longitude))) > 50) { - track_add_wpt(posn_trk_head, waypt_dupe(wpt)); - } else { - /* If we haven't move more than our threshold, pretend - * we didn't move at all to prevent Earth from jittering - * the zoom levels on us. - */ - wpt->latitude = newest_posn->latitude; - wpt->longitude = newest_posn->longitude; - } - } - - waypt_add(wpt); - kml_write(); - waypt_del(wpt); - - /* - * If we are keeping only a recent subset of the trail, trim the - * head here. - */ - while (max_position_points && - (posn_trk_head->rte_waypt_ct >= max_position_points)) { - waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); - track_del_wpt(posn_trk_head, tonuke); - } - - kml_wr_deinit(); + static time_t last_valid_fix; + + kml_wr_init(posnfilenametmp); + + if (!posn_trk_head) { + posn_trk_head = route_head_alloc(); + track_add_head(posn_trk_head); + } + + if (last_valid_fix == 0) { + last_valid_fix = current_time(); + } + + /* We want our waypoint to have a name, but not our trackpoint */ + if (!wpt->shortname) { + if (wpt->fix == fix_none) { + wpt->shortname = xstrdup("ESTIMATED Position"); + } else { + wpt->shortname = xstrdup("Position"); + } + } + + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + case fix_unknown: + break; + default: + last_valid_fix = wpt->creation_time; + } + + wpt->icon_descr = kml_get_posn_icon(wpt->creation_time - last_valid_fix); + + + /* In order to avoid clutter while we're sitting still, don't add + track points if we've not moved a minimum distance from the + beginnning of our accumulated track. */ + { + waypoint *newest_posn= (waypoint *) QUEUE_LAST(&posn_trk_head->waypoint_list); + + if (radtometers(gcdist(RAD(wpt->latitude), RAD(wpt->longitude), + RAD(newest_posn->latitude), RAD(newest_posn->longitude))) > 50) { + track_add_wpt(posn_trk_head, waypt_dupe(wpt)); + } else { + /* If we haven't move more than our threshold, pretend + * we didn't move at all to prevent Earth from jittering + * the zoom levels on us. + */ + wpt->latitude = newest_posn->latitude; + wpt->longitude = newest_posn->longitude; + } + } + + waypt_add(wpt); + kml_write(); + waypt_del(wpt); + + /* + * If we are keeping only a recent subset of the trail, trim the + * head here. + */ + while (max_position_points && + (posn_trk_head->rte_waypt_ct >= max_position_points)) { + waypoint *tonuke = (waypoint *) QUEUE_FIRST(&posn_trk_head->waypoint_list); + track_del_wpt(posn_trk_head, tonuke); + } + + kml_wr_deinit(); } ff_vecs_t kml_vecs = { - ff_type_file, - FF_CAP_RW_ALL, /* Format can do RW_ALL */ - kml_rd_init, - kml_wr_init, - kml_rd_deinit, - kml_wr_deinit, - kml_read, - kml_write, - NULL, - kml_args, - CET_CHARSET_UTF8, 1, /* CET-REVIEW */ - { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_position_deinit } + ff_type_file, + FF_CAP_RW_ALL, /* Format can do RW_ALL */ + kml_rd_init, + kml_wr_init, + kml_rd_deinit, + kml_wr_deinit, + kml_read, + kml_write, + NULL, + kml_args, + CET_CHARSET_UTF8, 1, /* CET-REVIEW */ + { NULL, NULL, NULL, kml_wr_position_init, kml_wr_position, kml_wr_position_deinit } }; diff --git a/gpsbabel/lmx.c b/gpsbabel/lmx.c index 84fd561ea..bef1bfe3f 100644 --- a/gpsbabel/lmx.c +++ b/gpsbabel/lmx.c @@ -38,10 +38,12 @@ static char *binary = NULL; static arglist_t lmx_args[] = { - { "binary", &binary, - "Compact binary representation", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "binary", &binary, + "Compact binary representation", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* @@ -52,190 +54,235 @@ arglist_t lmx_args[] = { static void lmx_wr_init(const char *fname) { - ofd = gbfopen(fname, "w", MYNAME); + ofd = gbfopen(fname, "w", MYNAME); } static void lmx_wr_deinit(void) { - gbfclose(ofd); + gbfclose(ofd); } static char * lmx_stag(int tag) { - switch (tag) { - case 0xC5: return "lmx"; - case 0x46: return "landmarkCollection"; - case 0x47: return "landmark"; - case 0x48: return "name"; - case 0x49: return "description"; - case 0x4A: return "coordinates"; - case 0x4B: return "latitude"; - case 0x4C: return "longitude"; - case 0x4D: return "altitude"; - case 0x4E: return "horizontalAccuracy"; - case 0x4F: return "verticalAccuracy"; - case 0x50: return "timeStamp"; - case 0x51: return "coverageRadius"; - case 0x52: return "category"; - case 0x53: return "id"; - case 0x54: return "addressInfo"; - case 0x55: return "country"; - case 0x56: return "countryCode"; - case 0x57: return "state"; - case 0x58: return "county"; - case 0x59: return "city"; - case 0x5A: return "district"; - case 0x5B: return "postalCode"; - case 0x5C: return "crossing1"; - case 0x5D: return "crossing2"; - case 0x5E: return "street"; - case 0x5F: return "buildingName"; - case 0x60: return "buildingFloor"; - case 0x61: return "buildingZone"; - case 0x62: return "buildingRoom"; - case 0x63: return "extension"; - case 0x64: return "phoneNumber"; - case 0x65: return "mediaLink"; - case 0x66: return "mime"; - case 0x67: return "url"; - default: return 0; - } + switch (tag) { + case 0xC5: + return "lmx"; + case 0x46: + return "landmarkCollection"; + case 0x47: + return "landmark"; + case 0x48: + return "name"; + case 0x49: + return "description"; + case 0x4A: + return "coordinates"; + case 0x4B: + return "latitude"; + case 0x4C: + return "longitude"; + case 0x4D: + return "altitude"; + case 0x4E: + return "horizontalAccuracy"; + case 0x4F: + return "verticalAccuracy"; + case 0x50: + return "timeStamp"; + case 0x51: + return "coverageRadius"; + case 0x52: + return "category"; + case 0x53: + return "id"; + case 0x54: + return "addressInfo"; + case 0x55: + return "country"; + case 0x56: + return "countryCode"; + case 0x57: + return "state"; + case 0x58: + return "county"; + case 0x59: + return "city"; + case 0x5A: + return "district"; + case 0x5B: + return "postalCode"; + case 0x5C: + return "crossing1"; + case 0x5D: + return "crossing2"; + case 0x5E: + return "street"; + case 0x5F: + return "buildingName"; + case 0x60: + return "buildingFloor"; + case 0x61: + return "buildingZone"; + case 0x62: + return "buildingRoom"; + case 0x63: + return "extension"; + case 0x64: + return "phoneNumber"; + case 0x65: + return "mediaLink"; + case 0x66: + return "mime"; + case 0x67: + return "url"; + default: + return 0; + } } static void lmx_indent(int count) { - int i; - for (i=0; i", lmx_stag(tag)); - } + if (binary) { + gbfputc(tag, ofd); + } else { + lmx_indent(indent); + gbfprintf(ofd, "", lmx_stag(tag)); + } } static void lmx_end_tag(int tag, int indent) { - if (binary) - gbfputc(0x01, ofd); - else { - lmx_indent(indent); - gbfprintf(ofd, "\n", lmx_stag(tag)); - } + if (binary) { + gbfputc(0x01, ofd); + } else { + lmx_indent(indent); + gbfprintf(ofd, "\n", lmx_stag(tag)); + } } static void lmx_write_xml(int tag, const char *data, int indent) { - lmx_start_tag(tag, indent); - - if (binary) { - gbfputc(0x03, ofd); // inline string follows - gbfputcstr(data, ofd); - } - else { - char *tmp_ent = xml_entitize(data); - gbfputs(tmp_ent, ofd); - xfree(tmp_ent); - } - - lmx_end_tag(tag, 0); + lmx_start_tag(tag, indent); + + if (binary) { + gbfputc(0x03, ofd); // inline string follows + gbfputcstr(data, ofd); + } else { + char *tmp_ent = xml_entitize(data); + gbfputs(tmp_ent, ofd); + xfree(tmp_ent); + } + + lmx_end_tag(tag, 0); } static void lmx_print(const waypoint *wpt) -{ - const char *oname; - char *odesc; - char tbuf[100]; - - /* - * Desparation time, try very hard to get a good shortname - */ - odesc = wpt->notes; - if (!odesc) { - odesc = wpt->description; - } - if (!odesc) { - odesc = wpt->shortname; - } - - oname = global_opts.synthesize_shortnames ? odesc : wpt->shortname; - - lmx_start_tag(0x47, 2); // landmark - if (!binary) gbfputc('\n', ofd); - if (oname) { - lmx_write_xml(0x48, oname, 3); // name - } - if (wpt->description) { - lmx_write_xml(0x49, wpt->description, 3); // description - } - lmx_start_tag(0x4A, 3); // coordinates - if (!binary) gbfputc('\n', ofd); - - sprintf(tbuf, "%f", wpt->latitude); - lmx_write_xml(0x4B, tbuf, 4); // latitude - - sprintf(tbuf, "%f", wpt->longitude); - lmx_write_xml(0x4C, tbuf, 4); // longitude - - if (wpt->altitude && (wpt->altitude != unknown_alt)) { - sprintf(tbuf, "%f", wpt->altitude); - lmx_write_xml(0x4D, tbuf, 4); // altitude - } - lmx_end_tag(0x4A, 3); // coordinates - - if (wpt->url && wpt->url[0]) { - lmx_start_tag(0x65, 3); // mediaLink - if (!binary) gbfputc('\n', ofd); - if (wpt->url_link_text) - lmx_write_xml(0x48, wpt->url_link_text, 4); // name - lmx_write_xml(0x67, wpt->url, 4); // url - lmx_end_tag(0x65, 3); // mediaLink - } - - lmx_end_tag(0x47, 2); // landmark +{ + const char *oname; + char *odesc; + char tbuf[100]; + + /* + * Desparation time, try very hard to get a good shortname + */ + odesc = wpt->notes; + if (!odesc) { + odesc = wpt->description; + } + if (!odesc) { + odesc = wpt->shortname; + } + + oname = global_opts.synthesize_shortnames ? odesc : wpt->shortname; + + lmx_start_tag(0x47, 2); // landmark + if (!binary) { + gbfputc('\n', ofd); + } + if (oname) { + lmx_write_xml(0x48, oname, 3); // name + } + if (wpt->description) { + lmx_write_xml(0x49, wpt->description, 3); // description + } + lmx_start_tag(0x4A, 3); // coordinates + if (!binary) { + gbfputc('\n', ofd); + } + + sprintf(tbuf, "%f", wpt->latitude); + lmx_write_xml(0x4B, tbuf, 4); // latitude + + sprintf(tbuf, "%f", wpt->longitude); + lmx_write_xml(0x4C, tbuf, 4); // longitude + + if (wpt->altitude && (wpt->altitude != unknown_alt)) { + sprintf(tbuf, "%f", wpt->altitude); + lmx_write_xml(0x4D, tbuf, 4); // altitude + } + lmx_end_tag(0x4A, 3); // coordinates + + if (wpt->url && wpt->url[0]) { + lmx_start_tag(0x65, 3); // mediaLink + if (!binary) { + gbfputc('\n', ofd); + } + if (wpt->url_link_text) { + lmx_write_xml(0x48, wpt->url_link_text, 4); // name + } + lmx_write_xml(0x67, wpt->url, 4); // url + lmx_end_tag(0x65, 3); // mediaLink + } + + lmx_end_tag(0x47, 2); // landmark } static void lmx_write(void) { - if (binary) { - gbfputc(0x03, ofd); // WBXML version 1.3 - gbfputuint16(0x04A4, ofd); // "-//NOKIA//DTD LANDMARKS 1.0//EN" - gbfputc(106, ofd); // Charset=UTF-8 - gbfputc(0x00, ofd); // empty string table - gbfputc(0xC5, ofd); // lmx - gbfputc(0x05, ofd); // xmlns=http://www.nokia.com/schemas/location/landmarks/ - gbfputc(0x85, ofd); // 1/0/ - gbfputc(0x06, ofd); // xmlns:xsi= - gbfputc(0x86, ofd); // http://www.w3.org/2001/XMLSchema-instance - gbfputc(0x07, ofd); // xsi:schemaLocation=http://www.nokia.com/schemas/location/landmarks/ - gbfputc(0x85, ofd); // 1/0/ - gbfputc(0x87, ofd); // whitespace - gbfputc(0x88, ofd); // lmx.xsd - gbfputc(0x01, ofd); // END lmx attributes - } else { - gbfprintf(ofd, "\n"); - gbfprintf(ofd, "\n"); - } - - lmx_start_tag(0x46, 1); // landmarkCollection - if (!binary) gbfputc('\n', ofd); - waypt_disp_all(lmx_print); - lmx_end_tag(0x46, 1); // landmarkCollection - lmx_end_tag(0xC5, 0); // lmx + if (binary) { + gbfputc(0x03, ofd); // WBXML version 1.3 + gbfputuint16(0x04A4, ofd); // "-//NOKIA//DTD LANDMARKS 1.0//EN" + gbfputc(106, ofd); // Charset=UTF-8 + gbfputc(0x00, ofd); // empty string table + gbfputc(0xC5, ofd); // lmx + gbfputc(0x05, ofd); // xmlns=http://www.nokia.com/schemas/location/landmarks/ + gbfputc(0x85, ofd); // 1/0/ + gbfputc(0x06, ofd); // xmlns:xsi= + gbfputc(0x86, ofd); // http://www.w3.org/2001/XMLSchema-instance + gbfputc(0x07, ofd); // xsi:schemaLocation=http://www.nokia.com/schemas/location/landmarks/ + gbfputc(0x85, ofd); // 1/0/ + gbfputc(0x87, ofd); // whitespace + gbfputc(0x88, ofd); // lmx.xsd + gbfputc(0x01, ofd); // END lmx attributes + } else { + gbfprintf(ofd, "\n"); + gbfprintf(ofd, "\n"); + } + + lmx_start_tag(0x46, 1); // landmarkCollection + if (!binary) { + gbfputc('\n', ofd); + } + waypt_disp_all(lmx_print); + lmx_end_tag(0x46, 1); // landmarkCollection + lmx_end_tag(0xC5, 0); // lmx } /* @@ -250,36 +297,36 @@ static xg_callback lmx_lm_link, lmx_lm_linkt; static xg_tag_mapping gl_map[] = { #define LM "/lm:lmx/lm:landmarkCollection/lm:landmark" - { lmx_lm_start, cb_start, LM }, - { lmx_lm_end, cb_end, LM }, - { lmx_lm_name, cb_cdata, LM "/lm:name" }, - { lmx_lm_desc, cb_cdata, LM "/lm:description" }, - { lmx_lm_lat, cb_cdata, LM "/lm:coordinates/lm:latitude" }, - { lmx_lm_lon, cb_cdata, LM "/lm:coordinates/lm:longitude" }, - { lmx_lm_alt, cb_cdata, LM "/lm:coordinates/lm:altitude" }, - { lmx_lm_mlink_s, cb_start, LM "/lm:mediaLink" }, - { lmx_lm_link, cb_cdata, LM "/lm:mediaLink/lm:url" }, - { lmx_lm_linkt, cb_cdata, LM "/lm:mediaLink/lm:name" }, - { lmx_lm_mlink_e, cb_end, LM "/lm:mediaLink" }, - { NULL, 0, NULL} + { lmx_lm_start, cb_start, LM }, + { lmx_lm_end, cb_end, LM }, + { lmx_lm_name, cb_cdata, LM "/lm:name" }, + { lmx_lm_desc, cb_cdata, LM "/lm:description" }, + { lmx_lm_lat, cb_cdata, LM "/lm:coordinates/lm:latitude" }, + { lmx_lm_lon, cb_cdata, LM "/lm:coordinates/lm:longitude" }, + { lmx_lm_alt, cb_cdata, LM "/lm:coordinates/lm:altitude" }, + { lmx_lm_mlink_s, cb_start, LM "/lm:mediaLink" }, + { lmx_lm_link, cb_cdata, LM "/lm:mediaLink/lm:url" }, + { lmx_lm_linkt, cb_cdata, LM "/lm:mediaLink/lm:name" }, + { lmx_lm_mlink_e, cb_end, LM "/lm:mediaLink" }, + { NULL, 0, NULL} }; static void lmx_rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void lmx_read(void) { - xml_read(); + xml_read(); } static void lmx_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } @@ -287,84 +334,84 @@ lmx_rd_deinit(void) static void lmx_lm_start(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } static void lmx_lm_end(const char *args, const char **unused) { - waypt_add(wpt_tmp); + waypt_add(wpt_tmp); } static void lmx_lm_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } static void lmx_lm_lon(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } static void lmx_lm_alt(const char *args, const char **unused) { - wpt_tmp->altitude = atof(args); + wpt_tmp->altitude = atof(args); } static void lmx_lm_name(const char *args, const char **unused) { - wpt_tmp->shortname = xstrdup(args); + wpt_tmp->shortname = xstrdup(args); } -static void +static void lmx_lm_desc(const char *args, const char **unused) { - wpt_tmp->description = xstrdup(args); + wpt_tmp->description = xstrdup(args); } static void lmx_lm_mlink_s(const char *args, const char **unused) { - urllink = urllinkt = NULL; + urllink = urllinkt = NULL; } static void lmx_lm_link(const char *args, const char **unused) { - urllink = xstrdup(args); + urllink = xstrdup(args); } static void lmx_lm_linkt(const char *args, const char **unused) { - urllinkt = xstrdup(args); + urllinkt = xstrdup(args); } static void lmx_lm_mlink_e(const char *args, const char **unused) { - waypt_add_url(wpt_tmp, urllink, urllinkt); + waypt_add_url(wpt_tmp, urllink, urllinkt); } ff_vecs_t lmx_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_none /* routes */ - }, - lmx_rd_init, - lmx_wr_init, - lmx_rd_deinit, - lmx_wr_deinit, - lmx_read, - lmx_write, - NULL, - lmx_args, - CET_CHARSET_UTF8, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none /* routes */ + }, + lmx_rd_init, + lmx_wr_init, + lmx_rd_deinit, + lmx_wr_deinit, + lmx_read, + lmx_write, + NULL, + lmx_args, + CET_CHARSET_UTF8, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/lowranceusr.c b/gpsbabel/lowranceusr.c index 90f2cf362..7f0c57e6c 100644 --- a/gpsbabel/lowranceusr.c +++ b/gpsbabel/lowranceusr.c @@ -37,159 +37,159 @@ #include /* for lat/lon conversion */ typedef struct lowranceusr_icon_mapping { - const int value; - const char *icon; + const int value; + const char *icon; } lowranceusr_icon_mapping_t; #define DEF_ICON 10001 /* Taken from iFinder 1.8 */ const lowranceusr_icon_mapping_t lowranceusr_icon_value_table[] = { - { 10000, "diamond 1" }, - { 10001, "diamond 2" }, - { 10002, "diamond 3" }, - { 10003, "x 1" }, - { 10004, "x 2" }, - { 10005, "x 3" }, - { 10006, "cross" }, - { 10007, "house" }, - { 10008, "car" }, - { 10009, "store" }, - { 10010, "gas station" }, - { 10011, "fork and spoon" }, - { 10012, "telephone" }, - { 10013, "airplane" }, - { 10014, "exit sign" }, - { 10015, "stop sign" }, - { 10016, "exclamation" }, - { 10017, "traffic light" }, - { 10018, "american flag" }, - { 10019, "person" }, - { 10020, "restrooms" }, - { 10021, "tree" }, - { 10022, "mountains" }, - { 10023, "campsite" }, - { 10024, "picnic table" }, - { 10025, "deer" }, - { 10026, "deer tracks" }, - { 10027, "turkey tracks" }, - { 10028, "tree stand" }, - { 10029, "bridge" }, - { 10030, "skull and crossbones" }, - { 10031, "fish" }, - { 10032, "two fish" }, - { 10033, "dive flag" }, - { 10034, "wreck" }, - { 10035, "anchor" }, - { 10036, "boat" }, - { 10037, "boat ramp" }, - { 10038, "flag buoy" }, - { 10039, "dam" }, - { 10040, "swimmer" }, - { 10041, "pier"}, - -/* The following list is from TopoFusion */ - - { 10000, "Waypoint" }, /* diamond 1 */ - { DEF_ICON, "Text Label (No Dot)" }, - { 10018, "Trailhead" }, /* american flag */ - { 10023, "Campground" }, /* campsite */ - { 10022, "Summit" }, /* mountains */ - { DEF_ICON, "Tall Tower" }, - { DEF_ICON, "Short Tower" }, - { 10021, "Forest" }, /* tree */ - { DEF_ICON, "Mine" }, + { 10000, "diamond 1" }, + { 10001, "diamond 2" }, + { 10002, "diamond 3" }, + { 10003, "x 1" }, + { 10004, "x 2" }, + { 10005, "x 3" }, + { 10006, "cross" }, + { 10007, "house" }, + { 10008, "car" }, + { 10009, "store" }, + { 10010, "gas station" }, + { 10011, "fork and spoon" }, + { 10012, "telephone" }, + { 10013, "airplane" }, + { 10014, "exit sign" }, + { 10015, "stop sign" }, + { 10016, "exclamation" }, + { 10017, "traffic light" }, + { 10018, "american flag" }, + { 10019, "person" }, + { 10020, "restrooms" }, + { 10021, "tree" }, + { 10022, "mountains" }, + { 10023, "campsite" }, + { 10024, "picnic table" }, + { 10025, "deer" }, + { 10026, "deer tracks" }, + { 10027, "turkey tracks" }, + { 10028, "tree stand" }, + { 10029, "bridge" }, + { 10030, "skull and crossbones" }, + { 10031, "fish" }, + { 10032, "two fish" }, + { 10033, "dive flag" }, + { 10034, "wreck" }, + { 10035, "anchor" }, + { 10036, "boat" }, + { 10037, "boat ramp" }, + { 10038, "flag buoy" }, + { 10039, "dam" }, + { 10040, "swimmer" }, + { 10041, "pier"}, + + /* The following list is from TopoFusion */ + + { 10000, "Waypoint" }, /* diamond 1 */ + { DEF_ICON, "Text Label (No Dot)" }, + { 10018, "Trailhead" }, /* american flag */ + { 10023, "Campground" }, /* campsite */ + { 10022, "Summit" }, /* mountains */ + { DEF_ICON, "Tall Tower" }, + { DEF_ICON, "Short Tower" }, + { 10021, "Forest" }, /* tree */ + { DEF_ICON, "Mine" }, // { 10038, "Geocache" }, /* flag buoy */ // { 10016, "Geocache Found" }, /* exclamation */ - { DEF_ICON, "Skiing Area" }, - { 10029, "Crossing" }, /* bridge */ - { 10007, "House" }, /* house */ - { 10003, "Dot" }, /* x 1 */ - { 10025, "Hunting Area" }, /* deer */ - { 10031, "Fishing Area" }, /* fish */ - { 10040, "Swimming Area" }, /* swimmer */ - { 10012, "Telephone" }, /* telephone */ - { 10024, "Rest Area" }, /* picnic table */ - { 10021, "Park" }, /* tree */ - { 10007, "Information" }, /* house */ - { 10022, "Scenic Area" }, /* mountains */ - { DEF_ICON, "Bank/Dollar" }, - { 10009, "Hotel" }, /* store */ - { 10011, "Restaurant" }, /* fork and spoon */ - { 10030, "Danger Area" }, /* skull and crossbones */ - { 10035, "Anchor" }, /* anchor */ - { 10002, "City (Large)" }, /* diamond 3 */ - { 10001, "City (Medium)" }, /* diamond 2 */ - { 10000, "City (Small)" }, /* diamond 1 */ - { DEF_ICON, "Drinking Water" }, - { 10008, "Parking Area" }, /* car */ - { 10023, "RV Park" }, /* campsite */ - { 10020, "Rest Room" }, /* restroom */ - { 10019, "Shower" }, /* person */ - { DEF_ICON, "Tunnel" }, - - /* This list comes from 'wifinder' from ifinder H20 Color */ - - { 10062, "Interesting Land Feature" }, - { 10063, "Global Location" }, - { 10064, "Note" }, - { 10065, "Ghost" }, - { 10066, "Letter" }, - { 10067, "Multi-Treasure" }, - { 10068, "Mystery Or Puzzle" }, - { 10069, "Treasure" }, - { 10070, "Webmail" }, - { 10071, "Sun" }, - { 10072, "Musical Note" }, - { 10073, "Camera/Movie Theater" }, - { 10074, "Star" }, - { 10075, "Coffee Mug" }, - { 10076, "Books" }, - { 10077, "Historical Marker" }, - { 10078, "Tools/Repair" }, - { 10079, "Favorite" }, - { 10080, "Arena" }, - { 10081, "Golf Course" }, - { 10082, "Money/Atm" }, - - /* This list comes from Alan Porter , using an iFinder Expedition C */ - - { 10042, "icon42" }, // black box with red X - { 10043, "icon43" }, // small red dot - { 10044, "icon44" }, // 4-wheeler - { 10045, "icon45" }, // hiding hunter - { 10046, "icon46" }, // tree (yellow base) - { 10047, "icon47" }, // windmill - { 10048, "icon48" }, // camera - { 10049, "icon49" }, // tree (something in front of base) - { 10050, "icon50" }, // tree (something hanging from left side) - { 10051, "icon51" }, // 4 dots in rhombus shape - { 10052, "icon52" }, // bare winter tree - { 10053, "icon53" }, // hiding deer head peeking over bushes - { 10054, "icon54" }, // piston? over a pile of salt? - { 10055, "icon55" }, // corn - { 10056, "icon56" }, // turkey - { 10057, "icon57" }, // duck - { 10058, "icon58" }, // hen - { 10059, "icon59" }, // rabbit - { 10060, "icon60" }, // paw print - { 10061, "icon61" }, // 2 red flames? - - /* These are the icons that gpsbabel will use */ - - { 10038, "Geocache" }, // flag buoy - { 10016, "Geocache Found" }, // exclamation - { 10043, "Micro-Cache" }, // small red dot - { 10065, "Virtual cache" }, // ghost - { 10051, "Multi-Cache" }, // 4 dots in rhombus shape - { 10068, "Unknown Cache" }, // ? mark - { 10045, "Locationless (Reverse) Cache" }, // hiding hunter - { 10066, "Post Office" }, // letter - { 10019, "Event Cache" }, // person - { 10070, "Webcam Cache" }, // webcam - { 10042, "Disabled Cache" }, // black box with red X - - { -1, NULL } + { DEF_ICON, "Skiing Area" }, + { 10029, "Crossing" }, /* bridge */ + { 10007, "House" }, /* house */ + { 10003, "Dot" }, /* x 1 */ + { 10025, "Hunting Area" }, /* deer */ + { 10031, "Fishing Area" }, /* fish */ + { 10040, "Swimming Area" }, /* swimmer */ + { 10012, "Telephone" }, /* telephone */ + { 10024, "Rest Area" }, /* picnic table */ + { 10021, "Park" }, /* tree */ + { 10007, "Information" }, /* house */ + { 10022, "Scenic Area" }, /* mountains */ + { DEF_ICON, "Bank/Dollar" }, + { 10009, "Hotel" }, /* store */ + { 10011, "Restaurant" }, /* fork and spoon */ + { 10030, "Danger Area" }, /* skull and crossbones */ + { 10035, "Anchor" }, /* anchor */ + { 10002, "City (Large)" }, /* diamond 3 */ + { 10001, "City (Medium)" }, /* diamond 2 */ + { 10000, "City (Small)" }, /* diamond 1 */ + { DEF_ICON, "Drinking Water" }, + { 10008, "Parking Area" }, /* car */ + { 10023, "RV Park" }, /* campsite */ + { 10020, "Rest Room" }, /* restroom */ + { 10019, "Shower" }, /* person */ + { DEF_ICON, "Tunnel" }, + + /* This list comes from 'wifinder' from ifinder H20 Color */ + + { 10062, "Interesting Land Feature" }, + { 10063, "Global Location" }, + { 10064, "Note" }, + { 10065, "Ghost" }, + { 10066, "Letter" }, + { 10067, "Multi-Treasure" }, + { 10068, "Mystery Or Puzzle" }, + { 10069, "Treasure" }, + { 10070, "Webmail" }, + { 10071, "Sun" }, + { 10072, "Musical Note" }, + { 10073, "Camera/Movie Theater" }, + { 10074, "Star" }, + { 10075, "Coffee Mug" }, + { 10076, "Books" }, + { 10077, "Historical Marker" }, + { 10078, "Tools/Repair" }, + { 10079, "Favorite" }, + { 10080, "Arena" }, + { 10081, "Golf Course" }, + { 10082, "Money/Atm" }, + + /* This list comes from Alan Porter , using an iFinder Expedition C */ + + { 10042, "icon42" }, // black box with red X + { 10043, "icon43" }, // small red dot + { 10044, "icon44" }, // 4-wheeler + { 10045, "icon45" }, // hiding hunter + { 10046, "icon46" }, // tree (yellow base) + { 10047, "icon47" }, // windmill + { 10048, "icon48" }, // camera + { 10049, "icon49" }, // tree (something in front of base) + { 10050, "icon50" }, // tree (something hanging from left side) + { 10051, "icon51" }, // 4 dots in rhombus shape + { 10052, "icon52" }, // bare winter tree + { 10053, "icon53" }, // hiding deer head peeking over bushes + { 10054, "icon54" }, // piston? over a pile of salt? + { 10055, "icon55" }, // corn + { 10056, "icon56" }, // turkey + { 10057, "icon57" }, // duck + { 10058, "icon58" }, // hen + { 10059, "icon59" }, // rabbit + { 10060, "icon60" }, // paw print + { 10061, "icon61" }, // 2 red flames? + + /* These are the icons that gpsbabel will use */ + + { 10038, "Geocache" }, // flag buoy + { 10016, "Geocache Found" }, // exclamation + { 10043, "Micro-Cache" }, // small red dot + { 10065, "Virtual cache" }, // ghost + { 10051, "Multi-Cache" }, // 4 dots in rhombus shape + { 10068, "Unknown Cache" }, // ? mark + { 10045, "Locationless (Reverse) Cache" }, // hiding hunter + { 10066, "Post Office" }, // letter + { 10019, "Event Cache" }, // person + { 10070, "Webcam Cache" }, // webcam + { 10042, "Disabled Cache" }, // black box with red X + + { -1, NULL } }; static gbfile *file_in; @@ -226,200 +226,222 @@ const time_t base_time_secs = 946706400; static int lowranceusr_readstr(char *buf, const int maxlen, gbfile *file) { - int org, len; - - org = len = gbfgetint32(file); - if (len < 0) fatal(MYNAME ": Invalid item length (%d)!\n", len); - else if (len) { - int i; - if (len > maxlen) len = maxlen; - (void) gbfread(buf, 1, len, file); - if (org > maxlen) (void) gbfseek(file, org - maxlen, SEEK_CUR); - // IWay 350C puts 0x01 for the accented o in the street name - // of the Montreal Holiday Inn. - for (i = 0; i < len; i++) { - if (buf[i] == 0x01) - buf[i] = '*'; - } - - } - - return len; + int org, len; + + org = len = gbfgetint32(file); + if (len < 0) { + fatal(MYNAME ": Invalid item length (%d)!\n", len); + } else if (len) { + int i; + if (len > maxlen) { + len = maxlen; + } + (void) gbfread(buf, 1, len, file); + if (org > maxlen) { + (void) gbfseek(file, org - maxlen, SEEK_CUR); + } + // IWay 350C puts 0x01 for the accented o in the street name + // of the Montreal Holiday Inn. + for (i = 0; i < len; i++) { + if (buf[i] == 0x01) { + buf[i] = '*'; + } + } + + } + + return len; } const char * lowranceusr_find_desc_from_icon_number(const int icon) { - const lowranceusr_icon_mapping_t *i; + const lowranceusr_icon_mapping_t *i; - for (i = lowranceusr_icon_value_table; i->icon; i++) { - if (icon == i->value) { - return i->icon; - } - } + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } - return ""; + return ""; } int lowranceusr_find_icon_number_from_desc(const char *desc) { - const lowranceusr_icon_mapping_t *i; - int n; - - if (!desc) { - return DEF_ICON; - } - - /* - * If we were given a numeric icon number as a description - * (i.e. 8255), just return that. - */ - n = atoi(desc); - if (n) { - return n; - } - - - for (i = lowranceusr_icon_value_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - return i->value; - } - } - - return DEF_ICON; + const lowranceusr_icon_mapping_t *i; + int n; + + if (!desc) { + return DEF_ICON; + } + + /* + * If we were given a numeric icon number as a description + * (i.e. 8255), just return that. + */ + n = atoi(desc); + if (n) { + return n; + } + + + for (i = lowranceusr_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + + return DEF_ICON; } static arglist_t lowranceusr_args[] = { - {"ignoreicons", &ignoreicons, "Ignore event marker icons on read", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"writeasicons", &writeasicons, "Treat waypoints as icons on write", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"merge", &merge, "(USR output) Merge into one segmented track", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"break", &seg_break, "(USR input) Break segments into separate tracks", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"wversion", &wversion_arg, "(USR output) Write version", - "2", ARGTYPE_INT, "2", "3" }, - ARG_TERMINATOR + { + "ignoreicons", &ignoreicons, "Ignore event marker icons on read", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "writeasicons", &writeasicons, "Treat waypoints as icons on write", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "merge", &merge, "(USR output) Merge into one segmented track", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "break", &seg_break, "(USR input) Break segments into separate tracks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "wversion", &wversion_arg, "(USR output) Write version", + "2", ARGTYPE_INT, "2", "3" + }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); - waypt_out_count = 0; - writing_version = atoi(wversion_arg); + file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + waypt_out_count = 0; + writing_version = atoi(wversion_arg); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } /** * Latitude and longitude for USR coords are in the lowrance mercator meter * format in WGS84. The below code converts them to degrees. */ -static double -lon_mm_to_deg(double x) { - return x / (DEGREESTORADIANS * SEMIMINOR); +static double +lon_mm_to_deg(double x) +{ + return x / (DEGREESTORADIANS * SEMIMINOR); } -static long -lon_deg_to_mm(double x) { - return (long)(x * SEMIMINOR * DEGREESTORADIANS); +static long +lon_deg_to_mm(double x) +{ + return (long)(x * SEMIMINOR * DEGREESTORADIANS); } -static double -lat_mm_to_deg(double x) { - return (2.0 * atan(exp(x / SEMIMINOR)) - M_PI / 2.0) / DEGREESTORADIANS; +static double +lat_mm_to_deg(double x) +{ + return (2.0 * atan(exp(x / SEMIMINOR)) - M_PI / 2.0) / DEGREESTORADIANS; } static long -lat_deg_to_mm(double x) { - return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2.0) / 2.0))); +lat_deg_to_mm(double x) +{ + return (long)(SEMIMINOR * log(tan((x * DEGREESTORADIANS + M_PI / 2.0) / 2.0))); } static void lowranceusr_parse_waypt(waypoint *wpt_tmp) { - char buff[MAXUSRSTRINGSIZE + 1]; - int text_len; - time_t waypt_time; - short waypt_type; - - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in)); - if (METERS_TO_FEET(wpt_tmp->altitude) <= -10000) { - wpt_tmp->altitude = unknown_alt; - } - - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) { - buff[text_len] = '\0'; - wpt_tmp->shortname = xstrdup(buff); - } - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude, - wpt_tmp->longitude, wpt_tmp->altitude); - - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) { - buff[text_len] = '\0'; - wpt_tmp->description = xstrdup(buff); - } - /* Time is number of seconds since Jan. 1, 2000 */ - waypt_time = gbfgetint32(file_in); - if (waypt_time) - wpt_tmp->creation_time = base_time_secs + waypt_time; - - if (global_opts.debug_level >= 2) - { - printf(MYNAME " parse_waypt: creation time %d\n", - (int)wpt_tmp->creation_time); - printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs); - printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time); - } - - /* Symbol ID */ - wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); - if (!wpt_tmp->icon_descr[0]) { - char nbuf[10]; - snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - wpt_tmp->icon_descr = xstrdup(nbuf); - } - - /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ - waypt_type = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type); - - // Version 3 has a depth field here. - if (reading_version >= 3) { - float depth_feet = gbfgetflt(file_in); - if (abs(depth_feet - 99999.0) > .1) - WAYPT_SET(wpt_tmp, depth, FEET_TO_METERS(depth_feet)); - } + char buff[MAXUSRSTRINGSIZE + 1]; + int text_len; + time_t waypt_time; + short waypt_type; + + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = FEET_TO_METERS(gbfgetint32(file_in)); + if (METERS_TO_FEET(wpt_tmp->altitude) <= -10000) { + wpt_tmp->altitude = unknown_alt; + } + + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->shortname = xstrdup(buff); + } + + if (global_opts.debug_level >= 1) + printf(MYNAME " parse_waypt: Waypt name = %s Lat = %f Lon = %f alt = %f\n",wpt_tmp->shortname, wpt_tmp->latitude, + wpt_tmp->longitude, wpt_tmp->altitude); + + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + wpt_tmp->description = xstrdup(buff); + } + /* Time is number of seconds since Jan. 1, 2000 */ + waypt_time = gbfgetint32(file_in); + if (waypt_time) { + wpt_tmp->creation_time = base_time_secs + waypt_time; + } + + if (global_opts.debug_level >= 2) { + printf(MYNAME " parse_waypt: creation time %d\n", + (int)wpt_tmp->creation_time); + printf(MYNAME " parse_waypt: base_time %d\n", (int)base_time_secs); + printf(MYNAME " parse_waypt: waypt time %d\n", (int)waypt_time); + } + + /* Symbol ID */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + if (!wpt_tmp->icon_descr[0]) { + char nbuf[10]; + snprintf(nbuf, sizeof(nbuf), "%d", le_read32(buff)); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + wpt_tmp->icon_descr = xstrdup(nbuf); + } + + /* Waypoint Type (USER, TEMPORARY, POINT_OF_INTEREST) */ + waypt_type = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_waypt: waypt_type = %d\n",waypt_type); + } + + // Version 3 has a depth field here. + if (reading_version >= 3) { + float depth_feet = gbfgetflt(file_in); + if (abs(depth_feet - 99999.0) > .1) { + WAYPT_SET(wpt_tmp, depth, FEET_TO_METERS(depth_feet)); + } + } } @@ -428,46 +450,44 @@ lowranceusr_parse_waypt(waypoint *wpt_tmp) static void lowranceusr_parse_routes(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_routes, num_legs; - int i,j; - int text_len; - waypoint *wpt_tmp; - - num_routes = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_routes: Num Routes = %d\n", num_routes); - - for (i=0; i < num_routes; i++) - { - rte_head = route_head_alloc(); - route_add_head(rte_head); - rte_head->rte_num = i+1; - - /* route name */ - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - if (text_len) - { - buff[text_len] = '\0'; - rte_head->rte_name = xstrdup(buff); - } - rte_head->rte_desc = '\0'; /* ???????? */ - - /* num Legs */ - num_legs = gbfgetint16(file_in); - - /* route reversed */ - (void) gbfread(&buff[0], 1, 1, file_in); - - /* waypoints */ - for (j=0; j < num_legs; j++) - { - wpt_tmp = waypt_new(); - lowranceusr_parse_waypt(wpt_tmp); - route_add_wpt(rte_head, wpt_tmp); - } - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_routes, num_legs; + int i,j; + int text_len; + waypoint *wpt_tmp; + + num_routes = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_routes: Num Routes = %d\n", num_routes); + } + + for (i=0; i < num_routes; i++) { + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = i+1; + + /* route name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + if (text_len) { + buff[text_len] = '\0'; + rte_head->rte_name = xstrdup(buff); + } + rte_head->rte_desc = '\0'; /* ???????? */ + + /* num Legs */ + num_legs = gbfgetint16(file_in); + + /* route reversed */ + (void) gbfread(&buff[0], 1, 1, file_in); + + /* waypoints */ + for (j=0; j < num_legs; j++) { + wpt_tmp = waypt_new(); + lowranceusr_parse_waypt(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } + } } /* @@ -477,303 +497,312 @@ lowranceusr_parse_routes(void) static void lowranceusr_parse_icons(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_icons; - int i; - - num_icons = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_icons: num Icons = %d\n", num_icons); - - for (i=0; i < num_icons; i++) - { - if (ignoreicons) - { - /* position coord lat & long */ - (void) gbfread(&buff[0], 4, 2, file_in); - /* symbol */ - (void) gbfread(&buff[0], 4, 1, file_in); - } - else - { - waypoint *wpt_tmp; - wpt_tmp = waypt_new(); - - /* position coord lat & long */ - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->altitude = 0; - snprintf(buff, sizeof(buff), "Icon %d", i+1); - wpt_tmp->shortname = xstrdup(buff); - /* symbol */ - wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); - waypt_add(wpt_tmp); - } - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_icons; + int i; + + num_icons = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_icons: num Icons = %d\n", num_icons); + } + + for (i=0; i < num_icons; i++) { + if (ignoreicons) { + /* position coord lat & long */ + (void) gbfread(&buff[0], 4, 2, file_in); + /* symbol */ + (void) gbfread(&buff[0], 4, 1, file_in); + } else { + waypoint *wpt_tmp; + wpt_tmp = waypt_new(); + + /* position coord lat & long */ + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->altitude = 0; + snprintf(buff, sizeof(buff), "Icon %d", i+1); + wpt_tmp->shortname = xstrdup(buff); + /* symbol */ + wpt_tmp->icon_descr = lowranceusr_find_desc_from_icon_number(gbfgetint32(file_in)); + waypt_add(wpt_tmp); + } + } } static void lowranceusr_parse_trails(void) { - char buff[MAXUSRSTRINGSIZE + 1]; - short int num_trails, num_trail_points, num_section_points; - int i,j, trk_num, itmp; - int text_len; - waypoint *wpt_tmp; - route_head *trk_tmp; - - /* num trails */ - num_trails = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num trails = %d\n", num_trails); - - for (i=trk_num=0; i < num_trails; i++) - { - trk_head = route_head_alloc(); - trk_head->rte_num = ++trk_num; - track_add_head(trk_head); - - /* trail name */ - text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: name text len = %d\n", text_len); - - if (text_len) { - buff[text_len] = '\0'; - trk_head->rte_name = xstrdup(buff); - } - trk_head->rte_desc = '\0'; - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: trail name = %s\n", trk_head->rte_name); - - /* visible */ - (void) gbfread(&buff[0], 1, 1, file_in); - /* num trail points */ - num_trail_points = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num trail points = %d\n", num_trail_points); - - /* max trail size */ - itmp = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: max trail size = %d\n", itmp); - - if (num_trail_points) - { - - while (num_trail_points) - { - /* num section points */ - num_section_points = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: num section points = %d\n", num_section_points); - - for (j=0; j < num_section_points; j++, num_trail_points--) - { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); - wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); - /* continuous */ - (void) gbfread(&buff[0], 1, 1, file_in); - if (!buff[0] && seg_break && j) - { - trk_tmp = route_head_alloc(); - trk_tmp->rte_num = ++trk_num; - trk_tmp->rte_name = xstrdup(trk_head->rte_name); - trk_tmp->rte_desc = '\0'; - track_add_head(trk_tmp); - trk_head = trk_tmp; - } - track_add_wpt(trk_head, wpt_tmp); - - if (global_opts.debug_level >= 1) - printf(MYNAME " parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); - } - } - } - /* remove the trail since it's empty */ - else track_del_head(trk_head); - } + char buff[MAXUSRSTRINGSIZE + 1]; + short int num_trails, num_trail_points, num_section_points; + int i,j, trk_num, itmp; + int text_len; + waypoint *wpt_tmp; + route_head *trk_tmp; + + /* num trails */ + num_trails = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num trails = %d\n", num_trails); + } + + for (i=trk_num=0; i < num_trails; i++) { + trk_head = route_head_alloc(); + trk_head->rte_num = ++trk_num; + track_add_head(trk_head); + + /* trail name */ + text_len = lowranceusr_readstr(&buff[0], MAXUSRSTRINGSIZE, file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: name text len = %d\n", text_len); + } + + if (text_len) { + buff[text_len] = '\0'; + trk_head->rte_name = xstrdup(buff); + } + trk_head->rte_desc = '\0'; + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: trail name = %s\n", trk_head->rte_name); + } + + /* visible */ + (void) gbfread(&buff[0], 1, 1, file_in); + /* num trail points */ + num_trail_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num trail points = %d\n", num_trail_points); + } + + /* max trail size */ + itmp = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: max trail size = %d\n", itmp); + } + + if (num_trail_points) { + + while (num_trail_points) { + /* num section points */ + num_section_points = gbfgetint16(file_in); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: num section points = %d\n", num_section_points); + } + + for (j=0; j < num_section_points; j++, num_trail_points--) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = lat_mm_to_deg(gbfgetint32(file_in)); + wpt_tmp->longitude = lon_mm_to_deg(gbfgetint32(file_in)); + /* continuous */ + (void) gbfread(&buff[0], 1, 1, file_in); + if (!buff[0] && seg_break && j) { + trk_tmp = route_head_alloc(); + trk_tmp->rte_num = ++trk_num; + trk_tmp->rte_name = xstrdup(trk_head->rte_name); + trk_tmp->rte_desc = '\0'; + track_add_head(trk_tmp); + trk_head = trk_tmp; + } + track_add_wpt(trk_head, wpt_tmp); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " parse_trails: Trail pt lat %f lon %f\n", wpt_tmp->latitude, wpt_tmp->longitude); + } + } + } + } + /* remove the trail since it's empty */ + else { + track_del_head(trk_head); + } + } } static void data_read(void) { - short int NumWaypoints, MajorVersion, MinorVersion, object_num; - int i; + short int NumWaypoints, MajorVersion, MinorVersion, object_num; + int i; + + MajorVersion = gbfgetint16(file_in); + reading_version = MajorVersion; + MinorVersion = gbfgetint16(file_in); - MajorVersion = gbfgetint16(file_in); - reading_version = MajorVersion; - MinorVersion = gbfgetint16(file_in); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: Major Version %d Minor Version %d\n", MajorVersion, MinorVersion); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: Major Version %d Minor Version %d\n", MajorVersion, MinorVersion); + } - if (MajorVersion < 2) { - fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n"); - } - if (MajorVersion > 3) { - fatal(MYNAME ": input file version %d is not supported\n", - MajorVersion); - } + if (MajorVersion < 2) { + fatal(MYNAME ": input file is from an old version of the USR file and is not supported\n"); + } + if (MajorVersion > 3) { + fatal(MYNAME ": input file version %d is not supported\n", + MajorVersion); + } - NumWaypoints = gbfgetint16(file_in); + NumWaypoints = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: Num waypoints %d\n", NumWaypoints); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: Num waypoints %d\n", NumWaypoints); + } - for (i = 0; i < NumWaypoints; i++) { - waypoint *wpt_tmp; + for (i = 0; i < NumWaypoints; i++) { + waypoint *wpt_tmp; - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); - /* Object num */ - object_num = gbfgetint16(file_in); - if (global_opts.debug_level >= 1) - printf(MYNAME " data_read: object_num = %d\n", object_num); + /* Object num */ + object_num = gbfgetint16(file_in); + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_read: object_num = %d\n", object_num); + } - /* waypoint */ - lowranceusr_parse_waypt(wpt_tmp); + /* waypoint */ + lowranceusr_parse_waypt(wpt_tmp); - waypt_add(wpt_tmp); - } + waypt_add(wpt_tmp); + } - lowranceusr_parse_routes(); - lowranceusr_parse_icons(); - lowranceusr_parse_trails(); + lowranceusr_parse_routes(); + lowranceusr_parse_icons(); + lowranceusr_parse_trails(); } static void lowranceusr_waypt_disp(const waypoint *wpt) { - int text_len, Lat, Lon, Time, SymbolId; - short int WayptType; - char *name; - char *comment; - int alt = METERS_TO_FEET(wpt->altitude); - - if (wpt->altitude == unknown_alt) { - alt = UNKNOWN_USR_ALTITUDE; - } - - Lat = lat_deg_to_mm(wpt->latitude); - Lon = lon_deg_to_mm(wpt->longitude); - gbfputint32(Lat, file_out); - gbfputint32(Lon, file_out); - gbfputint32(alt, file_out); - - if (writing_version >= 3) { - float depth = WAYPT_HAS(wpt, depth) ? - METERS_TO_FEET(wpt->depth) : -99999.0; - gbfputflt(depth, file_out); - } - - if (global_opts.debug_level >= 1) { - /* print lat/lon/alt on one easily greppable line */ - printf(MYNAME " waypt_disp: Lat = %d Lon = %d Alt = %d\n",Lat, Lon, alt); - } - - /* Try and make sure we have a name */ - if ((! wpt->shortname) || global_opts.synthesize_shortnames) { - if (wpt->description && global_opts.synthesize_shortnames) { - name = mkshort_from_wpt(mkshort_handle, wpt); - } else if (wpt->shortname) { - name = xstrdup(wpt->shortname); - } else if (wpt->description) { - name = xstrdup(wpt->description); - } else { - name = xstrdup(""); - } - } else { - name = xstrdup(wpt->shortname); - } - - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(name, 1, text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " waypt_disp: Waypt name = %s\n",name); - - xfree(name); - - /** - * Comments are now used by the iFinder (Expedition C supports them) - */ - if (wpt->description && strcmp(wpt->description, wpt->shortname) != 0) { - comment = xstrdup(wpt->description); - text_len = strlen(comment); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(comment, 1, text_len, file_out); - xfree(comment); - } else { - text_len = 0; - gbfputint32(text_len, file_out); - } - - if (wpt->creation_time > base_time_secs) { - Time = wpt->creation_time - base_time_secs; - } else { - Time = 0; - } - - if (global_opts.debug_level >= 2) - { - time_t wpt_time = Time; - printf(MYNAME " waypt_disp: base_time : %d\n", (int)base_time_secs); - printf(MYNAME " waypt_disp: creation time : %d\n", (int)wpt->creation_time); - printf(MYNAME " waypt_disp: waypt time : %d\n", (int)wpt_time); - printf(MYNAME " waypt_disp: waypt time (local): %s\n", ctime(&wpt_time)); - } - - gbfputint32(Time, file_out); - - if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { - SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt)); - } else { - SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr); - } - /* If the waypoint is archived or disabled, use a "disabled" icon instead. */ - if ( (wpt->gc_data->is_archived==status_true) || (wpt->gc_data->is_available==status_false) ) { - SymbolId = lowranceusr_find_icon_number_from_desc("Disabled Cache"); - } - - gbfputint32(SymbolId, file_out); - - /* USER waypoint type */ - WayptType = 0; - gbfputint16(WayptType, file_out); + int text_len, Lat, Lon, Time, SymbolId; + short int WayptType; + char *name; + char *comment; + int alt = METERS_TO_FEET(wpt->altitude); + + if (wpt->altitude == unknown_alt) { + alt = UNKNOWN_USR_ALTITUDE; + } + + Lat = lat_deg_to_mm(wpt->latitude); + Lon = lon_deg_to_mm(wpt->longitude); + gbfputint32(Lat, file_out); + gbfputint32(Lon, file_out); + gbfputint32(alt, file_out); + + if (writing_version >= 3) { + float depth = WAYPT_HAS(wpt, depth) ? + METERS_TO_FEET(wpt->depth) : -99999.0; + gbfputflt(depth, file_out); + } + + if (global_opts.debug_level >= 1) { + /* print lat/lon/alt on one easily greppable line */ + printf(MYNAME " waypt_disp: Lat = %d Lon = %d Alt = %d\n",Lat, Lon, alt); + } + + /* Try and make sure we have a name */ + if ((! wpt->shortname) || global_opts.synthesize_shortnames) { + if (wpt->description && global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(mkshort_handle, wpt); + } else if (wpt->shortname) { + name = xstrdup(wpt->shortname); + } else if (wpt->description) { + name = xstrdup(wpt->description); + } else { + name = xstrdup(""); + } + } else { + name = xstrdup(wpt->shortname); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " waypt_disp: Waypt name = %s\n",name); + } + + xfree(name); + + /** + * Comments are now used by the iFinder (Expedition C supports them) + */ + if (wpt->description && strcmp(wpt->description, wpt->shortname) != 0) { + comment = xstrdup(wpt->description); + text_len = strlen(comment); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(comment, 1, text_len, file_out); + xfree(comment); + } else { + text_len = 0; + gbfputint32(text_len, file_out); + } + + if (wpt->creation_time > base_time_secs) { + Time = wpt->creation_time - base_time_secs; + } else { + Time = 0; + } + + if (global_opts.debug_level >= 2) { + time_t wpt_time = Time; + printf(MYNAME " waypt_disp: base_time : %d\n", (int)base_time_secs); + printf(MYNAME " waypt_disp: creation time : %d\n", (int)wpt->creation_time); + printf(MYNAME " waypt_disp: waypt time : %d\n", (int)wpt_time); + printf(MYNAME " waypt_disp: waypt time (local): %s\n", ctime(&wpt_time)); + } + + gbfputint32(Time, file_out); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + SymbolId = lowranceusr_find_icon_number_from_desc(get_cache_icon(wpt)); + } else { + SymbolId = lowranceusr_find_icon_number_from_desc(wpt->icon_descr); + } + /* If the waypoint is archived or disabled, use a "disabled" icon instead. */ + if ((wpt->gc_data->is_archived==status_true) || (wpt->gc_data->is_available==status_false)) { + SymbolId = lowranceusr_find_icon_number_from_desc("Disabled Cache"); + } + + gbfputint32(SymbolId, file_out); + + /* USER waypoint type */ + WayptType = 0; + gbfputint16(WayptType, file_out); } static void lowranceusr_waypt_pr(const waypoint *wpt) { - /* our personal waypoint counter */ - gbfputint16(waypt_out_count, file_out); + /* our personal waypoint counter */ + gbfputint16(waypt_out_count, file_out); - if (global_opts.debug_level >= 1) - printf(MYNAME " waypt_pr: waypoint #%d ",waypt_out_count); + if (global_opts.debug_level >= 1) { + printf(MYNAME " waypt_pr: waypoint #%d ",waypt_out_count); + } - waypt_out_count++; + waypt_out_count++; - lowranceusr_waypt_disp(wpt); + lowranceusr_waypt_disp(wpt); } /* - * In Lowrance parlance, an "Icon" is a waypoint but without any + * In Lowrance parlance, an "Icon" is a waypoint but without any * kind of a name. The header count of icons has already been written - * before we get here, so it's just a matter of spitting out + * before we get here, so it's just a matter of spitting out * 4 bytes lat * 4 bytes long * 4 bytes symbol @@ -781,15 +810,15 @@ lowranceusr_waypt_pr(const waypoint *wpt) static void lowranceusr_write_icon(const waypoint *wpt) { - int latmm = lat_deg_to_mm(wpt->latitude); - int lonmm = lon_deg_to_mm(wpt->longitude); - int icon = wpt->icon_descr ? - lowranceusr_find_icon_number_from_desc(wpt->icon_descr) : - 10003; - - gbfputint32(latmm, file_out); - gbfputint32(lonmm, file_out); - gbfputint32(icon, file_out); + int latmm = lat_deg_to_mm(wpt->latitude); + int lonmm = lon_deg_to_mm(wpt->longitude); + int icon = wpt->icon_descr ? + lowranceusr_find_icon_number_from_desc(wpt->icon_descr) : + 10003; + + gbfputint32(latmm, file_out); + gbfputint32(lonmm, file_out); + gbfputint32(icon, file_out); } /* @@ -806,263 +835,268 @@ lowranceusr_write_icon(const waypoint *wpt) * == Once this is known then the waypoints ought to be * == broken up into sections */ - + static void lowranceusr_track_hdr(const route_head *trk) { - int text_len; - char *name, tmp_name[20]; - short num_trail_points, max_trail_size; - char visible=1; - - ++trail_count; - if (trk->rte_name) { - name = xstrdup(trk->rte_name); - } else if (trk->rte_desc) { - name = xstrdup(trk->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); - name = xstrdup(tmp_name); - } - - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name text len = %d\n", text_len); - gbfputint32(text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name = %s\n", name); - - gbfwrite(name, 1, text_len, file_out); - - num_trail_points = (short) trk->rte_waypt_ct; - max_trail_size = MAX_TRAIL_POINTS; - if (num_trail_points > max_trail_size) - num_trail_points = max_trail_size; - num_section_points = num_trail_points; - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", - num_trail_points, max_trail_size, num_section_points); - - gbfwrite(&visible, 1, 1, file_out); - gbfputint16(num_trail_points, file_out); - gbfputint16(max_trail_size, file_out); - gbfputint16(num_section_points, file_out); - xfree(name); - trail_point_count=1; + int text_len; + char *name, tmp_name[20]; + short num_trail_points, max_trail_size; + char visible=1; + + ++trail_count; + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name text len = %d\n", text_len); + } + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name = %s\n", name); + } + + gbfwrite(name, 1, text_len, file_out); + + num_trail_points = (short) trk->rte_waypt_ct; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) { + num_trail_points = max_trail_size; + } + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " track_hdr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + xfree(name); + trail_point_count=1; } static void lowranceusr_route_hdr(const route_head *rte) { - int text_len; - char *name, tmp_name[20]; - short num_legs; - char route_reversed=0; - - /* route name */ - if (rte->rte_name) { - name = xstrdup(rte->rte_name); - } else if (rte->rte_desc) { - name = xstrdup(rte->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel R%d", ++lowrance_route_count); - name = xstrdup(tmp_name); - } - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - gbfwrite(name, 1, text_len, file_out); - xfree(name); - - /* num legs */ - num_legs = (short) rte->rte_waypt_ct; - gbfputint16(num_legs, file_out); - gbfwrite(&route_reversed, 1, 1, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " route_hdr: route name \"%s\" num_legs = %d\n", - rte->rte_name, num_legs); + int text_len; + char *name, tmp_name[20]; + short num_legs; + char route_reversed=0; + + /* route name */ + if (rte->rte_name) { + name = xstrdup(rte->rte_name); + } else if (rte->rte_desc) { + name = xstrdup(rte->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel R%d", ++lowrance_route_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + gbfwrite(name, 1, text_len, file_out); + xfree(name); + + /* num legs */ + num_legs = (short) rte->rte_waypt_ct; + gbfputint16(num_legs, file_out); + gbfwrite(&route_reversed, 1, 1, file_out); + + if (global_opts.debug_level >= 1) + printf(MYNAME " route_hdr: route name \"%s\" num_legs = %d\n", + rte->rte_name, num_legs); } static void lowranceusr_track_disp(const waypoint *wpt) { - int lat, lon; - - if (++trail_point_count <= MAX_TRAIL_POINTS) - { - lat = lat_deg_to_mm(wpt->latitude); - lon = lon_deg_to_mm(wpt->longitude); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_disp: Trail point #%d lat = %d long = %d\n",trail_point_count, lat, lon); - - gbfputint32(lat, file_out); - gbfputint32(lon, file_out); - gbfwrite(&continuous, 1, 1, file_out); - if (!continuous) - continuous = 1; - } + int lat, lon; + + if (++trail_point_count <= MAX_TRAIL_POINTS) { + lat = lat_deg_to_mm(wpt->latitude); + lon = lon_deg_to_mm(wpt->longitude); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_disp: Trail point #%d lat = %d long = %d\n",trail_point_count, lat, lon); + } + + gbfputint32(lat, file_out); + gbfputint32(lon, file_out); + gbfwrite(&continuous, 1, 1, file_out); + if (!continuous) { + continuous = 1; + } + } } static void lowranceusr_merge_track_hdr(const route_head *trk) { - int text_len; - char *name, tmp_name[20]; - - if (++trail_count == 1) - { - if (trk->rte_name) { - name = xstrdup(trk->rte_name); - } else if (trk->rte_desc) { - name = xstrdup(trk->rte_desc); - } else - { - tmp_name[0]='\0'; - snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); - name = xstrdup(tmp_name); - } - text_len = strlen(name); - if (text_len > MAXUSRSTRINGSIZE) text_len = MAXUSRSTRINGSIZE; - gbfputint32(text_len, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " track_hdr: trail name = %s\n", name); - - gbfwrite(name, 1, text_len, file_out); - } - - trail_point_count += (short) trk->rte_waypt_ct; + int text_len; + char *name, tmp_name[20]; + + if (++trail_count == 1) { + if (trk->rte_name) { + name = xstrdup(trk->rte_name); + } else if (trk->rte_desc) { + name = xstrdup(trk->rte_desc); + } else { + tmp_name[0]='\0'; + snprintf(tmp_name, sizeof(tmp_name), "Babel %d", trail_count); + name = xstrdup(tmp_name); + } + text_len = strlen(name); + if (text_len > MAXUSRSTRINGSIZE) { + text_len = MAXUSRSTRINGSIZE; + } + gbfputint32(text_len, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " track_hdr: trail name = %s\n", name); + } + + gbfwrite(name, 1, text_len, file_out); + } + + trail_point_count += (short) trk->rte_waypt_ct; } static void lowranceusr_merge_track_tlr(const route_head *trk) { - short num_trail_points, max_trail_size; - char visible=1; - - if (trail_count == track_count()) /* last trail */ - { - num_trail_points = trail_point_count; - max_trail_size = MAX_TRAIL_POINTS; - if (num_trail_points > max_trail_size) - num_trail_points = max_trail_size; - num_section_points = num_trail_points; - - if (global_opts.debug_level >= 1) - printf(MYNAME " merge_track_tlr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", - num_trail_points, max_trail_size, num_section_points); - - gbfwrite(&visible, 1, 1, file_out); - gbfputint16(num_trail_points, file_out); - gbfputint16(max_trail_size, file_out); - gbfputint16(num_section_points, file_out); - } + short num_trail_points, max_trail_size; + char visible=1; + + if (trail_count == track_count()) { /* last trail */ + num_trail_points = trail_point_count; + max_trail_size = MAX_TRAIL_POINTS; + if (num_trail_points > max_trail_size) { + num_trail_points = max_trail_size; + } + num_section_points = num_trail_points; + + if (global_opts.debug_level >= 1) + printf(MYNAME " merge_track_tlr: num_trail_points = %d\nmax_trail_size = %d\nnum_section_points = %d\n", + num_trail_points, max_trail_size, num_section_points); + + gbfwrite(&visible, 1, 1, file_out); + gbfputint16(num_trail_points, file_out); + gbfputint16(max_trail_size, file_out); + gbfputint16(num_section_points, file_out); + } } static void lowranceusr_merge_track_hdr_2(const route_head *trk) { - continuous = 0; + continuous = 0; } static void data_write(void) { - short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons; - setshort_length(mkshort_handle, 15); - MajorVersion = writing_version; - MinorVersion = 0; - - NumWaypoints = waypt_count(); - - gbfputint16(MajorVersion, file_out); - gbfputint16(MinorVersion, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num waypoints = %d\n", NumWaypoints); - - if (writeasicons) { - short zero = 0; - gbfputint16(zero, file_out); - } else { - gbfputint16(NumWaypoints, file_out); - waypt_disp_all(lowranceusr_waypt_pr); - } - - /* Route support added 6/21/05 */ - NumRoutes = route_count(); - gbfputint16(NumRoutes, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num routes = %d\n", NumRoutes); - - if (NumRoutes) - { - lowrance_route_count=0; - route_disp_all(lowranceusr_route_hdr, NULL, lowranceusr_waypt_disp); - } - - if (NumWaypoints && writeasicons) { - gbfputint16(NumWaypoints, file_out); - waypt_disp_all(lowranceusr_write_icon); - } else { - NumIcons = 0; - gbfputint16(NumIcons, file_out); - } - - /* Track support added 6/21/05 */ - NumTrails = track_count(); - - if (NumTrails && merge) - { - NumTrails = 1; - gbfputint16(NumTrails, file_out); - trail_point_count = 0; - trail_count = 0; - /* count the number of total track points */ - track_disp_all(lowranceusr_merge_track_hdr, lowranceusr_merge_track_tlr, NULL); - /* write out the new track header */ - trail_point_count = 0; - track_disp_all(lowranceusr_merge_track_hdr_2, NULL, lowranceusr_track_disp); - - } - else - { - - gbfputint16(NumTrails, file_out); - - if (global_opts.debug_level >= 1) - printf(MYNAME " data_write: Num tracks = %d\n", NumTrails); - - if (NumTrails) - { - trail_count=0; - track_disp_all(lowranceusr_track_hdr, NULL, lowranceusr_track_disp); - } - } + short int NumWaypoints, MajorVersion, MinorVersion, NumRoutes, NumTrails, NumIcons; + setshort_length(mkshort_handle, 15); + MajorVersion = writing_version; + MinorVersion = 0; + + NumWaypoints = waypt_count(); + + gbfputint16(MajorVersion, file_out); + gbfputint16(MinorVersion, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num waypoints = %d\n", NumWaypoints); + } + + if (writeasicons) { + short zero = 0; + gbfputint16(zero, file_out); + } else { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_waypt_pr); + } + + /* Route support added 6/21/05 */ + NumRoutes = route_count(); + gbfputint16(NumRoutes, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num routes = %d\n", NumRoutes); + } + + if (NumRoutes) { + lowrance_route_count=0; + route_disp_all(lowranceusr_route_hdr, NULL, lowranceusr_waypt_disp); + } + + if (NumWaypoints && writeasicons) { + gbfputint16(NumWaypoints, file_out); + waypt_disp_all(lowranceusr_write_icon); + } else { + NumIcons = 0; + gbfputint16(NumIcons, file_out); + } + + /* Track support added 6/21/05 */ + NumTrails = track_count(); + + if (NumTrails && merge) { + NumTrails = 1; + gbfputint16(NumTrails, file_out); + trail_point_count = 0; + trail_count = 0; + /* count the number of total track points */ + track_disp_all(lowranceusr_merge_track_hdr, lowranceusr_merge_track_tlr, NULL); + /* write out the new track header */ + trail_point_count = 0; + track_disp_all(lowranceusr_merge_track_hdr_2, NULL, lowranceusr_track_disp); + + } else { + + gbfputint16(NumTrails, file_out); + + if (global_opts.debug_level >= 1) { + printf(MYNAME " data_write: Num tracks = %d\n", NumTrails); + } + + if (NumTrails) { + trail_count=0; + track_disp_all(lowranceusr_track_hdr, NULL, lowranceusr_track_disp); + } + } } ff_vecs_t lowranceusr_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - lowranceusr_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + lowranceusr_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/mag_pdb.c b/gpsbabel/mag_pdb.c index c9ebcca29..0ff03b29a 100644 --- a/gpsbabel/mag_pdb.c +++ b/gpsbabel/mag_pdb.c @@ -1,4 +1,4 @@ -/* +/* Support of Palm/OS files from Map&Guide based products like "PowerRoute" 5+6, "Motorrad Routenplaner" @@ -36,144 +36,143 @@ static pdbfile *file_in; -static arglist_t magpdb_args[] = -{ - ARG_TERMINATOR +static arglist_t magpdb_args[] = { + ARG_TERMINATOR }; static double magpdb_to_degree(const int degx) { - int m, d, x; - double s, res; - - d = degx / 100000; - x = degx % 100000; - m = x / 1000; - x = x % 1000; - s = (double)(x) / 10; - - GPS_Math_DegMinSec_To_Deg(d, m, s, &res); - - return res; + int m, d, x; + double s, res; + + d = degx / 100000; + x = degx % 100000; + m = x / 1000; + x = x % 1000; + s = (double)(x) / 10; + + GPS_Math_DegMinSec_To_Deg(d, m, s, &res); + + return res; } static void magpdb_read_data(const char *data, const size_t data_len) { - route_head *route; - char *cin = (char *)data; - char *cend = cin + data_len; - - route = route_head_alloc(); - route_add_head(route); - - while (cin < cend) - { - char *lend; - int len; - - lend = strchr(cin, '\x0A'); - if (lend == NULL) break; - - len = (lend - cin); - if (len > 0) - { - double distance; - int hour, min; - *lend = '\0'; - - if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) /* This only works with the german release */ - { /* test-data created with other releases are welcome */ - cin += 8; - if (*cin != '\0') - route->rte_name = xstrdup(cin); - } - else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) - { - } - else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) - { - } - else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) - { - } - /* check, if line starts with time and distance */ - else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) - { - char *buff, *comma; - - /* detect time-format settings, 12,0 or 12.0 */ - - comma = strchr(cin, '.'); - buff = strchr(cin, ','); - if (comma == NULL) - comma = buff; - else - if ((buff != NULL) && (buff < comma)) - comma = buff; - if (comma != NULL) - { - char separator = *comma; - - /* now we are looking for a sequence like 0,1 NE (123456,654321) */ - - buff = xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ - - comma = cin; - while ((comma = strchr(comma, separator))) - { - int i, xlat, xlon; - waypoint *wpt; - char *cx; - - comma++; - - if (isdigit(*comma) == 0) continue; - if (isdigit(*(comma - 2)) == 0) continue; - - if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) continue; - if (strchr("NESW", *buff) == NULL) continue; /* north, east, ... */ - - cx = comma - 2; /* go left over delta distance */ - while (isdigit(*cx) != 0) *cx-- = '\0'; - cin = lrtrim(cin); - - for (i = 0; i < 2; i++) /* skip time and distance at start of line */ - { - cin = strchr(cin, ' '); - cin = lrtrim(cin); - } - - wpt = waypt_new(); - - wpt->latitude = magpdb_to_degree(xlat); - wpt->longitude = magpdb_to_degree(xlon); - wpt->description = xstrdup(cin); - - cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ - if (cx != NULL) - { - char *tail = lrtrim(++cx); - if (*tail != '\0') - { - wpt->notes = xstrdup(tail); - } - } - /* generate some waypoints from our route-only format */ - if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) - waypt_add(waypt_dupe(wpt)); - - route_add_wpt(route, wpt); - break; - } - xfree(buff); - } - } - - } - cin = lend + 1; - } + route_head *route; + char *cin = (char *)data; + char *cend = cin + data_len; + + route = route_head_alloc(); + route_add_head(route); + + while (cin < cend) { + char *lend; + int len; + + lend = strchr(cin, '\x0A'); + if (lend == NULL) { + break; + } + + len = (lend - cin); + if (len > 0) { + double distance; + int hour, min; + *lend = '\0'; + + if (case_ignore_strncmp(cin, "Wegname=", 8) == 0) { /* This only works with the german release */ + /* test-data created with other releases are welcome */ + cin += 8; + if (*cin != '\0') { + route->rte_name = xstrdup(cin); + } + } else if (case_ignore_strncmp(cin, "Fahrzeit=", 9) == 0) { + } else if (case_ignore_strncmp(cin, "Kosten=", 7) == 0) { + } else if (case_ignore_strncmp(cin, "Entfernung=", 11) == 0) { + } + /* check, if line starts with time and distance */ + else if (3 == sscanf(cin, "%d:%d %lf", &hour, &min, &distance)) { + char *buff, *comma; + + /* detect time-format settings, 12,0 or 12.0 */ + + comma = strchr(cin, '.'); + buff = strchr(cin, ','); + if (comma == NULL) { + comma = buff; + } else if ((buff != NULL) && (buff < comma)) { + comma = buff; + } + if (comma != NULL) { + char separator = *comma; + + /* now we are looking for a sequence like 0,1 NE (123456,654321) */ + + buff = xmalloc(strlen(cin) + 1); /* safe target space for sscanf( ... */ + + comma = cin; + while ((comma = strchr(comma, separator))) { + int i, xlat, xlon; + waypoint *wpt; + char *cx; + + comma++; + + if (isdigit(*comma) == 0) { + continue; + } + if (isdigit(*(comma - 2)) == 0) { + continue; + } + + if (4 != sscanf(comma, "%d %s (%d,%d)", &i, buff, &xlon, &xlat)) { + continue; + } + if (strchr("NESW", *buff) == NULL) { + continue; /* north, east, ... */ + } + + cx = comma - 2; /* go left over delta distance */ + while (isdigit(*cx) != 0) { + *cx-- = '\0'; + } + cin = lrtrim(cin); + + for (i = 0; i < 2; i++) { /* skip time and distance at start of line */ + cin = strchr(cin, ' '); + cin = lrtrim(cin); + } + + wpt = waypt_new(); + + wpt->latitude = magpdb_to_degree(xlat); + wpt->longitude = magpdb_to_degree(xlon); + wpt->description = xstrdup(cin); + + cx = strchr(comma, ')'); /* find tailing notes after the coordinates */ + if (cx != NULL) { + char *tail = lrtrim(++cx); + if (*tail != '\0') { + wpt->notes = xstrdup(tail); + } + } + /* generate some waypoints from our route-only format */ + if ((*cin != '-') && (case_ignore_strncmp(cin, "bei ", 4) != 0)) { + waypt_add(waypt_dupe(wpt)); + } + + route_add_wpt(route, wpt); + break; + } + xfree(buff); + } + } + + } + cin = lend + 1; + } } /* ============================================================================================ @@ -182,52 +181,50 @@ magpdb_read_data(const char *data, const size_t data_len) static void magpdb_rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void magpdb_rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void magpdb_read(void) { - pdbrec_t *pdb_rec; - - is_fatal((file_in->creator != PROUTE_MAGIC), /* identify the database */ - MYNAME ": Not a Map&Guide pdb file (0x%08x).", file_in->creator); - - is_fatal((file_in->version != 0), /* only version "0" currently seen and tested */ - MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", file_in->version + 5); - - is_fatal((file_in->type != PROUTE_ROUTE), - MYNAME ": Unknown pdb data type (0x%08x).", file_in->type); - - for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) - { - char *data = (char *)pdb_rec->data; - - if (be_read16(data) == 0) - { - int len = be_read16(data + 2); - magpdb_read_data(data + 4, len); - } - } + pdbrec_t *pdb_rec; + + is_fatal((file_in->creator != PROUTE_MAGIC), /* identify the database */ + MYNAME ": Not a Map&Guide pdb file (0x%08x).", file_in->creator); + + is_fatal((file_in->version != 0), /* only version "0" currently seen and tested */ + MYNAME ": This file is from an unsupported version (%d) of Map&Guide and is unsupported.", file_in->version + 5); + + is_fatal((file_in->type != PROUTE_ROUTE), + MYNAME ": Unknown pdb data type (0x%08x).", file_in->type); + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + char *data = (char *)pdb_rec->data; + + if (be_read16(data) == 0) { + int len = be_read16(data + 2); + magpdb_read_data(data + 4, len); + } + } } /* ======================================================================================= */ ff_vecs_t magpdb_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ - magpdb_rd_init, - NULL, - magpdb_rd_deinit, - NULL, - magpdb_read, - NULL, - NULL, - magpdb_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_read }, /* real route + emulated waypoints */ + magpdb_rd_init, + NULL, + magpdb_rd_deinit, + NULL, + magpdb_read, + NULL, + NULL, + magpdb_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/magellan.h b/gpsbabel/magellan.h index 062742634..cc8eecc48 100644 --- a/gpsbabel/magellan.h +++ b/gpsbabel/magellan.h @@ -24,24 +24,24 @@ * (Donations welcome. :-) */ typedef enum { - mm_unknown = 0 , - mm_gps315320, - mm_map410, - mm_map330, - mm_gps310, - mm_meridian, - mm_sportrak + mm_unknown = 0 , + mm_gps315320, + mm_map410, + mm_map330, + mm_gps310, + mm_meridian, + mm_sportrak } meridian_model; typedef struct pid_to_model { - meridian_model model; - int pid; - const char *model_n; + meridian_model model; + int pid; + const char *model_n; } pid_to_model_t; typedef struct icon_mapping { - const char *token; - const char *icon; + const char *token; + const char *icon; } icon_mapping_t; const char * mag_find_descr_from_token(const char *token); diff --git a/gpsbabel/maggeo.c b/gpsbabel/maggeo.c index 68dddb355..402053960 100644 --- a/gpsbabel/maggeo.c +++ b/gpsbabel/maggeo.c @@ -39,146 +39,156 @@ static time_t maggeo_parsedate(char *dmy); static void maggeo_writemsg(const char * const buf) { - unsigned int osum = mag_checksum(buf); - gbfprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum); + unsigned int osum = mag_checksum(buf); + gbfprintf(maggeofile_out, "$%s*%02X\r\n",buf, osum); } static void maggeo_rd_init(const char *fname) { - maggeofile_in = gbfopen(fname, "rb", MYNAME); + maggeofile_in = gbfopen(fname, "rb", MYNAME); } static void maggeo_rd_deinit(void) { - gbfclose(maggeofile_in); + gbfclose(maggeofile_in); } static void maggeo_wr_init(const char *fname) { - if (waypt_count() > 200) { - fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); - } - maggeofile_out = gbfopen(fname, "wb", MYNAME); - desc_handle = mkshort_new_handle(); - setshort_length(desc_handle, 20); - setshort_badchars(desc_handle, "\"$,"); + if (waypt_count() > 200) { + fatal(MYNAME ": eXplorist does not support more than 200 waypoints in one .gs file.\nDecrease the number of waypoints sent.\n"); + } + maggeofile_out = gbfopen(fname, "wb", MYNAME); + desc_handle = mkshort_new_handle(); + setshort_length(desc_handle, 20); + setshort_badchars(desc_handle, "\"$,"); } static void maggeo_wr_deinit(void) { - maggeo_writemsg("PMGNCMD,END"); - mkshort_del_handle(&desc_handle); - gbfclose(maggeofile_out); + maggeo_writemsg("PMGNCMD,END"); + mkshort_del_handle(&desc_handle); + gbfclose(maggeofile_out); } static void maggeo_read(void) { - char *buff; - - while ((buff = gbfgetstr(maggeofile_in))) { - waypoint *wpt_tmp; - geocache_data *gcdata; - char *s = NULL; - int fld; - - buff = lrtrim(buff); - if (*buff == '\0') continue; - if (strncmp(buff, "$PMGNGEO,", 9)) continue; - - buff += 9; /* skip field no. 1 */ - fld = 1; - - wpt_tmp = waypt_new(); - gcdata = waypt_alloc_gc_data(wpt_tmp); - - while ((s = csv_lineparse(buff, ",", "", fld++))) { - buff = NULL; - - s = lrtrim(s); - if (*s == '\0') continue; - - switch(fld) { - case 2: - wpt_tmp->latitude = ddmm2degrees(atof(s)); - break; - case 3: - if (s[0] == 'S') - wpt_tmp->latitude = -wpt_tmp->latitude; - break; - case 4: - wpt_tmp->longitude = ddmm2degrees(atof(s)); - break; - case 5: - if (s[0] == 'W') - wpt_tmp->longitude = -wpt_tmp->longitude; - break; - case 6: - wpt_tmp->altitude = atof(s); - break; - case 7: - if (s[0] == 'F') wpt_tmp->altitude = METERS_TO_FEET(wpt_tmp->altitude); - break; - case 8: - wpt_tmp->shortname = xstrdup(s); - break; - case 9: - wpt_tmp->description = xstrdup(s); - break; - case 10: - gcdata->placer = xstrdup(s); - break; - case 11: - gcdata->hint = xstrdup(s); - break; - case 12: // cache type - gcdata->type = gs_mktype(s); - break; - case 13: - wpt_tmp->creation_time = maggeo_parsedate(s); - break; - case 14: // last found date is ignored. - break; - case 15: - gcdata->diff = 10 * atof(s); - break; - case 16: - gcdata->terr = 10 * atof(s); - break; - } - } - waypt_add(wpt_tmp); - } + char *buff; + + while ((buff = gbfgetstr(maggeofile_in))) { + waypoint *wpt_tmp; + geocache_data *gcdata; + char *s = NULL; + int fld; + + buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + if (strncmp(buff, "$PMGNGEO,", 9)) { + continue; + } + + buff += 9; /* skip field no. 1 */ + fld = 1; + + wpt_tmp = waypt_new(); + gcdata = waypt_alloc_gc_data(wpt_tmp); + + while ((s = csv_lineparse(buff, ",", "", fld++))) { + buff = NULL; + + s = lrtrim(s); + if (*s == '\0') { + continue; + } + + switch (fld) { + case 2: + wpt_tmp->latitude = ddmm2degrees(atof(s)); + break; + case 3: + if (s[0] == 'S') { + wpt_tmp->latitude = -wpt_tmp->latitude; + } + break; + case 4: + wpt_tmp->longitude = ddmm2degrees(atof(s)); + break; + case 5: + if (s[0] == 'W') { + wpt_tmp->longitude = -wpt_tmp->longitude; + } + break; + case 6: + wpt_tmp->altitude = atof(s); + break; + case 7: + if (s[0] == 'F') { + wpt_tmp->altitude = METERS_TO_FEET(wpt_tmp->altitude); + } + break; + case 8: + wpt_tmp->shortname = xstrdup(s); + break; + case 9: + wpt_tmp->description = xstrdup(s); + break; + case 10: + gcdata->placer = xstrdup(s); + break; + case 11: + gcdata->hint = xstrdup(s); + break; + case 12: // cache type + gcdata->type = gs_mktype(s); + break; + case 13: + wpt_tmp->creation_time = maggeo_parsedate(s); + break; + case 14: // last found date is ignored. + break; + case 15: + gcdata->diff = 10 * atof(s); + break; + case 16: + gcdata->terr = 10 * atof(s); + break; + } + } + waypt_add(wpt_tmp); + } } /* * Note: returns allocated buffer that must be freed by caller. */ -static +static char * maggeo_fmtdate(time_t t) { - #define SZ 16 - - struct tm *tm = NULL; - int date; - char *cbuf = xmalloc(SZ); - - cbuf[0] = '\0'; - if (t > 0) { - tm = gmtime(&t); - if ( tm ) { - date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + - tm->tm_year; - snprintf(cbuf, SZ, "%07d", date); - } - } - return cbuf; +#define SZ 16 + + struct tm *tm = NULL; + int date; + char *cbuf = xmalloc(SZ); + + cbuf[0] = '\0'; + if (t > 0) { + tm = gmtime(&t); + if (tm) { + date = tm->tm_mday * 100000 + (1+tm->tm_mon) * 1000 + + tm->tm_year; + snprintf(cbuf, SZ, "%07d", date); + } + } + return cbuf; } /* @@ -189,169 +199,179 @@ maggeo_fmtdate(time_t t) */ static time_t maggeo_parsedate(char *dmy) { - struct tm tm; - char dd[3]; - char mm[3]; + struct tm tm; + char dd[3]; + char mm[3]; - if (strlen(dmy) < 5) return 0; + if (strlen(dmy) < 5) { + return 0; + } - memset(&tm, 0, sizeof(tm)); + memset(&tm, 0, sizeof(tm)); - dd[0] = dmy[0]; - dd[1] = dmy[1]; - dd[2] = 0; + dd[0] = dmy[0]; + dd[1] = dmy[1]; + dd[2] = 0; - mm[0] = dmy[2]; - mm[1] = dmy[3]; - mm[2] = 0; + mm[0] = dmy[2]; + mm[1] = dmy[3]; + mm[2] = 0; - tm.tm_mday = atoi(dd); - tm.tm_mon = atoi(mm) - 1; - tm.tm_year = atoi(dmy + 4); + tm.tm_mday = atoi(dd); + tm.tm_mon = atoi(mm) - 1; + tm.tm_year = atoi(dmy + 4); - return mktime(&tm); + return mktime(&tm); } /* - * Append an optional UTF string to buf, prepending a comma, + * Append an optional UTF string to buf, prepending a comma, * cleansing it of NMEA-isms and decomposing to ASCII as we go. */ static void append(char *buf, const char *str) { - char *cleansed1, *cleansed2; + char *cleansed1, *cleansed2; - strcat(buf, ","); + strcat(buf, ","); - if (!str) { - return; - } + if (!str) { + return; + } - cleansed1 = xstrdup(str); + cleansed1 = xstrdup(str); #if FIRMWARE_DOES_88591 -/* Actually, this function needs needs refactored... */ - cleansed2 = xstrdup(cleansed1); + /* Actually, this function needs needs refactored... */ + cleansed2 = xstrdup(cleansed1); #else - cleansed2 = m330_cleanse(cleansed1); + cleansed2 = m330_cleanse(cleansed1); #endif - strcat(buf, cleansed2); + strcat(buf, cleansed2); - xfree(cleansed1); - xfree(cleansed2); + xfree(cleansed1); + xfree(cleansed2); } static void maggeo_waypt_pr(const waypoint *waypointp) { - char obuf[4096]; - double ilon, ilat; - double lon, lat; - int lon_deg, lat_deg; - char *shortname; - char *cname = NULL; - const char *ctype = NULL; - char *placer = NULL; - char *lfounddate = NULL; - char *placeddate = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - shortname = waypointp->shortname; - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - /* - * For some reason, Magellan used exactly the GPX spellings of - * everything except this one... - */ - if (waypointp->gc_data->type == gt_suprise) { - ctype = "Mystery Cache"; - } else { - ctype = gs_get_cachetype(waypointp->gc_data->type); - } - placeddate = maggeo_fmtdate(waypointp->creation_time); - lfounddate = maggeo_fmtdate(waypointp->gc_data->last_found); - cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->description); - placer = waypointp->gc_data->placer; - - /* - * As of this writing on 05/04, the firmware in the units will - * let you write fields of just about any width, but appears to - * only use the following: - * shortname - 8 chars - * cname - 20 chars (scrolls in some places, not others) - * placer - display limited by width - * hint - 50 chars - * cache type - appears to be parsed by f/w for icon matching. - * - * - */ - snprintf(obuf, sizeof(obuf), - "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude); - append(obuf, shortname); - append(obuf, cname); - append(obuf, placer); - append(obuf, waypointp->gc_data->hint); - append(obuf, ctype); - append(obuf, placeddate); - append(obuf, lfounddate); - - if (waypointp->gc_data->diff/10.0) - sprintf(obuf + strlen(obuf), ",%3.1f", - waypointp->gc_data->diff/10.0); - else - strcat(obuf, ","); - - if (waypointp->gc_data->terr/10.0) - sprintf(obuf + strlen(obuf), ",%3.1f", - waypointp->gc_data->terr/10.0); - else - strcat(obuf, ","); - - if (lfounddate) xfree(lfounddate); - if (placeddate) xfree(placeddate); - if (cname) xfree(cname); - - maggeo_writemsg(obuf); + char obuf[4096]; + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char *shortname; + char *cname = NULL; + const char *ctype = NULL; + char *placer = NULL; + char *lfounddate = NULL; + char *placeddate = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + shortname = waypointp->shortname; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + /* + * For some reason, Magellan used exactly the GPX spellings of + * everything except this one... + */ + if (waypointp->gc_data->type == gt_suprise) { + ctype = "Mystery Cache"; + } else { + ctype = gs_get_cachetype(waypointp->gc_data->type); + } + placeddate = maggeo_fmtdate(waypointp->creation_time); + lfounddate = maggeo_fmtdate(waypointp->gc_data->last_found); + cname = mkshort(desc_handle, waypointp->notes ? waypointp->notes : waypointp->description); + placer = waypointp->gc_data->placer; + + /* + * As of this writing on 05/04, the firmware in the units will + * let you write fields of just about any width, but appears to + * only use the following: + * shortname - 8 chars + * cname - 20 chars (scrolls in some places, not others) + * placer - display limited by width + * hint - 50 chars + * cache type - appears to be parsed by f/w for icon matching. + * + * + */ + snprintf(obuf, sizeof(obuf), + "PMGNGEO,%4.3f,%c,%08.3f,%c,%04.0f,F", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude); + append(obuf, shortname); + append(obuf, cname); + append(obuf, placer); + append(obuf, waypointp->gc_data->hint); + append(obuf, ctype); + append(obuf, placeddate); + append(obuf, lfounddate); + + if (waypointp->gc_data->diff/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data->diff/10.0); + else { + strcat(obuf, ","); + } + + if (waypointp->gc_data->terr/10.0) + sprintf(obuf + strlen(obuf), ",%3.1f", + waypointp->gc_data->terr/10.0); + else { + strcat(obuf, ","); + } + + if (lfounddate) { + xfree(lfounddate); + } + if (placeddate) { + xfree(placeddate); + } + if (cname) { + xfree(cname); + } + + maggeo_writemsg(obuf); } static void maggeo_write(void) { - waypt_disp_all(maggeo_waypt_pr); + waypt_disp_all(maggeo_waypt_pr); } ff_vecs_t maggeo_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, - maggeo_rd_init, - maggeo_wr_init, - maggeo_rd_deinit, - maggeo_wr_deinit, - maggeo_read, - maggeo_write, - NULL, - NULL, + ff_type_file, + { ff_cap_read | ff_cap_write, ff_cap_none, ff_cap_none }, + maggeo_rd_init, + maggeo_wr_init, + maggeo_rd_deinit, + maggeo_wr_deinit, + maggeo_read, + maggeo_write, + NULL, + NULL, #if FIRMWARE_DOES_88591 - CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ + CET_CHARSET_LATIN1, 0 /* CET-REVIEW */ #else - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ #endif }; diff --git a/gpsbabel/magnav.c b/gpsbabel/magnav.c index 038cd8919..f615c728d 100644 --- a/gpsbabel/magnav.c +++ b/gpsbabel/magnav.c @@ -28,25 +28,25 @@ #define MYCREATOR 0x4d47747a /* MGtz */ struct record { - pdb_16 crt_sec; /* Big endian, creation time */ - pdb_16 crt_min; - pdb_16 crt_hour; - pdb_16 crt_mday; - pdb_16 crt_mon; /* 1 = Jan */ - pdb_16 crt_year; /* includes century. */ - pdb_16 unknown; - pdb_16 xx_sec; /* appears to be time, but we don't know what it is. */ - pdb_16 xx_min; - pdb_16 xx_hour; - pdb_16 xx_mday; - pdb_16 xx_mon; - pdb_16 xx_year; - pdb_16 unknown2; - pdb_32 latitude; /* lat * 1e5 */ - pdb_32 longitude; /* lon * 1e5 */ - pdb_32 elevation; /* meters */ - char plot; /* 1 = plot on map screen. default = 0 */ - char unknown3; /* always 'a' */ + pdb_16 crt_sec; /* Big endian, creation time */ + pdb_16 crt_min; + pdb_16 crt_hour; + pdb_16 crt_mday; + pdb_16 crt_mon; /* 1 = Jan */ + pdb_16 crt_year; /* includes century. */ + pdb_16 unknown; + pdb_16 xx_sec; /* appears to be time, but we don't know what it is. */ + pdb_16 xx_min; + pdb_16 xx_hour; + pdb_16 xx_mday; + pdb_16 xx_mon; + pdb_16 xx_year; + pdb_16 unknown2; + pdb_32 latitude; /* lat * 1e5 */ + pdb_32 longitude; /* lon * 1e5 */ + pdb_32 elevation; /* meters */ + char plot; /* 1 = plot on map screen. default = 0 */ + char unknown3; /* always 'a' */ }; static pdbfile *file_in; @@ -57,197 +57,196 @@ static int ct; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 20); - ct = 0; + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a Magellan Navigator file.\n"); - } - - for(pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata; - struct tm tm; - - memset (&tm, 0, sizeof(tm)); - wpt_tmp = waypt_new(); - rec = (struct record *) pdb_rec->data; - wpt_tmp->altitude = be_read32(&rec->elevation); - - wpt_tmp->longitude = be_read32(&rec->longitude) / 1e5; - wpt_tmp->latitude = be_read32(&rec->latitude) / 1e5; - - vdata = (char *) pdb_rec->data + sizeof(*rec); - - wpt_tmp->shortname = xstrdup(vdata); - vdata += strlen (vdata) + 1; - - wpt_tmp->description = xstrdup(vdata); - vdata += strlen (vdata) + 1; - - tm.tm_sec = be_read16(&rec->crt_sec); - tm.tm_min = be_read16(&rec->crt_min); - tm.tm_hour = be_read16(&rec->crt_hour); - tm.tm_mday = be_read16(&rec->crt_mday); - tm.tm_mon = be_read16(&rec->crt_mon) - 1; - tm.tm_year = be_read16(&rec->crt_year) - 1900; - if (mkgmtime(&tm) > 0) - wpt_tmp->creation_time = mktime(&tm); - waypt_add(wpt_tmp); - - } + struct record *rec; + pdbrec_t *pdb_rec; + + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } + + for (pdb_rec = file_in->rec_list; pdb_rec; pdb_rec = pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + wpt_tmp = waypt_new(); + rec = (struct record *) pdb_rec->data; + wpt_tmp->altitude = be_read32(&rec->elevation); + + wpt_tmp->longitude = be_read32(&rec->longitude) / 1e5; + wpt_tmp->latitude = be_read32(&rec->latitude) / 1e5; + + vdata = (char *) pdb_rec->data + sizeof(*rec); + + wpt_tmp->shortname = xstrdup(vdata); + vdata += strlen(vdata) + 1; + + wpt_tmp->description = xstrdup(vdata); + vdata += strlen(vdata) + 1; + + tm.tm_sec = be_read16(&rec->crt_sec); + tm.tm_min = be_read16(&rec->crt_min); + tm.tm_hour = be_read16(&rec->crt_hour); + tm.tm_mday = be_read16(&rec->crt_mday); + tm.tm_mon = be_read16(&rec->crt_mon) - 1; + tm.tm_year = be_read16(&rec->crt_year) - 1900; + if (mkgmtime(&tm) > 0) { + wpt_tmp->creation_time = mktime(&tm); + } + waypt_add(wpt_tmp); + + } } static void my_writewpt(const waypoint *wpt) { - struct record *rec; - struct tm *tm; - char *vdata; - time_t tm_t; - const char *sn = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname; - - rec = xcalloc(sizeof(*rec)+56,1); - - tm = NULL; - if ( wpt->creation_time ) { - tm = gmtime( &wpt->creation_time); - } - if ( !tm ) { - tm_t = current_time(); - tm = gmtime( &tm_t ); - } - - be_write16( &rec->crt_sec, tm->tm_sec ); - be_write16( &rec->crt_min, tm->tm_min ); - be_write16( &rec->crt_hour, tm->tm_hour ); - be_write16( &rec->crt_mday, tm->tm_mday ); - be_write16( &rec->crt_mon, tm->tm_mon + 1 ); - be_write16( &rec->crt_year, tm->tm_year + 1900 ); - - be_write16( &rec->unknown, 0); - - be_write16( &rec->xx_sec, tm->tm_sec ); - be_write16( &rec->xx_min, tm->tm_min ); - be_write16( &rec->xx_hour, tm->tm_hour ); - be_write16( &rec->xx_mday, tm->tm_mday ); - be_write16( &rec->xx_mon, tm->tm_mon + 1 ); - be_write16( &rec->xx_year, tm->tm_year + 1900 ); - - be_write16( &rec->unknown2, 0); - - be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); - be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); - be_write32(&rec->elevation, (unsigned int) (wpt->altitude)); - - rec->plot = 0; - rec->unknown3 = 'a'; - - vdata = (char *)rec + sizeof(*rec); - if ( sn ) { - strncpy( vdata, sn, 21 ); - vdata[20] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 33 ); - vdata[32] = '\0'; - } - else { - vdata[0] = '\0'; - } - vdata += strlen( vdata ) + 1; - vdata[0] = '\0'; - vdata[1] = '\0'; - vdata += 2; - - pdb_write_rec(file_out, 0, 0, ct++, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record *rec; + struct tm *tm; + char *vdata; + time_t tm_t; + const char *sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname; + + rec = xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + if (!tm) { + tm_t = current_time(); + tm = gmtime(&tm_t); + } + + be_write16(&rec->crt_sec, tm->tm_sec); + be_write16(&rec->crt_min, tm->tm_min); + be_write16(&rec->crt_hour, tm->tm_hour); + be_write16(&rec->crt_mday, tm->tm_mday); + be_write16(&rec->crt_mon, tm->tm_mon + 1); + be_write16(&rec->crt_year, tm->tm_year + 1900); + + be_write16(&rec->unknown, 0); + + be_write16(&rec->xx_sec, tm->tm_sec); + be_write16(&rec->xx_min, tm->tm_min); + be_write16(&rec->xx_hour, tm->tm_hour); + be_write16(&rec->xx_mday, tm->tm_mday); + be_write16(&rec->xx_mon, tm->tm_mon + 1); + be_write16(&rec->xx_year, tm->tm_year + 1900); + + be_write16(&rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, (unsigned int)(wpt->altitude)); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char *)rec + sizeof(*rec); + if (sn) { + strncpy(vdata, sn, 21); + vdata[20] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 33); + vdata[32] = '\0'; + } else { + vdata[0] = '\0'; + } + vdata += strlen(vdata) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write_rec(file_out, 0, 0, ct++, rec, (char *)vdata - (char *)rec); + + xfree(rec); } static void data_write(void) { - static char *appinfo = - "\0\x01" - "User\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\x01\x02\x03\x04\x05\x06\x07\x08" - "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; - - strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = 276; - - waypt_disp_all(my_writewpt); + static char *appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); } ff_vecs_t magnav_vec = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/magproto.c b/gpsbabel/magproto.c index 5220efcec..b748d0db6 100644 --- a/gpsbabel/magproto.c +++ b/gpsbabel/magproto.c @@ -75,27 +75,27 @@ static char ** os_gpx_files(const char *dirname); static int suppress_ack; typedef enum { - mrs_handoff = 0, - mrs_handon, - mrs_awaiting_ack + mrs_handoff = 0, + mrs_handon, + mrs_awaiting_ack } mag_rxstate; /* * An individual element of a route. */ typedef struct mag_rte_elem { - queue Q; /* My link pointers */ - char *wpt_name; - char *wpt_icon; + queue Q; /* My link pointers */ + char *wpt_name; + char *wpt_icon; } mag_rte_elem; /* * A header of a route. Related elements of a route belong to this. */ typedef struct mag_rte_head { - queue Q; /* Queue head for child rte_elems */ - char *rte_name; - int nelems; + queue Q; /* Queue head for child rte_elems */ + char *rte_name; + int nelems; } mag_rte_head; static queue rte_wpt_tmp; /* temporary PGMNWPL msgs for routes */ @@ -111,109 +111,108 @@ static route_head *trk_head; static int ignore_unable; static waypoint * mag_wptparse(char *); -typedef char * (cleanse_fn) (char *); +typedef char * (cleanse_fn)(char *); static cleanse_fn *mag_cleanse; static const char ** os_get_magellan_mountpoints(); static icon_mapping_t gps315_icon_table[] = { - { "a", "filled circle" }, - { "b", "box" }, - { "c", "red buoy" }, - { "d", "green buoy" }, - { "e", "buoy" }, - { "f", "rocks" }, - { "g", "red daymark" }, - { "h", "green daymark" }, - { "i", "bell" }, - { "j", "danger" }, - { "k", "diver down" }, - { "l", "fish" }, - { "m", "house" }, - { "n", "mark" }, - { "o", "car" }, - { "p", "tent" }, - { "q", "boat" }, - { "r", "food" }, - { "s", "fuel" }, - { "t", "tree" }, - { NULL, NULL } + { "a", "filled circle" }, + { "b", "box" }, + { "c", "red buoy" }, + { "d", "green buoy" }, + { "e", "buoy" }, + { "f", "rocks" }, + { "g", "red daymark" }, + { "h", "green daymark" }, + { "i", "bell" }, + { "j", "danger" }, + { "k", "diver down" }, + { "l", "fish" }, + { "m", "house" }, + { "n", "mark" }, + { "o", "car" }, + { "p", "tent" }, + { "q", "boat" }, + { "r", "food" }, + { "s", "fuel" }, + { "t", "tree" }, + { NULL, NULL } }; static icon_mapping_t map330_icon_table[] = { - { "a", "crossed square" }, - { "b", "box" }, - { "c", "house" }, - { "d", "aerial" }, - { "e", "airport" }, - { "f", "amusement park" }, - { "g", "ATM" }, - { "g", "Bank" }, - { "h", "auto repair" }, - { "i", "boating" }, - { "j", "camping" }, - { "k", "exit ramp" }, - { "l", "first aid" }, - { "m", "nav aid" }, - { "n", "buoy" }, - { "o", "fuel" }, - { "p", "garden" }, - { "q", "golf" }, - { "r", "hotel" }, - { "s", "hunting/fishing" }, - { "t", "large city" }, - { "u", "lighthouse" }, - { "v", "major city" }, - { "w", "marina" }, - { "x", "medium city" }, - { "y", "museum" }, - { "z", "obstruction" }, - { "aa", "park" }, - { "ab", "resort" }, - { "ac", "restaurant" }, - { "ad", "rock" }, - { "ae", "scuba" }, - { "af", "RV service" }, - { "ag", "shooting" }, - { "ah", "sight seeing" }, - { "ai", "small city" }, - { "aj", "sounding" }, - { "ak", "sports arena" }, - { "al", "tourist info" }, - { "am", "truck service" }, - { "an", "winery" }, - { "ao", "wreck" }, - { "ap", "zoo" }, - { "ah", "Virtual cache"}, /* Binos: because you "see" them. */ - { "ak", "Micro-Cache" }, /* Looks like a film canister. */ - { "an", "Multi-Cache"}, /* Winery: grapes 'coz they "bunch" */ - { "s", "Unknown Cache"}, /* 'Suprise' cache: use a target. */ - { "ac", "Event Cache"}, /* Event caches. May be food. */ - { NULL, NULL } + { "a", "crossed square" }, + { "b", "box" }, + { "c", "house" }, + { "d", "aerial" }, + { "e", "airport" }, + { "f", "amusement park" }, + { "g", "ATM" }, + { "g", "Bank" }, + { "h", "auto repair" }, + { "i", "boating" }, + { "j", "camping" }, + { "k", "exit ramp" }, + { "l", "first aid" }, + { "m", "nav aid" }, + { "n", "buoy" }, + { "o", "fuel" }, + { "p", "garden" }, + { "q", "golf" }, + { "r", "hotel" }, + { "s", "hunting/fishing" }, + { "t", "large city" }, + { "u", "lighthouse" }, + { "v", "major city" }, + { "w", "marina" }, + { "x", "medium city" }, + { "y", "museum" }, + { "z", "obstruction" }, + { "aa", "park" }, + { "ab", "resort" }, + { "ac", "restaurant" }, + { "ad", "rock" }, + { "ae", "scuba" }, + { "af", "RV service" }, + { "ag", "shooting" }, + { "ah", "sight seeing" }, + { "ai", "small city" }, + { "aj", "sounding" }, + { "ak", "sports arena" }, + { "al", "tourist info" }, + { "am", "truck service" }, + { "an", "winery" }, + { "ao", "wreck" }, + { "ap", "zoo" }, + { "ah", "Virtual cache"}, /* Binos: because you "see" them. */ + { "ak", "Micro-Cache" }, /* Looks like a film canister. */ + { "an", "Multi-Cache"}, /* Winery: grapes 'coz they "bunch" */ + { "s", "Unknown Cache"}, /* 'Suprise' cache: use a target. */ + { "ac", "Event Cache"}, /* Event caches. May be food. */ + { NULL, NULL } }; -pid_to_model_t pid_to_model[] = -{ - { mm_gps315320, 19, "ColorTrak" }, - { mm_gps315320, 24, "GPS 315/320" }, - { mm_map410, 25, "Map 410" }, - { mm_map330, 30, "Map 330" }, - { mm_gps310, 31, "GPS 310" }, - { mm_meridian, 33, "Meridian" }, - { mm_meridian, 35, "ProMark 2" }, - { mm_sportrak, 36, "SporTrak Map/Pro" }, - { mm_sportrak, 37, "SporTrak" }, - { mm_meridian, 38, "FX324 Plotter" }, - { mm_meridian, 39, "Meridian Color" }, - { mm_meridian, 40, "FX324C Plotter" }, - { mm_sportrak, 41, "Sportrak Color" }, - { mm_sportrak, 42, "Sportrak Marine" }, - { mm_meridian, 43, "Meridian Marine" }, - { mm_sportrak, 44, "Sportrak Topo" }, - { mm_sportrak, 45, "Mystic" }, - { mm_meridian, 46, "MobileMapper" }, - { mm_meridian, 110, "Explorist 100" }, - { mm_meridian, 111, "Explorist 200" }, - { mm_unknown, 0, NULL } +pid_to_model_t pid_to_model[] = { + { mm_gps315320, 19, "ColorTrak" }, + { mm_gps315320, 24, "GPS 315/320" }, + { mm_map410, 25, "Map 410" }, + { mm_map330, 30, "Map 330" }, + { mm_gps310, 31, "GPS 310" }, + { mm_meridian, 33, "Meridian" }, + { mm_meridian, 35, "ProMark 2" }, + { mm_sportrak, 36, "SporTrak Map/Pro" }, + { mm_sportrak, 37, "SporTrak" }, + { mm_meridian, 38, "FX324 Plotter" }, + { mm_meridian, 39, "Meridian Color" }, + { mm_meridian, 40, "FX324C Plotter" }, + { mm_sportrak, 41, "Sportrak Color" }, + { mm_sportrak, 42, "Sportrak Marine" }, + { mm_meridian, 43, "Meridian Marine" }, + { mm_sportrak, 44, "Sportrak Topo" }, + { mm_sportrak, 45, "Mystic" }, + { mm_meridian, 46, "MobileMapper" }, + { mm_meridian, 110, "Explorist 100" }, + { mm_meridian, 111, "Explorist 200" }, + { mm_unknown, 0, NULL } }; static icon_mapping_t *icon_mapping = map330_icon_table; @@ -226,17 +225,17 @@ static icon_mapping_t *icon_mapping = map330_icon_table; static char * m315_cleanse(char *istring) { - char *rstring = xmalloc(strlen(istring)+1); - char *i,*o; - static char m315_valid_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; - for (o=rstring,i=istring; *i; i++) { - if (strchr(m315_valid_chars, toupper(*i))) { - *o++ = toupper(*i); - } - } - *o = 0; - return rstring; + char *rstring = xmalloc(strlen(istring)+1); + char *i,*o; + static char m315_valid_chars[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"; + for (o=rstring,i=istring; *i; i++) { + if (strchr(m315_valid_chars, toupper(*i))) { + *o++ = toupper(*i); + } + } + *o = 0; + return rstring; } /* @@ -245,167 +244,167 @@ m315_cleanse(char *istring) char * m330_cleanse(char *istring) { - static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " - "abcdefghijklmnopqrstuvwxyz" - "0123456789+-.'/!@#<%^&>()=:\\"; - char *rstring = xmalloc(strlen(istring)+1); - char *o, *i; - - for (o=rstring,i=istring; *i;i++) { - if (strchr(m330_valid_chars, *i)) { - *o++ = *i; - } - } - *o = 0; - return rstring; + static char m330_valid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "abcdefghijklmnopqrstuvwxyz" + "0123456789+-.'/!@#<%^&>()=:\\"; + char *rstring = xmalloc(strlen(istring)+1); + char *o, *i; + + for (o=rstring,i=istring; *i; i++) { + if (strchr(m330_valid_chars, *i)) { + *o++ = *i; + } + } + *o = 0; + return rstring; } /* - * Given a protocol message, compute the checksum as needed by + * Given a protocol message, compute the checksum as needed by * the Magellan protocol. */ -unsigned int +unsigned int mag_checksum(const char * const buf) { - int csum = 0; - const char *p; - - for(p = buf; *p; p++) { - csum ^= *p; - } - - return csum; + int csum = 0; + const char *p; + + for (p = buf; *p; p++) { + csum ^= *p; + } + + return csum; } static unsigned int mag_pchecksum(const char * const buf, int len) { - int csum = 0; - const char *p = buf; - for (; len ; len--) { - csum ^= *p++; - } - return csum; + int csum = 0; + const char *p = buf; + for (; len ; len--) { + csum ^= *p++; + } + return csum; } static void mag_writemsg(const char * const buf) { - unsigned int osum = mag_checksum(buf); - int retry_cnt = 5; - int i; - char obuf[1000]; - - if (debug_serial) { - warning("WRITE: $%s*%02X\r\n",buf, osum); - } - - retry: - - i = sprintf(obuf, "$%s*%02X\r\n",buf, osum); - termwrite(obuf, i); - if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) { - magrxstate = mrs_awaiting_ack; - mag_readmsg(trkdata); - if (last_rx_csum != osum) { - if (debug_serial) { - warning("COMM ERROR: Expected %02x, got %02x", - osum, last_rx_csum); - } - if (retry_cnt--) - goto retry; - else { - mag_handoff(); - fatal(MYNAME - ": Too many communication errors.\n"); - } - } - } -} + unsigned int osum = mag_checksum(buf); + int retry_cnt = 5; + int i; + char obuf[1000]; + + if (debug_serial) { + warning("WRITE: $%s*%02X\r\n",buf, osum); + } + +retry: + + i = sprintf(obuf, "$%s*%02X\r\n",buf, osum); + termwrite(obuf, i); + if (magrxstate == mrs_handon || magrxstate == mrs_awaiting_ack) { + magrxstate = mrs_awaiting_ack; + mag_readmsg(trkdata); + if (last_rx_csum != osum) { + if (debug_serial) { + warning("COMM ERROR: Expected %02x, got %02x", + osum, last_rx_csum); + } + if (retry_cnt--) { + goto retry; + } else { + mag_handoff(); + fatal(MYNAME + ": Too many communication errors.\n"); + } + } + } +} static void mag_writeack(int osum) { - char obuf[200]; - char nbuf[200]; - int i; - unsigned int nsum; - - if (is_file) { - return; - } - - i = sprintf(nbuf, "PMGNCSM,%02X", osum); - nsum = mag_checksum(nbuf); - i = sprintf(obuf, "$%s*%02X\r\n",nbuf, nsum); - - if (debug_serial) { - warning("ACK WRITE: %s",obuf); - } - /* - * Don't call mag_writemsg here so we don't get into ack feedback - * loops. - */ - termwrite(obuf, i); + char obuf[200]; + char nbuf[200]; + int i; + unsigned int nsum; + + if (is_file) { + return; + } + + i = sprintf(nbuf, "PMGNCSM,%02X", osum); + nsum = mag_checksum(nbuf); + i = sprintf(obuf, "$%s*%02X\r\n",nbuf, nsum); + + if (debug_serial) { + warning("ACK WRITE: %s",obuf); + } + /* + * Don't call mag_writemsg here so we don't get into ack feedback + * loops. + */ + termwrite(obuf, i); } static void mag_handon(void) { - if (!is_file) { - mag_writemsg("PMGNCMD,HANDON"); - } - magrxstate = mrs_handon; - + if (!is_file) { + mag_writemsg("PMGNCMD,HANDON"); + } + magrxstate = mrs_handon; + } static void mag_handoff(void) { - if (!is_file) { - mag_writemsg("PMGNCMD,HANDOFF"); - } - magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,HANDOFF"); + } + magrxstate = mrs_handoff; } void mag_verparse(char *ibuf) { - int prodid = mm_unknown; - char version[1024]; - pid_to_model_t *pp = pid_to_model; - - got_version = 1; - sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); - - for (pp = pid_to_model; pp->model != mm_unknown; pp++) { - if (pp->pid == prodid) { - break; - } - } - - if (prodid == 37) { - broken_sportrak = 1; - } - - switch (pp->model) { - case mm_gps315320: - case mm_map410: - icon_mapping = gps315_icon_table; - setshort_length(mkshort_handle, 6); - setshort_mustupper(mkshort_handle, 1); - mag_cleanse = m315_cleanse; - break; - case mm_map330: - case mm_meridian: - case mm_sportrak: - icon_mapping = map330_icon_table; - setshort_length(mkshort_handle, wpt_len); - setshort_mustupper(mkshort_handle, 0); - mag_cleanse = m330_cleanse; - break; - default: - fatal(MYNAME ": Unknown receiver type %d, model version '%s'.\n", prodid, version); - } + int prodid = mm_unknown; + char version[1024]; + pid_to_model_t *pp = pid_to_model; + + got_version = 1; + sscanf(ibuf,"$PMGNVER,%d,%[^,]", &prodid, version); + + for (pp = pid_to_model; pp->model != mm_unknown; pp++) { + if (pp->pid == prodid) { + break; + } + } + + if (prodid == 37) { + broken_sportrak = 1; + } + + switch (pp->model) { + case mm_gps315320: + case mm_map410: + icon_mapping = gps315_icon_table; + setshort_length(mkshort_handle, 6); + setshort_mustupper(mkshort_handle, 1); + mag_cleanse = m315_cleanse; + break; + case mm_map330: + case mm_meridian: + case mm_sportrak: + icon_mapping = map330_icon_table; + setshort_length(mkshort_handle, wpt_len); + setshort_mustupper(mkshort_handle, 0); + mag_cleanse = m330_cleanse; + break; + default: + fatal(MYNAME ": Unknown receiver type %d, model version '%s'.\n", prodid, version); + } } #define IS_TKN(x) (strncmp(ibuf,x, sizeof(x)-1) == 0) @@ -413,194 +412,197 @@ mag_verparse(char *ibuf) static void mag_readmsg(gpsdata_type objective) { - char ibuf[512]; /* oliskoli: corrupted data (I've seen descr with a lot + char ibuf[512]; /* oliskoli: corrupted data (I've seen descr with a lot of escaped FFFFFFFF) may need more size */ - int isz; - unsigned int isum; - char *isump; - char *gr; - int retrycnt = 20; + int isz; + unsigned int isum; + char *isump; + char *gr; + int retrycnt = 20; retry: - gr = termread(ibuf, sizeof(ibuf)); - - if (!gr) { - if (!got_version) { - /* - * The 315 can take up to six seconds to respond to - * a VERSION command. Since this is on startup, - * we'll be fairly persistent in retrying. - */ - if (retrycnt--) { - goto retry; - } else { - fatal(MYNAME ": No data received from GPS.\n"); - } - } else { - if (is_file) { - found_done = 1; - } - return; - } - } - - /* If column zero isn't a dollar sign, it's not for us */ - if (ibuf[0] != '$') { - fatal(MYNAME ": line doesn't start with '$'.\n"); - } - - - isz = strlen(ibuf); - - if (isz < 5) { - if (debug_serial) - warning( "SHORT READ %d\n", isz); - return; - } - mag_error = 0; - while (!isprint(ibuf[isz])) - isz--; - isump = &ibuf[isz-1]; - isum = strtoul(isump, NULL,16); - if (isum != mag_pchecksum(&ibuf[1], isz-3)) { - if (debug_serial) - warning( "RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); - /* Special case receive errors early on. */ - if (!got_version) { - fatal(MYNAME ": bad communication. Check bit rate.\n"); - } - } - if (debug_serial) { - warning( "READ: %s\n", ibuf); - } - if (IS_TKN("$PMGNCSM,")) { - last_rx_csum = strtoul(&ibuf[9], NULL, 16); - magrxstate = mrs_handon; - return; - } - if (strncmp(ibuf, "$PMGNWPL,", 7) == 0) { - waypoint *wpt = mag_wptparse(ibuf); - waypoint_read_count++; - if (global_opts.verbose_status) { - waypt_status_disp(waypoint_read_count, - waypoint_read_count); - } - - if (extension_hint) { - if (extension_hint == WPTDATAMASK) { - waypt_add(wpt); - } else if (extension_hint == RTEDATAMASK) { - ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); - } - } else { - switch (objective) { - case wptdata: - waypt_add(wpt); - break; - case rtedata: - ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); - break; - default: - break; - } - } - } - if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { - waypoint *wpt = mag_trkparse(ibuf); - /* - * Allow lazy allocation of track head. - */ - if (trk_head == NULL) { - /* These tracks don't have names, so derive one - * from input filename. - */ - char *e; - const char *s = get_filename(curfname); - - trk_head = route_head_alloc(); - - /* Whack trailing extension if present. */ - trk_head->rte_name = xstrdup(s); - e = strrchr(trk_head->rte_name, '.'); - if (e) { - *e = '\0'; - } - - track_add_head(trk_head); - } - - track_add_wpt(trk_head, wpt); - } - if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { - mag_rteparse(ibuf); - } - if (IS_TKN("$PMGNVER,")) { - mag_verparse(ibuf); - } - mag_error = 0; - if (!ignore_unable && IS_TKN("$PMGNCMD,UNABLE")) { - warning( "Unable to send\n"); - found_done = 1; - mag_error = 1; - ignore_unable = 0; - return; - } - if (IS_TKN("$PMGNCMD,END") || (is_file && (gbfeof(magfile_h)))) { - found_done = 1; - return; - } - - if (magrxstate != mrs_handoff) { - mag_writeack(isum); - } + gr = termread(ibuf, sizeof(ibuf)); + + if (!gr) { + if (!got_version) { + /* + * The 315 can take up to six seconds to respond to + * a VERSION command. Since this is on startup, + * we'll be fairly persistent in retrying. + */ + if (retrycnt--) { + goto retry; + } else { + fatal(MYNAME ": No data received from GPS.\n"); + } + } else { + if (is_file) { + found_done = 1; + } + return; + } + } + + /* If column zero isn't a dollar sign, it's not for us */ + if (ibuf[0] != '$') { + fatal(MYNAME ": line doesn't start with '$'.\n"); + } + + + isz = strlen(ibuf); + + if (isz < 5) { + if (debug_serial) { + warning("SHORT READ %d\n", isz); + } + return; + } + mag_error = 0; + while (!isprint(ibuf[isz])) { + isz--; + } + isump = &ibuf[isz-1]; + isum = strtoul(isump, NULL,16); + if (isum != mag_pchecksum(&ibuf[1], isz-3)) { + if (debug_serial) { + warning("RXERR %02x/%02x: '%s'\n", isum, mag_pchecksum(&ibuf[1],isz-5), ibuf); + } + /* Special case receive errors early on. */ + if (!got_version) { + fatal(MYNAME ": bad communication. Check bit rate.\n"); + } + } + if (debug_serial) { + warning("READ: %s\n", ibuf); + } + if (IS_TKN("$PMGNCSM,")) { + last_rx_csum = strtoul(&ibuf[9], NULL, 16); + magrxstate = mrs_handon; + return; + } + if (strncmp(ibuf, "$PMGNWPL,", 7) == 0) { + waypoint *wpt = mag_wptparse(ibuf); + waypoint_read_count++; + if (global_opts.verbose_status) { + waypt_status_disp(waypoint_read_count, + waypoint_read_count); + } + + if (extension_hint) { + if (extension_hint == WPTDATAMASK) { + waypt_add(wpt); + } else if (extension_hint == RTEDATAMASK) { + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + } + } else { + switch (objective) { + case wptdata: + waypt_add(wpt); + break; + case rtedata: + ENQUEUE_TAIL(&rte_wpt_tmp, &wpt->Q); + break; + default: + break; + } + } + } + if (strncmp(ibuf, "$PMGNTRK,", 7) == 0) { + waypoint *wpt = mag_trkparse(ibuf); + /* + * Allow lazy allocation of track head. + */ + if (trk_head == NULL) { + /* These tracks don't have names, so derive one + * from input filename. + */ + char *e; + const char *s = get_filename(curfname); + + trk_head = route_head_alloc(); + + /* Whack trailing extension if present. */ + trk_head->rte_name = xstrdup(s); + e = strrchr(trk_head->rte_name, '.'); + if (e) { + *e = '\0'; + } + + track_add_head(trk_head); + } + + track_add_wpt(trk_head, wpt); + } + if (strncmp(ibuf, "$PMGNRTE,", 7) == 0) { + mag_rteparse(ibuf); + } + if (IS_TKN("$PMGNVER,")) { + mag_verparse(ibuf); + } + mag_error = 0; + if (!ignore_unable && IS_TKN("$PMGNCMD,UNABLE")) { + warning("Unable to send\n"); + found_done = 1; + mag_error = 1; + ignore_unable = 0; + return; + } + if (IS_TKN("$PMGNCMD,END") || (is_file && (gbfeof(magfile_h)))) { + found_done = 1; + return; + } + + if (magrxstate != mrs_handoff) { + mag_writeack(isum); + } } static void *serial_handle = NULL; -static int -terminit(const char *portname, int create_ok) +static int +terminit(const char *portname, int create_ok) { - if (gbser_is_serial(portname)) { - if (serial_handle = gbser_init(portname), NULL != serial_handle) { - int rc; - if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { - fatal(MYNAME ": Can't configure port\n"); - } - } - is_file = 0; - if (serial_handle == NULL) { - fatal(MYNAME ": Could not open serial port %s\n", portname); - } - return 1; - } else { - /* Does this check for an error? */ - magfile_h = gbfopen(portname, create_ok ? "w+b" : "rb", MYNAME); - is_file = 1; - icon_mapping = map330_icon_table; - mag_cleanse = m330_cleanse; - got_version = 1; - return 0; - } + if (gbser_is_serial(portname)) { + if (serial_handle = gbser_init(portname), NULL != serial_handle) { + int rc; + if (rc = gbser_set_port(serial_handle, bitrate, 8, 0, 1), gbser_OK != rc) { + fatal(MYNAME ": Can't configure port\n"); + } + } + is_file = 0; + if (serial_handle == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", portname); + } + return 1; + } else { + /* Does this check for an error? */ + magfile_h = gbfopen(portname, create_ok ? "w+b" : "rb", MYNAME); + is_file = 1; + icon_mapping = map330_icon_table; + mag_cleanse = m330_cleanse; + got_version = 1; + return 0; + } } -static char *termread(char *ibuf, int size) +static char *termread(char *ibuf, int size) { - if (is_file) { - return gbfgets(ibuf, size, magfile_h); - } else { - int rc; - rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); - if (rc != gbser_OK) { - fatal(MYNAME ": Read error\n"); - } - return ibuf; - } + if (is_file) { + return gbfgets(ibuf, size, magfile_h); + } else { + int rc; + rc = gbser_read_line(serial_handle, ibuf, size, 2000, 0x0a, 0x0d); + if (rc != gbser_OK) { + fatal(MYNAME ": Read error\n"); + } + return ibuf; + } } /* Though not documented in the protocol spec, if the unit itself - * wants to create a field containing a comma, it will encode it + * wants to create a field containing a comma, it will encode it * as 2C. We extrapolate that any 2 digit hex encoding may - * be valid. We don't do this in termread() since we need to do it + * be valid. We don't do this in termread() since we need to do it * after the scanf. This means we have to do it field-by-field * basis. * @@ -609,62 +611,62 @@ static char *termread(char *ibuf, int size) */ static void -mag_dequote(char *ibuf) +mag_dequote(char *ibuf) { - char *esc = NULL; - - while ((esc = strchr (ibuf, 0x1b))) { - int nremains = strlen(esc); - if (nremains >= 3) { - static const char hex[16] = "0123456789ABCDEF"; - char *c1 = strchr(hex, esc[1]); - char *c2 = strchr(hex, esc[2]); - if (c1 && c2) { - int escv = (c1 - hex) * 16 + (c2 - hex); - if (escv == 255) { /* corrupted data */ - char *tmp = esc + 1; - while (*tmp == 'F') tmp++; - memmove(esc, tmp, strlen(tmp) + 1); - } - else { - *esc++ = (isprint(escv)) ? escv : '$'; - /* buffers overlap */ - memmove(esc, esc+2, nremains - 2); - } - } - } - else { - *esc = '\0'; /* trim corrupted data, + char *esc = NULL; + + while ((esc = strchr(ibuf, 0x1b))) { + int nremains = strlen(esc); + if (nremains >= 3) { + static const char hex[16] = "0123456789ABCDEF"; + char *c1 = strchr(hex, esc[1]); + char *c2 = strchr(hex, esc[2]); + if (c1 && c2) { + int escv = (c1 - hex) * 16 + (c2 - hex); + if (escv == 255) { /* corrupted data */ + char *tmp = esc + 1; + while (*tmp == 'F') { + tmp++; + } + memmove(esc, tmp, strlen(tmp) + 1); + } else { + *esc++ = (isprint(escv)) ? escv : '$'; + /* buffers overlap */ + memmove(esc, esc+2, nremains - 2); + } + } + } else { + *esc = '\0'; /* trim corrupted data, otherwise we get an endless loop */ - } - } + } + } } -static void -termwrite(char *obuf, int size) +static void +termwrite(char *obuf, int size) { - if (is_file) { - size_t nw; - if (nw = gbfwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { - fatal(MYNAME ": Write error"); - } - } else { - int rc; - if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { - fatal(MYNAME ": Write error"); - } - } + if (is_file) { + size_t nw; + if (nw = gbfwrite(obuf, 1, size, magfile_h), nw < (size_t) size) { + fatal(MYNAME ": Write error"); + } + } else { + int rc; + if (rc = gbser_write(serial_handle, obuf, size), rc < 0) { + fatal(MYNAME ": Write error"); + } + } } -static void termdeinit() +static void termdeinit() { - if (is_file) { - gbfclose(magfile_h); - magfile_h = NULL; - } else { - gbser_deinit(serial_handle); - serial_handle = NULL; - } + if (is_file) { + gbfclose(magfile_h); + magfile_h = NULL; + } else { + gbser_deinit(serial_handle); + serial_handle = NULL; + } } /* @@ -672,181 +674,196 @@ static void termdeinit() */ static arglist_t mag_sargs[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", - "200", ARGTYPE_INT, ARG_NOMINMAX }, - {"baud", &bs, "Numeric value of bitrate (baud=4800)", "4800", - ARGTYPE_INT, ARG_NOMINMAX }, - {"noack", &noack, "Suppress use of handshaking in name of speed", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + "200", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "baud", &bs, "Numeric value of bitrate (baud=4800)", "4800", + ARGTYPE_INT, ARG_NOMINMAX + }, + { + "noack", &noack, "Suppress use of handshaking in name of speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + ARG_TERMINATOR }; static arglist_t mag_fargs[] = { - {"deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX }, - {"maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + "maxcmts", &cmts, "Max number of comments to write (maxcmts=200)", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -/* +/* * The part of the serial init that's common to read and write. */ static void mag_serial_init_common(const char *portname) { - time_t now, later; - - if (is_file) { - return; - } - - mag_handoff(); - if (!noack && !suppress_ack) - mag_handon(); - - now = current_time(); - /* - * The 315 can take up to 4.25 seconds to respond to initialization - * commands. Time out on the side of caution. - */ - later = now + 6; - got_version = 0; - mag_writemsg("PMGNCMD,VERSION"); - - while (!got_version) { - mag_readmsg(trkdata); - if (current_time() > later) { - fatal(MYNAME ": No acknowledgment from GPS on %s\n", - portname); - } - } - - if ((icon_mapping != gps315_icon_table)) { - /* - * The 315 can't handle this command, so we set a global - * to ignore the NAK on it. - */ - ignore_unable = 1; - mag_writemsg("PMGNCMD,NMEAOFF"); - ignore_unable = 0; - } - - if (nukewpt) { - /* The unit will send us an "end" message upon completion */ - mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); - mag_readmsg(trkdata); - if (!found_done) { - fatal(MYNAME ": Unexpected response to waypoint delete command.\n"); - } - found_done = 0; - } + time_t now, later; + + if (is_file) { + return; + } + + mag_handoff(); + if (!noack && !suppress_ack) { + mag_handon(); + } + + now = current_time(); + /* + * The 315 can take up to 4.25 seconds to respond to initialization + * commands. Time out on the side of caution. + */ + later = now + 6; + got_version = 0; + mag_writemsg("PMGNCMD,VERSION"); + + while (!got_version) { + mag_readmsg(trkdata); + if (current_time() > later) { + fatal(MYNAME ": No acknowledgment from GPS on %s\n", + portname); + } + } + + if ((icon_mapping != gps315_icon_table)) { + /* + * The 315 can't handle this command, so we set a global + * to ignore the NAK on it. + */ + ignore_unable = 1; + mag_writemsg("PMGNCMD,NMEAOFF"); + ignore_unable = 0; + } + + if (nukewpt) { + /* The unit will send us an "end" message upon completion */ + mag_writemsg("PMGNCMD,DELETE,WAYPOINT"); + mag_readmsg(trkdata); + if (!found_done) { + fatal(MYNAME ": Unexpected response to waypoint delete command.\n"); + } + found_done = 0; + } } static void mag_rd_init_common(const char *portname) { - char *ext; - waypoint_read_count = 0; - // For Explorist GC, intercept the device access and redirect to GPX. - // We actually do the rd_init() inside read as we may have multiple - // files that we have to read. - if (0 == strcmp(portname, "usb:")) { - const char **dlist = os_get_magellan_mountpoints(); - explorist_info = explorist_ini_get(dlist); - if (explorist_info) { - char *vec_opts = NULL; - gpx_vec = find_vec("gpx", &vec_opts); - } - return; - } - - if (bs) { - bitrate=atoi(bs); - } - - if (!mkshort_handle) { - mkshort_handle = mkshort_new_handle(); - } - - terminit(portname, 0); - mag_serial_init_common(portname); - - QUEUE_INIT(&rte_wpt_tmp); - - /* find the location of the tail of the path name, - * make a copy of it, then lop off the file extension - */ - - curfname = get_filename(portname); - - /* - * I'd rather not derive behaviour from filenames but since - * we can't otherwise tell if we should put a WPT on the route - * queue or the WPT queue in the presence of (-w -r -t) we - * divine a hint from the filename extension when we can. - */ - ext = strrchr(curfname, '.'); - if (ext) { - ext++; - if (0 == case_ignore_strcmp(ext, "upt")) { - extension_hint = WPTDATAMASK; - } else if (0 == case_ignore_strcmp(ext, "log")) { - extension_hint = TRKDATAMASK; - } else if (0 == case_ignore_strcmp(ext, "rte")) { - extension_hint = RTEDATAMASK; - } - } - - return; + char *ext; + waypoint_read_count = 0; + // For Explorist GC, intercept the device access and redirect to GPX. + // We actually do the rd_init() inside read as we may have multiple + // files that we have to read. + if (0 == strcmp(portname, "usb:")) { + const char **dlist = os_get_magellan_mountpoints(); + explorist_info = explorist_ini_get(dlist); + if (explorist_info) { + char *vec_opts = NULL; + gpx_vec = find_vec("gpx", &vec_opts); + } + return; + } + + if (bs) { + bitrate=atoi(bs); + } + + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } + + terminit(portname, 0); + mag_serial_init_common(portname); + + QUEUE_INIT(&rte_wpt_tmp); + + /* find the location of the tail of the path name, + * make a copy of it, then lop off the file extension + */ + + curfname = get_filename(portname); + + /* + * I'd rather not derive behaviour from filenames but since + * we can't otherwise tell if we should put a WPT on the route + * queue or the WPT queue in the presence of (-w -r -t) we + * divine a hint from the filename extension when we can. + */ + ext = strrchr(curfname, '.'); + if (ext) { + ext++; + if (0 == case_ignore_strcmp(ext, "upt")) { + extension_hint = WPTDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "log")) { + extension_hint = TRKDATAMASK; + } else if (0 == case_ignore_strcmp(ext, "rte")) { + extension_hint = RTEDATAMASK; + } + } + + return; } static void mag_rd_init(const char *portname) { - explorist = 0; - suppress_ack = 1; - mag_rd_init_common(portname); + explorist = 0; + suppress_ack = 1; + mag_rd_init_common(portname); } static void magX_rd_init(const char *portname) { - explorist = 1; - mag_rd_init_common(portname); + explorist = 1; + mag_rd_init_common(portname); } static void mag_wr_init_common(const char *portname) { - suppress_ack = 0; - if (bs) { - bitrate=atoi(bs); - } + suppress_ack = 0; + if (bs) { + bitrate=atoi(bs); + } - if (waypt_count() > 500) { - fatal(MYNAME ": Meridian/Explorist does not support more than 500 waypoints in one file. Only\n200 waypoints may have comments.\nDecrease the number of waypoints sent.\n"); - } + if (waypt_count() > 500) { + fatal(MYNAME ": Meridian/Explorist does not support more than 500 waypoints in one file. Only\n200 waypoints may have comments.\nDecrease the number of waypoints sent.\n"); + } - if (cmts) { - wptcmtcnt_max = atoi(cmts); - } else { - wptcmtcnt_max = MAXCMTCT ; - } + if (cmts) { + wptcmtcnt_max = atoi(cmts); + } else { + wptcmtcnt_max = MAXCMTCT ; + } - if (!mkshort_handle) { - mkshort_handle = mkshort_new_handle(); - } + if (!mkshort_handle) { + mkshort_handle = mkshort_new_handle(); + } - terminit(portname, 1); - mag_serial_init_common(portname); + terminit(portname, 1); + mag_serial_init_common(portname); - QUEUE_INIT(&rte_wpt_tmp); + QUEUE_INIT(&rte_wpt_tmp); } /* @@ -855,48 +872,49 @@ mag_wr_init_common(const char *portname) static void magX_wr_init(const char *portname) { - wpt_len = 20; - explorist = 1; - mag_wr_init_common(portname); - setshort_length(mkshort_handle, wpt_len); - setshort_whitespace_ok(mkshort_handle, 1); + wpt_len = 20; + explorist = 1; + mag_wr_init_common(portname); + setshort_length(mkshort_handle, wpt_len); + setshort_whitespace_ok(mkshort_handle, 1); } static void mag_wr_init(const char *portname) { - explorist = 0; - wpt_len = 8; - mag_wr_init_common(portname); - /* - * Whitespace is actually legal, but since waypoint name length is - * only 8 bytes, we'll conserve them. - */ - - setshort_whitespace_ok(mkshort_handle, 0); + explorist = 0; + wpt_len = 8; + mag_wr_init_common(portname); + /* + * Whitespace is actually legal, but since waypoint name length is + * only 8 bytes, we'll conserve them. + */ + + setshort_whitespace_ok(mkshort_handle, 0); } static void mag_deinit(void) { - if (explorist_info) { - explorist_ini_done(explorist_info); - return; - } - mag_handoff(); - termdeinit(); - if(mkshort_handle) - mkshort_del_handle(&mkshort_handle); - - waypt_flush(&rte_wpt_tmp); - - trk_head = NULL; + if (explorist_info) { + explorist_ini_done(explorist_info); + return; + } + mag_handoff(); + termdeinit(); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + + waypt_flush(&rte_wpt_tmp); + + trk_head = NULL; } /* - * I'm tired of arguing with scanf about optional fields . Detokenize + * I'm tired of arguing with scanf about optional fields . Detokenize * an incoming string that may contain empty fields. - * + * * Probably should be cleaned up and moved to common code, but * making it deal with an arbitrary number of fields of arbitrary * size is icky. We don't have to solve the general case here... @@ -906,20 +924,22 @@ static char ifield[20][100]; static void parse_istring(char *istring) { - int f = 0; - int n,x; - while (istring[0]) { - char *fp = ifield[f]; - x = sscanf(istring, "%[^,]%n", fp, &n); - f++; - if (x) { - istring += n; - /* IF more in this string, skip delim */ - if (istring[0]) istring++; - } else { - istring ++; - } - } + int f = 0; + int n,x; + while (istring[0]) { + char *fp = ifield[f]; + x = sscanf(istring, "%[^,]%n", fp, &n); + f++; + if (x) { + istring += n; + /* IF more in this string, skip delim */ + if (istring[0]) { + istring++; + } + } else { + istring ++; + } + } } /* @@ -927,64 +947,68 @@ void parse_istring(char *istring) * $PMGNTRK,3605.259,N,08644.389,W,00151,M,201444.61,A,,020302*66 * create and return a populated waypoint. */ -waypoint * +waypoint * mag_trkparse(char *trkmsg) { - double latdeg, lngdeg; - int alt; - char altunits; - char lngdir, latdir; - int dmy; - int hms; - int fracsecs; - struct tm tm; - waypoint *waypt; - - waypt = waypt_new(); - - memset(&tm, 0, sizeof(tm)); - - /* - * As some of the fields are optional, sscanf works badly - * for us. - */ - parse_istring(trkmsg); - latdeg = atof(ifield[1]); - latdir = ifield[2][0]; - lngdeg = atof(ifield[3]); - lngdir = ifield[4][0]; - alt = atof(ifield[5]); - altunits = ifield[6][0]; - sscanf(ifield[7], "%d.%d", &hms, &fracsecs); - /* Field 8 is constant */ - /* Field nine is optional track name */ - dmy = atoi(ifield[10]); - - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - - tm.tm_year = 100 + dmy % 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy % 100; - - waypt->creation_time = mkgmtime(&tm); - waypt->microseconds = CENTI_TO_MICRO(fracsecs); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - - return waypt; - + double latdeg, lngdeg; + int alt; + char altunits; + char lngdir, latdir; + int dmy; + int hms; + int fracsecs; + struct tm tm; + waypoint *waypt; + + waypt = waypt_new(); + + memset(&tm, 0, sizeof(tm)); + + /* + * As some of the fields are optional, sscanf works badly + * for us. + */ + parse_istring(trkmsg); + latdeg = atof(ifield[1]); + latdir = ifield[2][0]; + lngdeg = atof(ifield[3]); + lngdir = ifield[4][0]; + alt = atof(ifield[5]); + altunits = ifield[6][0]; + sscanf(ifield[7], "%d.%d", &hms, &fracsecs); + /* Field 8 is constant */ + /* Field nine is optional track name */ + dmy = atoi(ifield[10]); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + tm.tm_year = 100 + dmy % 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy % 100; + + waypt->creation_time = mkgmtime(&tm); + waypt->microseconds = CENTI_TO_MICRO(fracsecs); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + return waypt; + } /* @@ -995,171 +1019,179 @@ mag_trkparse(char *trkmsg) void mag_rteparse(char *rtemsg) { - char descr[100]; - int n; - int frags,frag,rtenum; - char xbuf[100],next_stop[100],abuf[100]; - char *currtemsg; - static mag_rte_head *mag_rte_head; - mag_rte_elem *rte_elem; - char *p; - char *rte_name = NULL; - - descr[0] = 0; + char descr[100]; + int n; + int frags,frag,rtenum; + char xbuf[100],next_stop[100],abuf[100]; + char *currtemsg; + static mag_rte_head *mag_rte_head; + mag_rte_elem *rte_elem; + char *p; + char *rte_name = NULL; + + descr[0] = 0; #if 0 - sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", - &frags,&frag,xbuf,&rtenum,&n); + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); #else - sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", - &frags,&frag,xbuf,&rtenum,&n); - - /* Explorist has a route name here */ - if (explorist) { - char *ca, *ce; - - ca = rtemsg + n; - is_fatal(*ca++ != ',', MYNAME ": Incorrectly formatted route line '%s'", rtemsg); - - ce = strchr(ca, ','); - is_fatal(ce == NULL, MYNAME ": Incorrectly formatted route line '%s'", rtemsg); - - if (ca == ce) - xasprintf(&rte_name, "Route%d", rtenum); - else - rte_name = xstrndup(ca, ce - ca); - - n += ((ce - ca) + 1); - } + sscanf(rtemsg,"$PMGNRTE,%d,%d,%c,%d%n", + &frags,&frag,xbuf,&rtenum,&n); + + /* Explorist has a route name here */ + if (explorist) { + char *ca, *ce; + + ca = rtemsg + n; + is_fatal(*ca++ != ',', MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + ce = strchr(ca, ','); + is_fatal(ce == NULL, MYNAME ": Incorrectly formatted route line '%s'", rtemsg); + + if (ca == ce) { + xasprintf(&rte_name, "Route%d", rtenum); + } else { + rte_name = xstrndup(ca, ce - ca); + } + + n += ((ce - ca) + 1); + } #endif - /* - * This is the first component of a route. Allocate a new - * queue head. - */ - if (frag == 1) { - mag_rte_head = xcalloc(sizeof (*mag_rte_head),1); - QUEUE_INIT(&mag_rte_head->Q); - mag_rte_head->nelems = frags; - } - - currtemsg = rtemsg + n; - - /* - * The individual line may contain several route elements. - * loop and pick those up. - */ - while (sscanf(currtemsg,",%[^,],%[^,]%n",next_stop, abuf,&n)) { - if ((next_stop[0] == 0) || (next_stop[0] == '*')) { - break; - } - - /* trim CRC from waypoint icon string */ - if ((p = strchr(abuf, '*')) != NULL) - *p = '\0'; - - rte_elem = xcalloc(sizeof (*rte_elem),1); - QUEUE_INIT(&rte_elem->Q); - - rte_elem->wpt_name = xstrdup(next_stop); - rte_elem->wpt_icon = xstrdup(abuf); - - ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); - - /* Sportrak (the non-mapping unit) creates malformed - * RTE sentence with no icon info after the routepoint - * name. So if we saw an "icon" treat that as new - * routepoint. - */ - if (broken_sportrak && abuf[0]) { - rte_elem = xcalloc(sizeof (*rte_elem),1); - QUEUE_INIT(&rte_elem->Q); - rte_elem->wpt_name = xstrdup(abuf); - - ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); - } - - next_stop[0] = 0; - currtemsg += n; - } - - /* - * If this was the last fragment of the route, add it to the - * gpsbabel internal structs now. - */ - if (frag == mag_rte_head->nelems) { - queue *elem, *tmp; - route_head *rte_head; - - rte_head = route_head_alloc(); - route_add_head(rte_head); - rte_head->rte_num = rtenum; - rte_head->rte_name = xstrdup(rte_name); - - /* - * It is quite feasible that we have 200 waypoints, - * 3 of which are used in the route. We'll need to find - * those in the queue for SD routes... - */ - - QUEUE_FOR_EACH(&mag_rte_head->Q, elem, tmp) { - mag_rte_elem *re = (mag_rte_elem *) elem; - waypoint *waypt; - queue *welem, *wtmp; - - /* - * Copy route points from temp wpt queue. - */ - QUEUE_FOR_EACH(&rte_wpt_tmp, welem, wtmp) { - waypt = (waypoint *)welem; - if (strcmp(waypt->shortname, re->wpt_name) == 0) { - waypoint * wpt = waypt_dupe(waypt); - route_add_wpt(rte_head, wpt); - break; - } - } - - dequeue(&re->Q); - xfree(re->wpt_name); - xfree(re->wpt_icon); - xfree(re); - } - xfree(mag_rte_head); - } - if (rte_name) xfree(rte_name); + /* + * This is the first component of a route. Allocate a new + * queue head. + */ + if (frag == 1) { + mag_rte_head = xcalloc(sizeof(*mag_rte_head),1); + QUEUE_INIT(&mag_rte_head->Q); + mag_rte_head->nelems = frags; + } + + currtemsg = rtemsg + n; + + /* + * The individual line may contain several route elements. + * loop and pick those up. + */ + while (sscanf(currtemsg,",%[^,],%[^,]%n",next_stop, abuf,&n)) { + if ((next_stop[0] == 0) || (next_stop[0] == '*')) { + break; + } + + /* trim CRC from waypoint icon string */ + if ((p = strchr(abuf, '*')) != NULL) { + *p = '\0'; + } + + rte_elem = xcalloc(sizeof(*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + + rte_elem->wpt_name = xstrdup(next_stop); + rte_elem->wpt_icon = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + + /* Sportrak (the non-mapping unit) creates malformed + * RTE sentence with no icon info after the routepoint + * name. So if we saw an "icon" treat that as new + * routepoint. + */ + if (broken_sportrak && abuf[0]) { + rte_elem = xcalloc(sizeof(*rte_elem),1); + QUEUE_INIT(&rte_elem->Q); + rte_elem->wpt_name = xstrdup(abuf); + + ENQUEUE_TAIL(&mag_rte_head->Q, &rte_elem->Q); + } + + next_stop[0] = 0; + currtemsg += n; + } + + /* + * If this was the last fragment of the route, add it to the + * gpsbabel internal structs now. + */ + if (frag == mag_rte_head->nelems) { + queue *elem, *tmp; + route_head *rte_head; + + rte_head = route_head_alloc(); + route_add_head(rte_head); + rte_head->rte_num = rtenum; + rte_head->rte_name = xstrdup(rte_name); + + /* + * It is quite feasible that we have 200 waypoints, + * 3 of which are used in the route. We'll need to find + * those in the queue for SD routes... + */ + + QUEUE_FOR_EACH(&mag_rte_head->Q, elem, tmp) { + mag_rte_elem *re = (mag_rte_elem *) elem; + waypoint *waypt; + queue *welem, *wtmp; + + /* + * Copy route points from temp wpt queue. + */ + QUEUE_FOR_EACH(&rte_wpt_tmp, welem, wtmp) { + waypt = (waypoint *)welem; + if (strcmp(waypt->shortname, re->wpt_name) == 0) { + waypoint * wpt = waypt_dupe(waypt); + route_add_wpt(rte_head, wpt); + break; + } + } + + dequeue(&re->Q); + xfree(re->wpt_name); + xfree(re->wpt_icon); + xfree(re); + } + xfree(mag_rte_head); + } + if (rte_name) { + xfree(rte_name); + } } const char * mag_find_descr_from_token(const char *token) { - icon_mapping_t *i = icon_mapping; - - if (icon_mapping == NULL) { - return "unknown"; - } - - for (i = icon_mapping; i->token; i++) { - if (token[0] == 0) break; - if (case_ignore_strcmp(token, i->token) == 0) - return i->icon; - } - return icon_mapping[0].icon; + icon_mapping_t *i = icon_mapping; + + if (icon_mapping == NULL) { + return "unknown"; + } + + for (i = icon_mapping; i->token; i++) { + if (token[0] == 0) { + break; + } + if (case_ignore_strcmp(token, i->token) == 0) { + return i->icon; + } + } + return icon_mapping[0].icon; } const char * mag_find_token_from_descr(const char *icon) { - icon_mapping_t *i = icon_mapping; - - if (i == NULL || icon == NULL) { - return "a"; - } - - for (i = icon_mapping; i->token; i++) { - if (case_ignore_strcmp(icon, i->icon) == 0) - return i->token; - } - return icon_mapping[0].token; + icon_mapping_t *i = icon_mapping; + + if (i == NULL || icon == NULL) { + return "a"; + } + + for (i = icon_mapping; i->token; i++) { + if (case_ignore_strcmp(icon, i->icon) == 0) { + return i->token; + } + } + return icon_mapping[0].token; } /* @@ -1167,280 +1199,288 @@ mag_find_token_from_descr(const char *icon) * $PMGNWPL,3549.499,N,08650.827,W,0000257,M,HOME,HOME,c*4D * create and return a populated waypoint. */ -static waypoint * +static waypoint * mag_wptparse(char *trkmsg) { - double latdeg, lngdeg; - char latdir; - char lngdir; - int alt; - char altunits; - char shortname[100]; - char descr[256]; - char icon_token[100]; - waypoint *waypt; - char *icons; - char *icone; - char *blah; - int i = 0; - - descr[0] = 0; - icon_token[0] = 0; - - waypt = waypt_new(); - - sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", - &latdeg,&latdir, - &lngdeg,&lngdir, - &alt,&altunits,shortname,descr); - icone = strrchr(trkmsg, '*'); - icons = strrchr(trkmsg, ',')+1; - - mag_dequote(descr); - - for (blah = icons ; blah < icone; blah++) - icon_token[i++] = *blah; - icon_token[i++] = '\0'; - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - waypt->shortname = xstrdup(shortname); - waypt->description = xstrdup(descr); - waypt->icon_descr = mag_find_descr_from_token(icon_token); - - return waypt; + double latdeg, lngdeg; + char latdir; + char lngdir; + int alt; + char altunits; + char shortname[100]; + char descr[256]; + char icon_token[100]; + waypoint *waypt; + char *icons; + char *icone; + char *blah; + int i = 0; + + descr[0] = 0; + icon_token[0] = 0; + + waypt = waypt_new(); + + sscanf(trkmsg,"$PMGNWPL,%lf,%c,%lf,%c,%d,%c,%[^,],%[^,]", + &latdeg,&latdir, + &lngdeg,&lngdir, + &alt,&altunits,shortname,descr); + icone = strrchr(trkmsg, '*'); + icons = strrchr(trkmsg, ',')+1; + + mag_dequote(descr); + + for (blah = icons ; blah < icone; blah++) { + icon_token[i++] = *blah; + } + icon_token[i++] = '\0'; + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + waypt->shortname = xstrdup(shortname); + waypt->description = xstrdup(descr); + waypt->icon_descr = mag_find_descr_from_token(icon_token); + + return waypt; } static void mag_read(void) { - if (gpx_vec) { - char **f = os_gpx_files(explorist_info->track_path); - while (f && *f) { - gpx_vec->rd_init(*f); - gpx_vec->read(); - f++; - } - - f = os_gpx_files(explorist_info->waypoint_path); - while (f && *f) { - gpx_vec->rd_init(*f); - gpx_vec->read(); - f++; - } + if (gpx_vec) { + char **f = os_gpx_files(explorist_info->track_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } + + f = os_gpx_files(explorist_info->waypoint_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } #if 0 - f = os_gpx_files(explorist_info->geo_path); - while (f && *f) { - gpx_vec->rd_init(*f); - gpx_vec->read(); - f++; - } + f = os_gpx_files(explorist_info->geo_path); + while (f && *f) { + gpx_vec->rd_init(*f); + gpx_vec->read(); + f++; + } #endif - return; - } - - found_done = 0; - if (global_opts.masked_objective & TRKDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) - mag_writemsg("PMGNCMD,TRACK,2"); - - while (!found_done) { - mag_readmsg(trkdata); - } - } - - found_done = 0; - if (global_opts.masked_objective & WPTDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) - mag_writemsg("PMGNCMD,WAYPOINT"); - - while (!found_done) { - mag_readmsg(wptdata); - } - } - - found_done = 0; - if (global_opts.masked_objective & RTEDATAMASK) { - magrxstate = mrs_handoff; - if (!is_file) { - /* - * serial routes require waypoint & routes - * messages commands. - */ - mag_writemsg("PMGNCMD,WAYPOINT"); - - while (!found_done) { - mag_readmsg(rtedata); - } - - mag_writemsg("PMGNCMD,ROUTE"); - - found_done = 0; - while (!found_done) { - mag_readmsg(rtedata); - } - } else { - /* - * SD routes are a stream of PMGNWPL and - * PMGNRTE messages, in that order. - */ - while (!found_done) { - mag_readmsg(rtedata); - } - } - } + return; + } + + found_done = 0; + if (global_opts.masked_objective & TRKDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,TRACK,2"); + } + + while (!found_done) { + mag_readmsg(trkdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & WPTDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + mag_writemsg("PMGNCMD,WAYPOINT"); + } + + while (!found_done) { + mag_readmsg(wptdata); + } + } + + found_done = 0; + if (global_opts.masked_objective & RTEDATAMASK) { + magrxstate = mrs_handoff; + if (!is_file) { + /* + * serial routes require waypoint & routes + * messages commands. + */ + mag_writemsg("PMGNCMD,WAYPOINT"); + + while (!found_done) { + mag_readmsg(rtedata); + } + + mag_writemsg("PMGNCMD,ROUTE"); + + found_done = 0; + while (!found_done) { + mag_readmsg(rtedata); + } + } else { + /* + * SD routes are a stream of PMGNWPL and + * PMGNRTE messages, in that order. + */ + while (!found_done) { + mag_readmsg(rtedata); + } + } + } } static void mag_waypt_pr(const waypoint *waypointp) { - double lon, lat; - double ilon, ilat; - int lon_deg, lat_deg; - char obuf[200]; - char ofmtdesc[200]; - const char *icon_token=NULL; - char *owpt; - char *odesc; - char *isrc = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - if (deficon) { - icon_token = mag_find_token_from_descr(deficon); - } else { - icon_token = mag_find_token_from_descr(waypointp->icon_descr); - } - - if (get_cache_icon(waypointp)) { - icon_token = mag_find_token_from_descr(get_cache_icon(waypointp)); - } - - isrc = waypointp->notes ? waypointp->notes : waypointp->description; - owpt = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname; - odesc = isrc ? isrc : ""; - owpt = mag_cleanse(owpt); - - if (global_opts.smart_icons && - waypointp->gc_data->diff && waypointp->gc_data->terr) { - sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data->diff, - waypointp->gc_data->terr, odesc); - odesc = mag_cleanse(ofmtdesc); - } else { - odesc = mag_cleanse(odesc); - } - - /* - * For the benefit of DirectRoute (which uses waypoint comments - * to deliver turn-by-turn popups for street routing) allow a - * cap on the comments delivered so we leave space for it to route. - */ - if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) - odesc[0] = 0; - - sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude, - wpt_len, - owpt, - odesc, - icon_token); - mag_writemsg(obuf); - xfree(owpt); - xfree(odesc); - - if (!is_file) { - if (mag_error) { - warning( "Protocol error Writing '%s'\n", obuf); - } - } + double lon, lat; + double ilon, ilat; + int lon_deg, lat_deg; + char obuf[200]; + char ofmtdesc[200]; + const char *icon_token=NULL; + char *owpt; + char *odesc; + char *isrc = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + if (deficon) { + icon_token = mag_find_token_from_descr(deficon); + } else { + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + } + + if (get_cache_icon(waypointp)) { + icon_token = mag_find_token_from_descr(get_cache_icon(waypointp)); + } + + isrc = waypointp->notes ? waypointp->notes : waypointp->description; + owpt = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : waypointp->shortname; + odesc = isrc ? isrc : ""; + owpt = mag_cleanse(owpt); + + if (global_opts.smart_icons && + waypointp->gc_data->diff && waypointp->gc_data->terr) { + sprintf(ofmtdesc, "%d/%d %s", waypointp->gc_data->diff, + waypointp->gc_data->terr, odesc); + odesc = mag_cleanse(ofmtdesc); + } else { + odesc = mag_cleanse(odesc); + } + + /* + * For the benefit of DirectRoute (which uses waypoint comments + * to deliver turn-by-turn popups for street routing) allow a + * cap on the comments delivered so we leave space for it to route. + */ + if (odesc && /* !is_file && */ (wptcmtcnt++ >= wptcmtcnt_max)) { + odesc[0] = 0; + } + + sprintf(obuf, "PMGNWPL,%4.3f,%c,%09.3f,%c,%07.0f,M,%-.*s,%-.46s,%s", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + wpt_len, + owpt, + odesc, + icon_token); + mag_writemsg(obuf); + xfree(owpt); + xfree(odesc); + + if (!is_file) { + if (mag_error) { + warning("Protocol error Writing '%s'\n", obuf); + } + } } static void mag_track_nop(const route_head *rte) { - return; + return; } static void mag_track_disp(const waypoint *waypointp) { - double ilon, ilat; - double lon, lat; - int lon_deg, lat_deg; - char obuf[200]; - int hms=0; - int fracsec=0; - int date=0; - struct tm *tm = NULL; - - ilat = waypointp->latitude; - ilon = waypointp->longitude; - tm = NULL; - if (waypointp->creation_time) { - tm = gmtime(&waypointp->creation_time); - if ( tm ) { - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + - tm->tm_sec; - date = tm->tm_mday * 10000 + tm->tm_mon * 100 + - tm->tm_year; - fracsec = MICRO_TO_CENTI(waypointp->microseconds); - } - } - if (!tm) { - date = 0; - fracsec = 0; - } - - lon = fabs(ilon); - lat = fabs(ilat); - - lon_deg = lon; - lat_deg = lat; - - lon = (lon - lon_deg) * 60.0; - lat = (lat - lat_deg) * 60.0; - - lon = (lon_deg * 100.0 + lon); - lat = (lat_deg * 100.0 + lat); - - sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", - lat, ilat < 0 ? 'S' : 'N', - lon, ilon < 0 ? 'W' : 'E', - waypointp->altitude == unknown_alt ? - 0 : waypointp->altitude, - 'M',hms,fracsec,date); - mag_writemsg(obuf); + double ilon, ilat; + double lon, lat; + int lon_deg, lat_deg; + char obuf[200]; + int hms=0; + int fracsec=0; + int date=0; + struct tm *tm = NULL; + + ilat = waypointp->latitude; + ilon = waypointp->longitude; + tm = NULL; + if (waypointp->creation_time) { + tm = gmtime(&waypointp->creation_time); + if (tm) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + + tm->tm_sec; + date = tm->tm_mday * 10000 + tm->tm_mon * 100 + + tm->tm_year; + fracsec = MICRO_TO_CENTI(waypointp->microseconds); + } + } + if (!tm) { + date = 0; + fracsec = 0; + } + + lon = fabs(ilon); + lat = fabs(ilat); + + lon_deg = lon; + lat_deg = lat; + + lon = (lon - lon_deg) * 60.0; + lat = (lat - lat_deg) * 60.0; + + lon = (lon_deg * 100.0 + lon); + lat = (lat_deg * 100.0 + lat); + + sprintf(obuf,"PMGNTRK,%4.3f,%c,%09.3f,%c,%05.0f,%c,%06d.%02d,A,,%06d", + lat, ilat < 0 ? 'S' : 'N', + lon, ilon < 0 ? 'W' : 'E', + waypointp->altitude == unknown_alt ? + 0 : waypointp->altitude, + 'M',hms,fracsec,date); + mag_writemsg(obuf); } static void mag_track_pr() { - track_disp_all(mag_track_nop, mag_track_nop, mag_track_disp); + track_disp_all(mag_track_nop, mag_track_nop, mag_track_disp); } /* @@ -1451,7 +1491,7 @@ Meridian SD card and serial (at least) writes in pairs: $PMGNRTE,4,1,c,1,HOME,c,I49X73,a*15 ... $PMGNRTE,4,4,c,1,RON273,a,MYCF93,a*7B - + The spec also says that some units don't like single-legged pairs, and to replace the 2nd name with "<<>>", but I haven't seen one of those. */ @@ -1459,68 +1499,70 @@ and to replace the 2nd name with "<<>>", but I haven't seen one of those. static void mag_route_trl(const route_head * rte) { - queue *elem, *tmp; - waypoint *waypointp; - char obuff[256]; - char buff1[64], buff2[64]; - char *pbuff, *owpt; - const char * icon_token; - int i, numlines, thisline; - - /* count waypoints for this route */ - i = rte->rte_waypt_ct; - - /* number of output PMGNRTE messages at 2 points per line */ - numlines = (i / 2) + (i % 2); - - /* increment the route counter. */ - route_out_count++; - - thisline = i = 0; - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypointp = (waypoint *) elem; - i++; - - if (deficon) - icon_token = mag_find_token_from_descr(deficon); - else - icon_token = mag_find_token_from_descr(waypointp->icon_descr); - - if (i == 1) - pbuff = buff1; - else - pbuff = buff2; - - owpt = waypointp->shortname; - if (strlen(owpt) > sizeof(buff1) - 3) { - owpt[sizeof(buff1) - 3] = 0; - } - owpt = mag_cleanse(owpt); - - sprintf(pbuff, "%s,%s", owpt, icon_token); - - xfree(owpt); - - if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { - char expbuf[1024]; - thisline++; - expbuf[0] = 0; - if (explorist) { - snprintf(expbuf, sizeof(expbuf), "%s,", - rte->rte_name ? rte->rte_name : ""); - } - sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", - numlines, thisline, - rte->rte_num ? rte->rte_num : route_out_count, - expbuf, - buff1, buff2); - - mag_writemsg(obuff); - buff1[0] = '\0'; - buff2[0] = '\0'; - i = 0; - } - } + queue *elem, *tmp; + waypoint *waypointp; + char obuff[256]; + char buff1[64], buff2[64]; + char *pbuff, *owpt; + const char * icon_token; + int i, numlines, thisline; + + /* count waypoints for this route */ + i = rte->rte_waypt_ct; + + /* number of output PMGNRTE messages at 2 points per line */ + numlines = (i / 2) + (i % 2); + + /* increment the route counter. */ + route_out_count++; + + thisline = i = 0; + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypointp = (waypoint *) elem; + i++; + + if (deficon) { + icon_token = mag_find_token_from_descr(deficon); + } else { + icon_token = mag_find_token_from_descr(waypointp->icon_descr); + } + + if (i == 1) { + pbuff = buff1; + } else { + pbuff = buff2; + } + + owpt = waypointp->shortname; + if (strlen(owpt) > sizeof(buff1) - 3) { + owpt[sizeof(buff1) - 3] = 0; + } + owpt = mag_cleanse(owpt); + + sprintf(pbuff, "%s,%s", owpt, icon_token); + + xfree(owpt); + + if ((tmp == &rte->waypoint_list) || ((i % 2) == 0)) { + char expbuf[1024]; + thisline++; + expbuf[0] = 0; + if (explorist) { + snprintf(expbuf, sizeof(expbuf), "%s,", + rte->rte_name ? rte->rte_name : ""); + } + sprintf(obuff, "PMGNRTE,%d,%d,c,%d,%s%s,%s", + numlines, thisline, + rte->rte_num ? rte->rte_num : route_out_count, + expbuf, + buff1, buff2); + + mag_writemsg(obuff); + buff1[0] = '\0'; + buff2[0] = '\0'; + i = 0; + } + } } static void @@ -1531,8 +1573,8 @@ mag_route_hdr(const route_head *rh) static void mag_route_pr() { - route_out_count = 0; - route_disp_all(mag_route_hdr, mag_route_trl, mag_waypt_pr); + route_out_count = 0; + route_disp_all(mag_route_hdr, mag_route_trl, mag_waypt_pr); } @@ -1540,33 +1582,32 @@ static void mag_write(void) { - wptcmtcnt = 0; - - switch (global_opts.objective) - { - case trkdata: - mag_track_pr(); - break; - case wptdata: - waypt_disp_all(mag_waypt_pr); - break; - case rtedata: - mag_route_pr(); - break; - default: - fatal(MYNAME ": Unknown objective.\n"); - } + wptcmtcnt = 0; + + switch (global_opts.objective) { + case trkdata: + mag_track_pr(); + break; + case wptdata: + waypt_disp_all(mag_waypt_pr); + break; + case rtedata: + mag_route_pr(); + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } } const char ** os_get_magellan_mountpoints() { #if __APPLE__ - const char **dlist = xcalloc(2, sizeof *dlist); - dlist[0] = xstrdup("/Volumes/Magellan"); - dlist[1] = NULL; - return dlist; + const char **dlist = xcalloc(2, sizeof *dlist); + dlist[0] = xstrdup("/Volumes/Magellan"); + dlist[1] = NULL; + return dlist; #else - fatal("Not implemented"); + fatal("Not implemented"); #endif } @@ -1576,14 +1617,14 @@ static char ** os_gpx_files(const char *dirname) { #if HAVE_GLOB - static glob_t g; - char *path; - xasprintf(&path, "%s/*.gpx", dirname); - glob(path, 0, NULL, &g); - xfree(path); - return g.gl_pathv; + static glob_t g; + char *path; + xasprintf(&path, "%s/*.gpx", dirname); + glob(path, 0, NULL, &g); + xfree(path); + return g.gl_pathv; #else - fatal("Not implemented"); + fatal("Not implemented"); #endif } @@ -1592,46 +1633,46 @@ os_gpx_files(const char *dirname) * for the benefit of GUI wrappers. */ ff_vecs_t mag_svecs = { - ff_type_serial, - FF_CAP_RW_ALL, - mag_rd_init, - mag_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_sargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_serial, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_sargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; ff_vecs_t mag_fvecs = { - ff_type_file, - FF_CAP_RW_ALL, - mag_rd_init, - mag_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_fargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mag_rd_init, + mag_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; /* * Extended (Explorist) entry tables. */ ff_vecs_t magX_fvecs = { - ff_type_file, - FF_CAP_RW_ALL, - magX_rd_init, - magX_wr_init, - mag_deinit, - mag_deinit, - mag_read, - mag_write, - NULL, - mag_fargs, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + magX_rd_init, + magX_wr_init, + mag_deinit, + mag_deinit, + mag_read, + mag_write, + NULL, + mag_fargs, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/main.c b/gpsbabel/main.c index ff3115f24..552655f06 100644 --- a/gpsbabel/main.c +++ b/gpsbabel/main.c @@ -33,690 +33,709 @@ void signal_handler(int sig); typedef struct arg_stack_s { - int argn; - int argc; - char **argv; - struct arg_stack_s *prev; + int argn; + int argc; + char **argv; + struct arg_stack_s *prev; } arg_stack_t; static arg_stack_t *push_args(arg_stack_t *stack, const int argn, const int argc, char *argv[]) { - arg_stack_t *res = (arg_stack_t *) xmalloc(sizeof(*res)); - - res->prev = stack; - res->argn = argn; - res->argc = argc; - res->argv = (char **)argv; - - return res; + arg_stack_t *res = (arg_stack_t *) xmalloc(sizeof(*res)); + + res->prev = stack; + res->argn = argn; + res->argc = argc; + res->argv = (char **)argv; + + return res; } static arg_stack_t *pop_args(arg_stack_t *stack, int *argn, int *argc, char **argv[]) { - arg_stack_t *res; - char **argv2 = *argv; - int i; - - if (stack == NULL) fatal("main: Invalid point in time to call 'pop_args'\n"); - - for (i = 0; i < *argc; i++) - xfree(argv2[i]); - xfree(*argv); - - *argn = stack->argn; - *argc = stack->argc; - *argv = stack->argv; - - res = stack->prev; - xfree(stack); - - return res; + arg_stack_t *res; + char **argv2 = *argv; + int i; + + if (stack == NULL) { + fatal("main: Invalid point in time to call 'pop_args'\n"); + } + + for (i = 0; i < *argc; i++) { + xfree(argv2[i]); + } + xfree(*argv); + + *argn = stack->argn; + *argc = stack->argc; + *argv = stack->argv; + + res = stack->prev; + xfree(stack); + + return res; } static void load_args(const char *filename, int *argc, char **argv[]) { - gbfile *fin; - char *str, *line = NULL; - int argc2; - char **argv2; - - fin = gbfopen(filename, "r", "main"); - while ((str = gbfgetstr(fin))) { - str = lrtrim(str); - if ((*str == '\0') || (*str == '#')) continue; - - if (line == NULL) line = xstrdup(str); - else { - char *tmp; - xasprintf(&tmp, "%s %s", line, str); - xfree(line); - line = tmp; - } - } - gbfclose(fin); - - argv2 = (char **) xmalloc(2 * sizeof(*argv2)); - argv2[0] = xstrdup(*argv[0]); - argc2 = 1; - - str = csv_lineparse(line, " ", "\"", 0); - while (str != NULL) { - argv2 = (char **) xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); - argv2[argc2] = xstrdup(str); - argc2++; - str = csv_lineparse(NULL, " ", "\"", 0); - } - xfree(line); - - argv2[argc2] = NULL; - - *argc = argc2; - *argv = argv2; + gbfile *fin; + char *str, *line = NULL; + int argc2; + char **argv2; + + fin = gbfopen(filename, "r", "main"); + while ((str = gbfgetstr(fin))) { + str = lrtrim(str); + if ((*str == '\0') || (*str == '#')) { + continue; + } + + if (line == NULL) { + line = xstrdup(str); + } else { + char *tmp; + xasprintf(&tmp, "%s %s", line, str); + xfree(line); + line = tmp; + } + } + gbfclose(fin); + + argv2 = (char **) xmalloc(2 * sizeof(*argv2)); + argv2[0] = xstrdup(*argv[0]); + argc2 = 1; + + str = csv_lineparse(line, " ", "\"", 0); + while (str != NULL) { + argv2 = (char **) xrealloc(argv2, (argc2 + 2) * sizeof(*argv2)); + argv2[argc2] = xstrdup(str); + argc2++; + str = csv_lineparse(NULL, " ", "\"", 0); + } + xfree(line); + + argv2[argc2] = NULL; + + *argc = argc2; + *argv = argv2; } static void -usage(const char *pname, int shorter ) +usage(const char *pname, int shorter) { - printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", - gpsbabel_version ); - printf( -"Usage:\n" -" %s [options] -i INTYPE -f INFILE [filter] -o OUTTYPE -F OUTFILE\n" -" %s [options] -i INTYPE -o OUTTYPE INFILE [filter] OUTFILE\n" -"\n" -" Converts GPS route and waypoint data from one format type to another.\n" -" The input type and filename are specified with the -i INTYPE\n" -" and -f INFILE options. The output type and filename are specified\n" -" with the -o OUTTYPE and -F OUTFILE options.\n" -" If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n" -"\n" -" In the second form of the command, INFILE and OUTFILE are the\n" -" first and second positional (non-option) arguments.\n" -"\n" -" INTYPE and OUTTYPE must be one of the supported file types and\n" -" may include options valid for that file type. For example:\n" -" 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" -" (without the quotes) are all valid file type specifications.\n" -"\n" -"Options:\n" -" -p Preferences file (gpsbabel.ini)\n" -" -s Synthesize shortnames\n" -" -r Process route information\n" -" -t Process track information\n" -" -T Process realtime tracking information\n" -" -w Process waypoint information [default]\n" -" -b Process command file (batch mode)\n" -" -c Character set for next operation\n" -" -N No smart icons on output\n" -" -x filtername Invoke filter (placed between inputs and output) \n" -" -D level Set debug level [%d]\n" -" -l Print GPSBabel builtin character sets and exit\n" -" -h, -? Print detailed help and exit\n" -" -V Print GPSBabel version and exit\n" -"\n" - , pname - , pname - , global_opts.debug_level - ); - if ( shorter ) { - printf( "\n\n[Press enter]" ); - fgetc(stdin); - } - else { - printf("File Types (-i and -o options):\n"); - disp_vecs(); - printf("\nSupported data filters:\n"); - disp_filter_vecs(); - } + printf("GPSBabel Version %s. http://www.gpsbabel.org\n\n", + gpsbabel_version); + printf( + "Usage:\n" + " %s [options] -i INTYPE -f INFILE [filter] -o OUTTYPE -F OUTFILE\n" + " %s [options] -i INTYPE -o OUTTYPE INFILE [filter] OUTFILE\n" + "\n" + " Converts GPS route and waypoint data from one format type to another.\n" + " The input type and filename are specified with the -i INTYPE\n" + " and -f INFILE options. The output type and filename are specified\n" + " with the -o OUTTYPE and -F OUTFILE options.\n" + " If '-' is used for INFILE or OUTFILE, stdin or stdout will be used.\n" + "\n" + " In the second form of the command, INFILE and OUTFILE are the\n" + " first and second positional (non-option) arguments.\n" + "\n" + " INTYPE and OUTTYPE must be one of the supported file types and\n" + " may include options valid for that file type. For example:\n" + " 'gpx', 'gpx,snlen=10' and 'ozi,snlen=10,snwhite=1'\n" + " (without the quotes) are all valid file type specifications.\n" + "\n" + "Options:\n" + " -p Preferences file (gpsbabel.ini)\n" + " -s Synthesize shortnames\n" + " -r Process route information\n" + " -t Process track information\n" + " -T Process realtime tracking information\n" + " -w Process waypoint information [default]\n" + " -b Process command file (batch mode)\n" + " -c Character set for next operation\n" + " -N No smart icons on output\n" + " -x filtername Invoke filter (placed between inputs and output) \n" + " -D level Set debug level [%d]\n" + " -l Print GPSBabel builtin character sets and exit\n" + " -h, -? Print detailed help and exit\n" + " -V Print GPSBabel version and exit\n" + "\n" + , pname + , pname + , global_opts.debug_level + ); + if (shorter) { + printf("\n\n[Press enter]"); + fgetc(stdin); + } else { + printf("File Types (-i and -o options):\n"); + disp_vecs(); + printf("\nSupported data filters:\n"); + disp_filter_vecs(); + } } -static void -spec_usage( const char *vec ) { - printf( "\n" ); - disp_vec( vec ); - disp_filter_vec ( vec ); - printf( "\n" ); +static void +spec_usage(const char *vec) +{ + printf("\n"); + disp_vec(vec); + disp_filter_vec(vec); + printf("\n"); } static void print_extended_info(void) { - printf( + printf( #if !ZLIB_INHIBITED /* Note polarity inverted here */ - "ZLIB_ENABLED " + "ZLIB_ENABLED " #endif #if FILTERS_ENABLED - "FILTERS_ENABLED " + "FILTERS_ENABLED " #endif #if CSVFMTS_ENABLED - "CSVFMTS_ENABLED " + "CSVFMTS_ENABLED " #endif -#if PDBFMTS_ENABLED - "PDBFMTS_ENABLED " +#if PDBFMTS_ENABLED + "PDBFMTS_ENABLED " #endif -#if SHAPELIB_ENABLED - "SHAPELIB_ENABLED " +#if SHAPELIB_ENABLED + "SHAPELIB_ENABLED " #endif #if HAVE_LIBEXPAT - "HAVE_LIBEXPAT " + "HAVE_LIBEXPAT " #if defined(XML_UNICODE) - "XML_UNICODE " + "XML_UNICODE " #endif #endif -#if defined CET_WANTED - "CET_ENABLED " +#if defined CET_WANTED + "CET_ENABLED " #endif - "\n"); + "\n"); } int main(int argc, char *argv[]) { - int c; - int argn; - ff_vecs_t *ivecs = NULL; - ff_vecs_t *ovecs = NULL; - filter_vecs_t *fvecs = NULL; - char *fname = NULL; - char *ofname = NULL; - char *ivec_opts = NULL; - char *ovec_opts = NULL; - char *fvec_opts = NULL; - int opt_version = 0; - int did_something = 0; - const char *prog_name = argv[0]; /* argv is modified during processing */ - queue *wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ - signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ - arg_stack_t *arg_stack = NULL; - - global_opts.objective = wptdata; - global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ - global_opts.charset = NULL; - global_opts.charset_name = NULL; - global_opts.inifile = NULL; - - gpsbabel_now = time(NULL); /* gpsbabel startup-time */ - gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ - + int c; + int argn; + ff_vecs_t *ivecs = NULL; + ff_vecs_t *ovecs = NULL; + filter_vecs_t *fvecs = NULL; + char *fname = NULL; + char *ofname = NULL; + char *ivec_opts = NULL; + char *ovec_opts = NULL; + char *fvec_opts = NULL; + int opt_version = 0; + int did_something = 0; + const char *prog_name = argv[0]; /* argv is modified during processing */ + queue *wpt_head_bak, *rte_head_bak, *trk_head_bak; /* #ifdef UTF8_SUPPORT */ + signed int wpt_ct_bak, rte_ct_bak, trk_ct_bak; /* #ifdef UTF8_SUPPORT */ + arg_stack_t *arg_stack = NULL; + + global_opts.objective = wptdata; + global_opts.masked_objective = NOTHINGMASK; /* this makes the default mask behaviour slightly different */ + global_opts.charset = NULL; + global_opts.charset_name = NULL; + global_opts.inifile = NULL; + + gpsbabel_now = time(NULL); /* gpsbabel startup-time */ + gpsbabel_time = current_time(); /* same like gpsbabel_now, but freezed to zero during testo */ + #ifdef DEBUG_MEM - debug_mem_open(); - debug_mem_output( "command line: " ); - for ( argn = 1; argn < argc; argn++ ) { - debug_mem_output( "%s ", argv[argn] ); - } - debug_mem_output( "\n" ); + debug_mem_open(); + debug_mem_output("command line: "); + for (argn = 1; argn < argc; argn++) { + debug_mem_output("%s ", argv[argn]); + } + debug_mem_output("\n"); #endif - if (gpsbabel_time != 0) { /* within testo ? */ - global_opts.inifile = inifile_init(NULL, MYNAME); - } - - init_vecs(); - init_filter_vecs(); - cet_register(); - session_init(); - waypt_init(); - route_init(); - - if ( argc < 2 ) { - usage(argv[0],1); - exit(0); - } - - /* - * Open-code getopts since POSIX-impaired OSes don't have one. - */ - argn = 1; - while (argn < argc) { - char *optarg; - - if (argv[argn][0] != '-') { - break; - } - if (argv[argn][1] == '-') { - break; - } - - if (argv[argn][1] == 'V' ) { - printf("\nGPSBabel Version %s\n\n", gpsbabel_version ); - if (argv[argn][2] == 'V') { - print_extended_info(); - } - exit(0); - } - - if (argv[argn][1] == '?' || argv[argn][1] == 'h') { - if ( argn < argc-1 ) { - spec_usage( argv[argn+1] ); - } - else { - usage(argv[0],0); - } - exit(0); - } - - c = argv[argn][1]; - - if (argv[argn][2]) { - opt_version = atoi(&argv[argn][2]); - } - - switch (c) { - case 'c': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - cet_convert_init(optarg, 1); - break; - case 'i': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ivecs = find_vec(optarg, &ivec_opts); - if (ivecs == NULL) { - fatal ("Input type '%s' not recognized\n", optarg); - } - break; - case 'o': - if (ivecs == NULL) { - warning ("-o appeared before -i. This is probably not what you want to do.\n"); - } - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ovecs = find_vec(optarg, &ovec_opts); - if (ovecs == NULL) { - fatal ("Output type '%s' not recognized\n", optarg); - } - break; - case 'f': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - fname = optarg; - if (fname == NULL) { - fatal ("No file or device name specified.\n"); - } - if (ivecs == NULL) { - fatal ("No valid input type specified\n"); - } - if (ivecs->rd_init == NULL) { - fatal ("Format does not support reading.\n"); - } - if (global_opts.masked_objective & POSNDATAMASK) { - did_something = 1; - break; - } - /* simulates the default behaviour of waypoints */ - if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; - - cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ - - start_session(ivecs->name, fname); - ivecs->rd_init(fname); - ivecs->read(); - ivecs->rd_deinit(); - - cet_convert_strings(global_opts.charset, NULL, NULL); - cet_convert_deinit(); - - did_something = 1; - break; - case 'F': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - ofname = optarg; - if (ofname == NULL) { - fatal ("No output file or device name specified.\n"); - } - if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { - /* simulates the default behaviour of waypoints */ - if (doing_nothing) - global_opts.masked_objective |= WPTDATAMASK; - if (ovecs->wr_init == NULL) { - fatal ("Format does not support writing.\n"); - } - - cet_convert_init(ovecs->encode, ovecs->fixed_encode); - - wpt_ct_bak = -1; - rte_ct_bak = -1; - trk_ct_bak = -1; - rte_head_bak = trk_head_bak = NULL; - - ovecs->wr_init(ofname); - - if (global_opts.charset != &cet_cs_vec_utf8) - { - /* - * Push and pop verbose_status so - * we don't get dual progress bars - * when doing characterset - * transformation. - */ - int saved_status = global_opts.verbose_status; - global_opts.verbose_status = 0; - waypt_backup(&wpt_ct_bak, &wpt_head_bak); - route_backup(&rte_ct_bak, &rte_head_bak); - track_backup(&trk_ct_bak, &trk_head_bak); - - cet_convert_strings(NULL, global_opts.charset, NULL); - global_opts.verbose_status = saved_status; - } - - ovecs->write(); - ovecs->wr_deinit(); - - cet_convert_deinit(); - - if (wpt_ct_bak != -1) waypt_restore(wpt_ct_bak, wpt_head_bak); - if (rte_ct_bak != -1) { - route_restore( rte_head_bak); - xfree( rte_head_bak ); - } - if (trk_ct_bak != -1) { - track_restore( trk_head_bak); - xfree( trk_head_bak ); - } - } - break; - case 's': - global_opts.synthesize_shortnames = 1; - break; - case 't': - global_opts.objective = trkdata; - global_opts.masked_objective |= TRKDATAMASK; - break; - case 'w': - global_opts.objective = wptdata; - global_opts.masked_objective |= WPTDATAMASK; - break; - case 'r': - global_opts.objective = rtedata; - global_opts.masked_objective |= RTEDATAMASK; - break; - case 'T': - global_opts.objective = posndata; - global_opts.masked_objective |= POSNDATAMASK; - break; - case 'N': + if (gpsbabel_time != 0) { /* within testo ? */ + global_opts.inifile = inifile_init(NULL, MYNAME); + } + + init_vecs(); + init_filter_vecs(); + cet_register(); + session_init(); + waypt_init(); + route_init(); + + if (argc < 2) { + usage(argv[0],1); + exit(0); + } + + /* + * Open-code getopts since POSIX-impaired OSes don't have one. + */ + argn = 1; + while (argn < argc) { + char *optarg; + + if (argv[argn][0] != '-') { + break; + } + if (argv[argn][1] == '-') { + break; + } + + if (argv[argn][1] == 'V') { + printf("\nGPSBabel Version %s\n\n", gpsbabel_version); + if (argv[argn][2] == 'V') { + print_extended_info(); + } + exit(0); + } + + if (argv[argn][1] == '?' || argv[argn][1] == 'h') { + if (argn < argc-1) { + spec_usage(argv[argn+1]); + } else { + usage(argv[0],0); + } + exit(0); + } + + c = argv[argn][1]; + + if (argv[argn][2]) { + opt_version = atoi(&argv[argn][2]); + } + + switch (c) { + case 'c': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + cet_convert_init(optarg, 1); + break; + case 'i': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ivecs = find_vec(optarg, &ivec_opts); + if (ivecs == NULL) { + fatal("Input type '%s' not recognized\n", optarg); + } + break; + case 'o': + if (ivecs == NULL) { + warning("-o appeared before -i. This is probably not what you want to do.\n"); + } + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ovecs = find_vec(optarg, &ovec_opts); + if (ovecs == NULL) { + fatal("Output type '%s' not recognized\n", optarg); + } + break; + case 'f': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fname = optarg; + if (fname == NULL) { + fatal("No file or device name specified.\n"); + } + if (ivecs == NULL) { + fatal("No valid input type specified\n"); + } + if (ivecs->rd_init == NULL) { + fatal("Format does not support reading.\n"); + } + if (global_opts.masked_objective & POSNDATAMASK) { + did_something = 1; + break; + } + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + + cet_convert_init(ivecs->encode, ivecs->fixed_encode); /* init by module vec */ + + start_session(ivecs->name, fname); + ivecs->rd_init(fname); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + did_something = 1; + break; + case 'F': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + ofname = optarg; + if (ofname == NULL) { + fatal("No output file or device name specified.\n"); + } + if (ovecs && (!(global_opts.masked_objective & POSNDATAMASK))) { + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + if (ovecs->wr_init == NULL) { + fatal("Format does not support writing.\n"); + } + + cet_convert_init(ovecs->encode, ovecs->fixed_encode); + + wpt_ct_bak = -1; + rte_ct_bak = -1; + trk_ct_bak = -1; + rte_head_bak = trk_head_bak = NULL; + + ovecs->wr_init(ofname); + + if (global_opts.charset != &cet_cs_vec_utf8) { + /* + * Push and pop verbose_status so + * we don't get dual progress bars + * when doing characterset + * transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + waypt_backup(&wpt_ct_bak, &wpt_head_bak); + route_backup(&rte_ct_bak, &rte_head_bak); + track_backup(&trk_ct_bak, &trk_head_bak); + + cet_convert_strings(NULL, global_opts.charset, NULL); + global_opts.verbose_status = saved_status; + } + + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + + if (wpt_ct_bak != -1) { + waypt_restore(wpt_ct_bak, wpt_head_bak); + } + if (rte_ct_bak != -1) { + route_restore(rte_head_bak); + xfree(rte_head_bak); + } + if (trk_ct_bak != -1) { + track_restore(trk_head_bak); + xfree(trk_head_bak); + } + } + break; + case 's': + global_opts.synthesize_shortnames = 1; + break; + case 't': + global_opts.objective = trkdata; + global_opts.masked_objective |= TRKDATAMASK; + break; + case 'w': + global_opts.objective = wptdata; + global_opts.masked_objective |= WPTDATAMASK; + break; + case 'r': + global_opts.objective = rtedata; + global_opts.masked_objective |= RTEDATAMASK; + break; + case 'T': + global_opts.objective = posndata; + global_opts.masked_objective |= POSNDATAMASK; + break; + case 'N': #if 0 -/* This option is silently eaten for compatibilty. -N is now the - * default. If you want the old behaviour, -S allows you to individually - * turn them on. The -N option will be removed in 2008. - */ - - switch(argv[argn][2]) { - case 'i': - global_opts.no_smart_icons = 1; - break; - case 'n': - global_opts.no_smart_names = 1; - break; - default: - global_opts.no_smart_names = 1; - global_opts.no_smart_icons = 1; - break; - } + /* This option is silently eaten for compatibilty. -N is now the + * default. If you want the old behaviour, -S allows you to individually + * turn them on. The -N option will be removed in 2008. + */ + + switch (argv[argn][2]) { + case 'i': + global_opts.no_smart_icons = 1; + break; + case 'n': + global_opts.no_smart_names = 1; + break; + default: + global_opts.no_smart_names = 1; + global_opts.no_smart_icons = 1; + break; + } #endif - - break; - case 'S': - switch(argv[argn][2]) { - case 'i': - global_opts.smart_icons = 1; - break; - case 'n': - global_opts.smart_names = 1; - break; - default: - global_opts.smart_icons = 1; - global_opts.smart_names = 1; - break; - } - break; - case 'x': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - fvecs = find_filter_vec(optarg, &fvec_opts); - - if (fvecs) { - if (fvecs->f_init) fvecs->f_init(fvec_opts); - fvecs->f_process(); - if (fvecs->f_deinit) fvecs->f_deinit(); - free_filter_vec(fvecs); - } else { - fatal("Unknown filter '%s'\n",optarg); - } - break; - case 'D': - optarg = argv[argn][2] - ? argv[argn]+2 : argv[++argn]; - global_opts.debug_level = atoi(optarg); - /* - * When debugging, announce version. - */ - if (global_opts.debug_level > 0) { - warning("GPSBabel Version: %s \n", gpsbabel_version ); - } - - break; - /* - * Undocumented '-vs' option for GUI wrappers. - */ - case 'v': - switch(argv[argn][2]) { - case 's': global_opts.verbose_status = 1; break; - case 'S': global_opts.verbose_status = 2; break; - } - break; - - /* - * DOS-derived systems will need to escape - * this as -^^. - */ - case '^': - disp_formats(opt_version); - exit(0); - case '%': - disp_filters(opt_version); - exit(0); - case 'h': - case '?': - usage(argv[0],0); - exit(0); - case 'l': - cet_disp_character_set_names(stdout); - exit(0); - case 'p': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - inifile_done(global_opts.inifile); - if (!optarg || strcmp(optarg, "") == 0) /* from GUI to preserve inconsistent options */ - global_opts.inifile = NULL; - else - global_opts.inifile = inifile_init(optarg, MYNAME); - break; - case 'b': - optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; - arg_stack = push_args(arg_stack, argn, argc, argv); - load_args(optarg, &argc, &argv); - if (argc == 0) - arg_stack = pop_args(arg_stack, &argn, &argc, &argv); - else - argn = 0; - break; - - default: - fatal("Unknown option '%s'.\n", argv[argn]); - break; - } - - if ((argn+1 >= argc) && (arg_stack != NULL)) - arg_stack = pop_args(arg_stack, &argn, &argc, &argv); - argn++; - } - - /* - * Allow input and output files to be specified positionally - * as well. This is the typical command line format. - */ - argc -= argn; - argv += argn; - if (argc > 2) { - fatal ("Extra arguments on command line\n"); - } - else if (argc && ivecs) { - did_something = 1; - /* simulates the default behaviour of waypoints */ - if (doing_nothing) global_opts.masked_objective |= WPTDATAMASK; - - cet_convert_init(ivecs->encode, 1); - - start_session(ivecs->name, argv[0]); - if (ivecs->rd_init == NULL) { - fatal ("Format does not support reading.\n"); - } - ivecs->rd_init(argv[0]); - ivecs->read(); - ivecs->rd_deinit(); - - cet_convert_strings(global_opts.charset, NULL, NULL); - cet_convert_deinit(); - - if (argc == 2 && ovecs) - { - cet_convert_init(ovecs->encode, 1); - cet_convert_strings(NULL, global_opts.charset, NULL); - - if (ovecs->wr_init == NULL) { - fatal ("Format does not support writing.\n"); - } - - ovecs->wr_init(argv[1]); - ovecs->write(); - ovecs->wr_deinit(); - - cet_convert_deinit(); - } - } - else if (argc) { - usage(prog_name,0); - exit(0); - } - if (ovecs == NULL) - { - /* - * Push and pop verbose_status so we don't get dual - * progress bars when doing characterset transformation. - */ - int saved_status = global_opts.verbose_status; - global_opts.verbose_status = 0; - cet_convert_init(CET_CHARSET_ASCII, 1); - cet_convert_strings(NULL, global_opts.charset, NULL); - waypt_disp_all(waypt_disp); - global_opts.verbose_status = saved_status; - } - - /* - * This is very unlike the rest of our command sequence. - * If we're doing realtime position tracking, we enforce that - * we're not doing anything else and we just bounce between - * the special "read position" and "write position" vectors - * in our most recent vecs. - */ - if (global_opts.masked_objective & POSNDATAMASK) { - - if (!ivecs) { - fatal("Realtime tracking (-T) requires an input type (-t)i such as Garmin or NMEA.\n"); - } - - if (!ivecs->position_ops.rd_position) { - fatal("Realtime tracking (-T) is not suppored by this input type.\n"); - } - - - if (ivecs->position_ops.rd_init) { - if (!fname) { - fatal("An input file (-f) must be specified.\n"); - } - start_session(ivecs->name, fname); - ivecs->position_ops.rd_init(fname); - } - - if (global_opts.masked_objective & ~POSNDATAMASK) { - fatal("Realtime tracking (-T) is exclusive of other modes.\n"); - } - - if (ovecs) { - if ( !ovecs->position_ops.wr_position ) { - fatal ("This output format does not support output of realtime positioning.\n"); - } - } - - if (signal(SIGINT, signal_handler) == SIG_ERR) { - fatal ("Couldn't install the exit signal handler.\n"); - } - - if (ovecs && ovecs->position_ops.wr_init) { - ovecs->position_ops.wr_init(ofname); - } - - tracking_status.request_terminate = 0; - while (!tracking_status.request_terminate) { - waypoint *wpt; - - wpt = ivecs->position_ops.rd_position(&tracking_status); - - if (tracking_status.request_terminate) { - if (wpt) { - waypt_free(wpt); - } - break; - } - if (wpt) { - if (ovecs) { + + break; + case 'S': + switch (argv[argn][2]) { + case 'i': + global_opts.smart_icons = 1; + break; + case 'n': + global_opts.smart_names = 1; + break; + default: + global_opts.smart_icons = 1; + global_opts.smart_names = 1; + break; + } + break; + case 'x': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + fvecs = find_filter_vec(optarg, &fvec_opts); + + if (fvecs) { + if (fvecs->f_init) { + fvecs->f_init(fvec_opts); + } + fvecs->f_process(); + if (fvecs->f_deinit) { + fvecs->f_deinit(); + } + free_filter_vec(fvecs); + } else { + fatal("Unknown filter '%s'\n",optarg); + } + break; + case 'D': + optarg = argv[argn][2] + ? argv[argn]+2 : argv[++argn]; + global_opts.debug_level = atoi(optarg); + /* + * When debugging, announce version. + */ + if (global_opts.debug_level > 0) { + warning("GPSBabel Version: %s \n", gpsbabel_version); + } + + break; + /* + * Undocumented '-vs' option for GUI wrappers. + */ + case 'v': + switch (argv[argn][2]) { + case 's': + global_opts.verbose_status = 1; + break; + case 'S': + global_opts.verbose_status = 2; + break; + } + break; + + /* + * DOS-derived systems will need to escape + * this as -^^. + */ + case '^': + disp_formats(opt_version); + exit(0); + case '%': + disp_filters(opt_version); + exit(0); + case 'h': + case '?': + usage(argv[0],0); + exit(0); + case 'l': + cet_disp_character_set_names(stdout); + exit(0); + case 'p': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + inifile_done(global_opts.inifile); + if (!optarg || strcmp(optarg, "") == 0) { /* from GUI to preserve inconsistent options */ + global_opts.inifile = NULL; + } else { + global_opts.inifile = inifile_init(optarg, MYNAME); + } + break; + case 'b': + optarg = argv[argn][2] ? argv[argn]+2 : argv[++argn]; + arg_stack = push_args(arg_stack, argn, argc, argv); + load_args(optarg, &argc, &argv); + if (argc == 0) { + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + } else { + argn = 0; + } + break; + + default: + fatal("Unknown option '%s'.\n", argv[argn]); + break; + } + + if ((argn+1 >= argc) && (arg_stack != NULL)) { + arg_stack = pop_args(arg_stack, &argn, &argc, &argv); + } + argn++; + } + + /* + * Allow input and output files to be specified positionally + * as well. This is the typical command line format. + */ + argc -= argn; + argv += argn; + if (argc > 2) { + fatal("Extra arguments on command line\n"); + } else if (argc && ivecs) { + did_something = 1; + /* simulates the default behaviour of waypoints */ + if (doing_nothing) { + global_opts.masked_objective |= WPTDATAMASK; + } + + cet_convert_init(ivecs->encode, 1); + + start_session(ivecs->name, argv[0]); + if (ivecs->rd_init == NULL) { + fatal("Format does not support reading.\n"); + } + ivecs->rd_init(argv[0]); + ivecs->read(); + ivecs->rd_deinit(); + + cet_convert_strings(global_opts.charset, NULL, NULL); + cet_convert_deinit(); + + if (argc == 2 && ovecs) { + cet_convert_init(ovecs->encode, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + + if (ovecs->wr_init == NULL) { + fatal("Format does not support writing.\n"); + } + + ovecs->wr_init(argv[1]); + ovecs->write(); + ovecs->wr_deinit(); + + cet_convert_deinit(); + } + } else if (argc) { + usage(prog_name,0); + exit(0); + } + if (ovecs == NULL) { + /* + * Push and pop verbose_status so we don't get dual + * progress bars when doing characterset transformation. + */ + int saved_status = global_opts.verbose_status; + global_opts.verbose_status = 0; + cet_convert_init(CET_CHARSET_ASCII, 1); + cet_convert_strings(NULL, global_opts.charset, NULL); + waypt_disp_all(waypt_disp); + global_opts.verbose_status = saved_status; + } + + /* + * This is very unlike the rest of our command sequence. + * If we're doing realtime position tracking, we enforce that + * we're not doing anything else and we just bounce between + * the special "read position" and "write position" vectors + * in our most recent vecs. + */ + if (global_opts.masked_objective & POSNDATAMASK) { + + if (!ivecs) { + fatal("Realtime tracking (-T) requires an input type (-t)i such as Garmin or NMEA.\n"); + } + + if (!ivecs->position_ops.rd_position) { + fatal("Realtime tracking (-T) is not suppored by this input type.\n"); + } + + + if (ivecs->position_ops.rd_init) { + if (!fname) { + fatal("An input file (-f) must be specified.\n"); + } + start_session(ivecs->name, fname); + ivecs->position_ops.rd_init(fname); + } + + if (global_opts.masked_objective & ~POSNDATAMASK) { + fatal("Realtime tracking (-T) is exclusive of other modes.\n"); + } + + if (ovecs) { + if (!ovecs->position_ops.wr_position) { + fatal("This output format does not support output of realtime positioning.\n"); + } + } + + if (signal(SIGINT, signal_handler) == SIG_ERR) { + fatal("Couldn't install the exit signal handler.\n"); + } + + if (ovecs && ovecs->position_ops.wr_init) { + ovecs->position_ops.wr_init(ofname); + } + + tracking_status.request_terminate = 0; + while (!tracking_status.request_terminate) { + waypoint *wpt; + + wpt = ivecs->position_ops.rd_position(&tracking_status); + + if (tracking_status.request_terminate) { + if (wpt) { + waypt_free(wpt); + } + break; + } + if (wpt) { + if (ovecs) { // ovecs->position_ops.wr_init(ofname); - ovecs->position_ops.wr_position(wpt); + ovecs->position_ops.wr_position(wpt); // ovecs->position_ops.wr_deinit(); - } else { - /* Just print to screen */ - waypt_disp(wpt); - } - waypt_free(wpt); - } - } - if (ivecs->position_ops.rd_deinit) { - ivecs->position_ops.rd_deinit(); - } - if (ovecs && ovecs->position_ops.wr_deinit) { - ovecs->position_ops.wr_deinit(); - } - exit(0); - } - - - if (!did_something) - fatal ("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); - - cet_deregister(); - waypt_flush_all(); - route_flush_all(); - session_exit(); - exit_vecs(); - exit_filter_vecs(); - inifile_done(global_opts.inifile); + } else { + /* Just print to screen */ + waypt_disp(wpt); + } + waypt_free(wpt); + } + } + if (ivecs->position_ops.rd_deinit) { + ivecs->position_ops.rd_deinit(); + } + if (ovecs && ovecs->position_ops.wr_deinit) { + ovecs->position_ops.wr_deinit(); + } + exit(0); + } + + + if (!did_something) { + fatal("Nothing to do! Use '%s -h' for command-line options.\n", prog_name); + } + + cet_deregister(); + waypt_flush_all(); + route_flush_all(); + session_exit(); + exit_vecs(); + exit_filter_vecs(); + inifile_done(global_opts.inifile); #ifdef DEBUG_MEM - debug_mem_close(); + debug_mem_close(); #endif - exit(0); + exit(0); } void signal_handler(int sig) { - tracking_status.request_terminate = 1; + tracking_status.request_terminate = 1; } diff --git a/gpsbabel/mapasia.c b/gpsbabel/mapasia.c index 58d04bbfe..cdbd6c85e 100644 --- a/gpsbabel/mapasia.c +++ b/gpsbabel/mapasia.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include #include #include @@ -54,7 +54,7 @@ struct tm tmref; static arglist_t tr7_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -64,134 +64,147 @@ arglist_t tr7_args[] = { static void tr7_rd_init(const char *fname) { - fin = gbfopen_le(fname, "rb", MYNAME); - tmref = *gmtime(&gpsbabel_now); - tmref.tm_year += 1900; - tmref.tm_mon += 1; + fin = gbfopen_le(fname, "rb", MYNAME); + tmref = *gmtime(&gpsbabel_now); + tmref.tm_year += 1900; + tmref.tm_mon += 1; } static void tr7_read(void) { - route_head *trk = NULL; - unsigned int magic; - waypoint *prev = NULL; - - magic = gbfgetint32(fin); - if (magic != TR7_TRACK_MAGIC) { - fatal(MYNAME ": Invalid magic number in header (%X, but %X expected)!\n", magic, TR7_TRACK_MAGIC); - } - - while (! gbfeof(fin)) { - unsigned char buff[TR7_S_SIZE]; - double lat, lon; - struct tm tm; - waypoint *wpt; - float speed, course; - - gbfread(buff, 1, sizeof(buff), fin); - - memset(&tm, 0, sizeof(tm)); - - lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0; - lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0; - - if ((fabs(lat) > 90) || (fabs(lon) > 180)) { /* that really happens */ - trk = NULL; - continue; - } - - tm.tm_year = le_read16(&buff[TR7_S_YEAR]); - tm.tm_mon = buff[TR7_S_MONTH]; - tm.tm_mday = buff[TR7_S_DAY]; - tm.tm_hour = buff[TR7_S_HOUR]; - tm.tm_min = buff[TR7_S_MIN]; - tm.tm_sec = buff[TR7_S_SEC]; - - if ((tm.tm_mday < 1) || (tm.tm_mday > 31) || - (tm.tm_mon < 1) || (tm.tm_mon > 12) || - (tm.tm_year <= 1970) || - (tm.tm_year > tmref.tm_year+1)) continue; - - speed = KPH_TO_MPS(le_read16(&buff[TR7_S_SPEED])); - course = 360 - le_read16(&buff[TR7_S_COURSE]); - if ((speed < 0) || (course > 360) || (course < 0)) continue; - - wpt = waypt_new(); - - wpt->latitude = lat; - wpt->longitude = lon; - - tm.tm_year -= 1900; - tm.tm_mon -= 1; - wpt->creation_time = mkgmtime(&tm); - - WAYPT_SET(wpt, course, course); - WAYPT_SET(wpt, speed, speed); + route_head *trk = NULL; + unsigned int magic; + waypoint *prev = NULL; + + magic = gbfgetint32(fin); + if (magic != TR7_TRACK_MAGIC) { + fatal(MYNAME ": Invalid magic number in header (%X, but %X expected)!\n", magic, TR7_TRACK_MAGIC); + } + + while (! gbfeof(fin)) { + unsigned char buff[TR7_S_SIZE]; + double lat, lon; + struct tm tm; + waypoint *wpt; + float speed, course; + + gbfread(buff, 1, sizeof(buff), fin); + + memset(&tm, 0, sizeof(tm)); + + lat = (double)le_read32(&buff[TR7_S_LAT]) / 1000000.0; + lon = (double)le_read32(&buff[TR7_S_LON]) / 1000000.0; + + if ((fabs(lat) > 90) || (fabs(lon) > 180)) { /* that really happens */ + trk = NULL; + continue; + } + + tm.tm_year = le_read16(&buff[TR7_S_YEAR]); + tm.tm_mon = buff[TR7_S_MONTH]; + tm.tm_mday = buff[TR7_S_DAY]; + tm.tm_hour = buff[TR7_S_HOUR]; + tm.tm_min = buff[TR7_S_MIN]; + tm.tm_sec = buff[TR7_S_SEC]; + + if ((tm.tm_mday < 1) || (tm.tm_mday > 31) || + (tm.tm_mon < 1) || (tm.tm_mon > 12) || + (tm.tm_year <= 1970) || + (tm.tm_year > tmref.tm_year+1)) { + continue; + } + + speed = KPH_TO_MPS(le_read16(&buff[TR7_S_SPEED])); + course = 360 - le_read16(&buff[TR7_S_COURSE]); + if ((speed < 0) || (course > 360) || (course < 0)) { + continue; + } + + wpt = waypt_new(); + + wpt->latitude = lat; + wpt->longitude = lon; + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + wpt->creation_time = mkgmtime(&tm); + + WAYPT_SET(wpt, course, course); + WAYPT_SET(wpt, speed, speed); #if 0 /* unsure, not validated items */ - wpt->fix = buff[TR7_S_FIX]; - if (buff[TR7_S_VALID] != 'A') { - waypt_free(wpt); - continue; - } + wpt->fix = buff[TR7_S_FIX]; + if (buff[TR7_S_VALID] != 'A') { + waypt_free(wpt); + continue; + } #endif - if (waypt_speed(prev, wpt) > 9999.9) { /* filter out some bad trackpoints */ - waypt_free(wpt); - continue; - } - - if (prev) { /* other track or bad timestamp */ - if (wpt->creation_time && (prev->creation_time > wpt->creation_time)) trk = NULL; - else if (waypt_distance(prev, wpt) > 9999.9) trk = NULL; - } - - if (! trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - prev = wpt; - } + if (waypt_speed(prev, wpt) > 9999.9) { /* filter out some bad trackpoints */ + waypt_free(wpt); + continue; + } + + if (prev) { /* other track or bad timestamp */ + if (wpt->creation_time && (prev->creation_time > wpt->creation_time)) { + trk = NULL; + } else if (waypt_distance(prev, wpt) > 9999.9) { + trk = NULL; + } + } + + if (! trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + prev = wpt; + } } static void tr7_check_after_read_head_cb(const route_head *trk) { - trk_tmp = trk; - course_tmp = 0; - speed_tmp = 0; + trk_tmp = trk; + course_tmp = 0; + speed_tmp = 0; } static void tr7_check_after_read_wpt_cb(const waypoint *wpt) { - if (wpt->speed != 0) speed_tmp = 1; - if (wpt->course != 360.0) course_tmp = 1; + if (wpt->speed != 0) { + speed_tmp = 1; + } + if (wpt->course != 360.0) { + course_tmp = 1; + } } static void tr7_check_after_read_trailer_cb(const route_head *trk) { - queue *elem, *tmp; - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - if (speed_tmp == 0) WAYPT_UNSET(wpt, speed); - if (course_tmp == 0) { - WAYPT_UNSET(wpt, course); - wpt->course = 0; - } - } + queue *elem, *tmp; + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + if (speed_tmp == 0) { + WAYPT_UNSET(wpt, speed); + } + if (course_tmp == 0) { + WAYPT_UNSET(wpt, course); + wpt->course = 0; + } + } } -static void +static void tr7_rd_deinit(void) { - track_disp_session(curr_session(), - tr7_check_after_read_head_cb, - tr7_check_after_read_trailer_cb, - tr7_check_after_read_wpt_cb); - gbfclose(fin); + track_disp_session(curr_session(), + tr7_check_after_read_head_cb, + tr7_check_after_read_trailer_cb, + tr7_check_after_read_wpt_cb); + gbfclose(fin); } /******************************************************************************* @@ -201,88 +214,102 @@ tr7_rd_deinit(void) static void tr7_disp_track_head_cb(const route_head *trk) { - wpt_tmp = NULL; + wpt_tmp = NULL; } static void tr7_disp_waypt_cb(const waypoint *wpt) { - unsigned char buff[TR7_S_SIZE]; - struct tm tm; - double speed, course; - - memset(buff, 0, sizeof(buff)); - - le_write32(&buff[TR7_S_LON], (int)(wpt->longitude * 1000000.0)); - le_write32(&buff[TR7_S_LAT], (int)(wpt->latitude * 1000000.0)); - - if WAYPT_HAS(wpt, course) course = wpt->course; - else if (wpt_tmp != NULL) course = waypt_course(wpt_tmp, wpt); - else course = -1; - if (course >= 0) le_write16(&buff[TR7_S_COURSE], (int)(360 - course)); - - if (wpt->creation_time) { - tm = *gmtime(&wpt->creation_time); - - le_write16(&buff[TR7_S_YEAR], tm.tm_year + 1900); - buff[TR7_S_MONTH] = tm.tm_mon + 1; - buff[TR7_S_DAY] = tm.tm_mday; - buff[TR7_S_HOUR] = tm.tm_hour; - buff[TR7_S_MIN] = tm.tm_min; - buff[TR7_S_SEC] = tm.tm_sec; - - if WAYPT_HAS(wpt, speed) speed = wpt->speed; - else if (wpt_tmp != NULL) speed = waypt_speed(wpt_tmp, wpt); - else speed = -1; - if (speed >= 0) le_write16(&buff[TR7_S_SPEED], (int)MPS_TO_KPH(speed)); - } - buff[TR7_S_VALID] = 'A'; /* meaning unknown */ + unsigned char buff[TR7_S_SIZE]; + struct tm tm; + double speed, course; + + memset(buff, 0, sizeof(buff)); + + le_write32(&buff[TR7_S_LON], (int)(wpt->longitude * 1000000.0)); + le_write32(&buff[TR7_S_LAT], (int)(wpt->latitude * 1000000.0)); + + if WAYPT_HAS(wpt, course) { + course = wpt->course; + } else if (wpt_tmp != NULL) { + course = waypt_course(wpt_tmp, wpt); + } else { + course = -1; + } + if (course >= 0) { + le_write16(&buff[TR7_S_COURSE], (int)(360 - course)); + } + + if (wpt->creation_time) { + tm = *gmtime(&wpt->creation_time); + + le_write16(&buff[TR7_S_YEAR], tm.tm_year + 1900); + buff[TR7_S_MONTH] = tm.tm_mon + 1; + buff[TR7_S_DAY] = tm.tm_mday; + buff[TR7_S_HOUR] = tm.tm_hour; + buff[TR7_S_MIN] = tm.tm_min; + buff[TR7_S_SEC] = tm.tm_sec; + + if WAYPT_HAS(wpt, speed) { + speed = wpt->speed; + } else if (wpt_tmp != NULL) { + speed = waypt_speed(wpt_tmp, wpt); + } else { + speed = -1; + } + if (speed >= 0) { + le_write16(&buff[TR7_S_SPEED], (int)MPS_TO_KPH(speed)); + } + } + buff[TR7_S_VALID] = 'A'; /* meaning unknown */ #if 0 /* not validated */ - if (wpt->fix != fix_unknown) buff[TR7_S_FIX] = wpt->fix; + if (wpt->fix != fix_unknown) { + buff[TR7_S_FIX] = wpt->fix; + } #endif - gbfwrite(buff, 1, sizeof(buff), fout); - - wpt_tmp = wpt; + gbfwrite(buff, 1, sizeof(buff), fout); + + wpt_tmp = wpt; } static void tr7_wr_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - gbfputint32(TR7_TRACK_MAGIC, fout); + fout = gbfopen_le(fname, "wb", MYNAME); + gbfputint32(TR7_TRACK_MAGIC, fout); } static void tr7_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void tr7_write(void) { - track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb); + track_disp_all(tr7_disp_track_head_cb, NULL, tr7_disp_waypt_cb); } /**************************************************************************/ ff_vecs_t mapasia_tr7_vecs = { /* we can read and write tracks */ - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - tr7_rd_init, - tr7_wr_init, - tr7_rd_deinit, - tr7_wr_deinit, - tr7_read, - tr7_write, - NULL, - tr7_args, - CET_CHARSET_UTF8, 1 /* FIXED - CET-REVIEW - */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + tr7_rd_init, + tr7_wr_init, + tr7_rd_deinit, + tr7_wr_deinit, + tr7_read, + tr7_write, + NULL, + tr7_args, + CET_CHARSET_UTF8, 1 /* FIXED - CET-REVIEW - */ }; diff --git a/gpsbabel/mapopolis.c b/gpsbabel/mapopolis.c index 0e5001c0f..1d3008142 100644 --- a/gpsbabel/mapopolis.c +++ b/gpsbabel/mapopolis.c @@ -33,21 +33,20 @@ #define LATDIV2 (1000000.0/(9*2)) -struct record0 -{ - char unk[6]; - pdb_32 lon1; - pdb_32 lat1; - pdb_32 lon2; - pdb_32 lat2; - pdb_32 lonD; - pdb_32 latD; - char name[31+1]; - char unk2[35]; - char demo; - char unk3[4]; - unsigned char expcode[4]; - /* ... more stuff ... */ +struct record0 { + char unk[6]; + pdb_32 lon1; + pdb_32 lat1; + pdb_32 lon2; + pdb_32 lat2; + pdb_32 lonD; + pdb_32 latD; + char name[31+1]; + char unk2[35]; + char demo; + char unk3[4]; + unsigned char expcode[4]; + /* ... more stuff ... */ }; double Lat1, Lon1; @@ -55,13 +54,13 @@ double Lat2, Lon2; double LatD, LonD; struct record { - char unknown[10]; - pdb_16 unk1; - pdb_16 unk2; - pdb_16 lon1d; - pdb_16 lat1d; - pdb_16 lon2d; - pdb_16 lat2d; + char unknown[10]; + pdb_16 unk1; + pdb_16 unk2; + pdb_16 lon1d; + pdb_16 lat1d; + pdb_16 lon2d; + pdb_16 lat2d; }; static pdbfile *file_in, *file_out; @@ -70,38 +69,38 @@ static short_handle mkshort_handle; static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); + pdb_close(file_in); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 20); + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 20); } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); } convert_rec0(struct record0 *rec0) { - Lon1 = be_read32(&rec0->lon1) / LONDIV; - Lat1 = be_read32(&rec0->lat1) / LATDIV; - Lon2 = be_read32(&rec0->lon2) / LONDIV; - Lat2 = be_read32(&rec0->lat2) / LATDIV; - LonD = be_read32(&rec0->lonD) / LONDIV2; - LatD = be_read32(&rec0->latD) / LATDIV2; + Lon1 = be_read32(&rec0->lon1) / LONDIV; + Lat1 = be_read32(&rec0->lat1) / LATDIV; + Lon2 = be_read32(&rec0->lon2) / LONDIV; + Lat2 = be_read32(&rec0->lat2) / LATDIV; + LonD = be_read32(&rec0->lonD) / LONDIV2; + LatD = be_read32(&rec0->latD) / LATDIV2; // printf("%s: %.5f %.5f %.5f %.5f %.5f %.5f\n", // rec0->name, Lat1, Lon1, Lat2, Lon2, LatD, LonD); @@ -115,56 +114,57 @@ convert_rec0(struct record0 *rec0) void decode(char *buf) { - int i; + int i; - for (i = 0; buf[i]; ++i) { - buf[i] = buf[i] ^ ((i % 96) & 0xf); - } + for (i = 0; buf[i]; ++i) { + buf[i] = buf[i] ^ ((i % 96) & 0xf); + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; + struct record *rec; + pdbrec_t *pdb_rec; - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a Magellan Navigator file.\n"); - } + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a Magellan Navigator file.\n"); + } - pdb_rec = file_in->rec_list; - convert_rec0((struct record0*) pdb_rec->data); + pdb_rec = file_in->rec_list; + convert_rec0((struct record0*) pdb_rec->data); // for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) { - for(pdb_rec = pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) { - waypoint *wpt_tmp; - char *vdata = 0; - char *edata; - struct tm tm = {0}; - - rec = (struct record *) pdb_rec->data; - edata = (char *) rec + pdb_rec->size; - - for (; vdata < edata; rec = (struct record *) vdata) { - wpt_tmp = waypt_new(); - wpt_tmp->latitude = Lat1 + - be_read16(&rec->lat1d) / LATDIV2; - wpt_tmp->longitude = Lon1 + - be_read16(&rec->lon1d) / LONDIV2; - - vdata = (char *) rec + sizeof(*rec); - wpt_tmp->description = xstrdup(vdata); - vdata += strlen(wpt_tmp->description) + 1 + 6; - - while (*vdata == 0x40) - vdata++; - decode(vdata); - wpt_tmp->notes = xstrdup(vdata); - vdata += strlen(wpt_tmp->notes) + 1; - - waypt_add(wpt_tmp); - } - } + for (pdb_rec = pdb_rec->next; pdb_rec; pdb_rec=pdb_rec->next) { + waypoint *wpt_tmp; + char *vdata = 0; + char *edata; + struct tm tm = {0}; + + rec = (struct record *) pdb_rec->data; + edata = (char *) rec + pdb_rec->size; + + for (; vdata < edata; rec = (struct record *) vdata) { + wpt_tmp = waypt_new(); + wpt_tmp->latitude = Lat1 + + be_read16(&rec->lat1d) / LATDIV2; + wpt_tmp->longitude = Lon1 + + be_read16(&rec->lon1d) / LONDIV2; + + vdata = (char *) rec + sizeof(*rec); + wpt_tmp->description = xstrdup(vdata); + vdata += strlen(wpt_tmp->description) + 1 + 6; + + while (*vdata == 0x40) { + vdata++; + } + decode(vdata); + wpt_tmp->notes = xstrdup(vdata); + vdata += strlen(wpt_tmp->notes) + 1; + + waypt_add(wpt_tmp); + } + } } @@ -172,127 +172,125 @@ static void my_writewpt(const waypoint *wpt) { #if 0 - struct record *rec; - static int ct; - struct tm *tm; - char *vdata; - time_t tm_t; - const char *sn = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, wpt->description) : - wpt->shortname; - - rec = xcalloc(sizeof(*rec)+56,1); - - tm = NULL; - if ( wpt->creation_time ) { - tm = gmtime( &wpt->creation_time); - } - if ( !tm ) { - tm_t = current_time(); - tm = gmtime( &tm_t ); - } - - be_write16( &rec->crt_sec, tm->tm_sec ); - be_write16( &rec->crt_min, tm->tm_min ); - be_write16( &rec->crt_hour, tm->tm_hour ); - be_write16( &rec->crt_mday, tm->tm_mday ); - be_write16( &rec->crt_mon, tm->tm_mon + 1 ); - be_write16( &rec->crt_year, tm->tm_mon + 1900 ); - - be_write16( &rec->unknown, 0); - - be_write16( &rec->xx_sec, tm->tm_sec ); - be_write16( &rec->xx_min, tm->tm_min ); - be_write16( &rec->xx_hour, tm->tm_hour ); - be_write16( &rec->xx_mday, tm->tm_mday ); - be_write16( &rec->xx_mon, tm->tm_mon + 1 ); - be_write16( &rec->xx_year, tm->tm_mon + 1900 ); - - be_write16( &rec->unknown2, 0); - - be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); - be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); - be_write32(&rec->elevation, wpt->altitude); - - rec->plot = 0; - rec->unknown3 = 'a'; - - vdata = (char *)rec + sizeof(*rec); - if ( sn ) { - strncpy( vdata, sn, 21 ); - vdata[20] = '\0'; - } - else { - vdata[0] ='\0'; - } - vdata += strlen( vdata ) + 1; - if ( wpt->description ) { - strncpy( vdata, wpt->description, 33 ); - vdata[32] = '\0'; - } - else { - vdata[0] = '\0'; - } - vdata += strlen( vdata ) + 1; - vdata[0] = '\0'; - vdata[1] = '\0'; - vdata += 2; - - pdb_write(file_out, 0, rec, (char *)vdata - (char *)rec); - - xfree(rec); + struct record *rec; + static int ct; + struct tm *tm; + char *vdata; + time_t tm_t; + const char *sn = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, wpt->description) : + wpt->shortname; + + rec = xcalloc(sizeof(*rec)+56,1); + + tm = NULL; + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + if (!tm) { + tm_t = current_time(); + tm = gmtime(&tm_t); + } + + be_write16(&rec->crt_sec, tm->tm_sec); + be_write16(&rec->crt_min, tm->tm_min); + be_write16(&rec->crt_hour, tm->tm_hour); + be_write16(&rec->crt_mday, tm->tm_mday); + be_write16(&rec->crt_mon, tm->tm_mon + 1); + be_write16(&rec->crt_year, tm->tm_mon + 1900); + + be_write16(&rec->unknown, 0); + + be_write16(&rec->xx_sec, tm->tm_sec); + be_write16(&rec->xx_min, tm->tm_min); + be_write16(&rec->xx_hour, tm->tm_hour); + be_write16(&rec->xx_mday, tm->tm_mday); + be_write16(&rec->xx_mon, tm->tm_mon + 1); + be_write16(&rec->xx_year, tm->tm_mon + 1900); + + be_write16(&rec->unknown2, 0); + + be_write32(&rec->longitude, si_round(wpt->longitude * 100000.0)); + be_write32(&rec->latitude, si_round(wpt->latitude * 100000.0)); + be_write32(&rec->elevation, wpt->altitude); + + rec->plot = 0; + rec->unknown3 = 'a'; + + vdata = (char *)rec + sizeof(*rec); + if (sn) { + strncpy(vdata, sn, 21); + vdata[20] = '\0'; + } else { + vdata[0] ='\0'; + } + vdata += strlen(vdata) + 1; + if (wpt->description) { + strncpy(vdata, wpt->description, 33); + vdata[32] = '\0'; + } else { + vdata[0] = '\0'; + } + vdata += strlen(vdata) + 1; + vdata[0] = '\0'; + vdata[1] = '\0'; + vdata += 2; + + pdb_write(file_out, 0, rec, (char *)vdata - (char *)rec); + + xfree(rec); #endif } static void data_write(void) { - static char *appinfo = - "\0\x01" - "User\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - "\0\x01\x02\x03\x04\x05\x06\x07\x08" - "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; - - strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = 276; - - waypt_disp_all(my_writewpt); + static char *appinfo = + "\0\x01" + "User\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\x01\x02\x03\x04\x05\x06\x07\x08" + "\x09\x0a\x0b\x0c\x0d\x0e\x0f\0\0"; + + strncpy(file_out->name, "Companion Waypoints", PDB_DBNAMELEN); + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = 276; + + waypt_disp_all(my_writewpt); } ff_vecs_t mapopolis_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/mapsend.c b/gpsbabel/mapsend.c index a47f5b0cb..0b9797223 100644 --- a/gpsbabel/mapsend.c +++ b/gpsbabel/mapsend.c @@ -42,511 +42,532 @@ static char *mapsend_opt_trkver = NULL; static arglist_t mapsend_args[] = { - {"trkver", &mapsend_opt_trkver, - "MapSend version TRK file to generate (3,4)", - "4", ARGTYPE_INT, "3", "4" }, - ARG_TERMINATOR + { + "trkver", &mapsend_opt_trkver, + "MapSend version TRK file to generate (3,4)", + "4", ARGTYPE_INT, "3", "4" + }, + ARG_TERMINATOR }; static void -mapsend_init_opts(const char isReading) { /* 1=read, 2=write */ - int opt_trkver; - - /* read & write options here */ - - if (isReading) { - /* reading-only options here */ - } else { - /* writing-only options here */ - - // TRK MapSend version - opt_trkver = atoi(mapsend_opt_trkver); - if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) - fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); - trk_version = opt_trkver * 10; - } +mapsend_init_opts(const char isReading) /* 1=read, 2=write */ +{ + int opt_trkver; + + /* read & write options here */ + + if (isReading) { + /* reading-only options here */ + } else { + /* writing-only options here */ + + // TRK MapSend version + opt_trkver = atoi(mapsend_opt_trkver); + if ((opt_trkver < MAPSEND_TRKVER_MIN) || (opt_trkver > MAPSEND_TRKVER_MAX)) { + fatal(MYNAME ": Unsupported MapSend TRK version \"%s\"!\n", mapsend_opt_trkver); + } + trk_version = opt_trkver * 10; + } } static void mapsend_rd_init(const char *fname) { - mapsend_init_opts(1); - mapsend_file_in = gbfopen_le(fname, "rb", MYNAME); + mapsend_init_opts(1); + mapsend_file_in = gbfopen_le(fname, "rb", MYNAME); } static void mapsend_rd_deinit(void) { - gbfclose(mapsend_file_in); + gbfclose(mapsend_file_in); } static void mapsend_wr_init(const char *fname) { - mapsend_init_opts(0); - mapsend_file_out = gbfopen(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + mapsend_init_opts(0); + mapsend_file_out = gbfopen(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); - wpt_handle = mkshort_new_handle(); - setshort_whitespace_ok(wpt_handle, 1); - setshort_length(wpt_handle, 8); + wpt_handle = mkshort_new_handle(); + setshort_whitespace_ok(wpt_handle, 1); + setshort_length(wpt_handle, 8); - route_wp_count = 0; + route_wp_count = 0; } static void mapsend_wr_deinit(void) { - gbfclose(mapsend_file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&wpt_handle); + gbfclose(mapsend_file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&wpt_handle); } static void mapsend_wpt_read(void) { - char tbuf[256]; - int wpt_count, rte_count, rte_num; - int wpt_number; - char wpt_icon; - char wpt_status; - waypoint *wpt_tmp; - route_head *rte_head; - - wpt_count = gbfgetint32(mapsend_file_in); - - while (wpt_count--) { - wpt_tmp = waypt_new(); - - wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); - wpt_tmp->description = gbfgetpstr(mapsend_file_in); - - wpt_number = gbfgetint32(mapsend_file_in); - wpt_icon = gbfgetc(mapsend_file_in); - wpt_status = gbfgetc(mapsend_file_in); - - wpt_tmp->altitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - if (wpt_icon < 26) - sprintf(tbuf, "%c", wpt_icon + 'a'); - else - sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); - wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); - - waypt_add(wpt_tmp); - } - - /* now read the routes... */ - rte_count = gbfgetint32(mapsend_file_in); - - while (rte_count--) { - rte_head = route_head_alloc(); - route_add_head(rte_head); - - /* route name */ - rte_head->rte_name = gbfgetpstr(mapsend_file_in); - - /* route # */ - rte_num = gbfgetint32(mapsend_file_in); - rte_head->rte_num = rte_num; - - /* points this route */ - wpt_count = gbfgetint32(mapsend_file_in); - - while (wpt_count--) { - wpt_tmp = waypt_new(); - - /* waypoint name */ - wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); - - /* waypoint # */ - wpt_number = gbfgetint32(mapsend_file_in); - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - gbfread(&wpt_icon, 1, sizeof(wpt_icon), mapsend_file_in); - - if (wpt_icon < 26) - sprintf(tbuf, "%c", wpt_icon + 'a'); - else - sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); - wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); - - route_add_wpt(rte_head, wpt_tmp); - } - } + char tbuf[256]; + int wpt_count, rte_count, rte_num; + int wpt_number; + char wpt_icon; + char wpt_status; + waypoint *wpt_tmp; + route_head *rte_head; + + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + wpt_tmp->description = gbfgetpstr(mapsend_file_in); + + wpt_number = gbfgetint32(mapsend_file_in); + wpt_icon = gbfgetc(mapsend_file_in); + wpt_status = gbfgetc(mapsend_file_in); + + wpt_tmp->altitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (wpt_icon < 26) { + sprintf(tbuf, "%c", wpt_icon + 'a'); + } else { + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + } + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + waypt_add(wpt_tmp); + } + + /* now read the routes... */ + rte_count = gbfgetint32(mapsend_file_in); + + while (rte_count--) { + rte_head = route_head_alloc(); + route_add_head(rte_head); + + /* route name */ + rte_head->rte_name = gbfgetpstr(mapsend_file_in); + + /* route # */ + rte_num = gbfgetint32(mapsend_file_in); + rte_head->rte_num = rte_num; + + /* points this route */ + wpt_count = gbfgetint32(mapsend_file_in); + + while (wpt_count--) { + wpt_tmp = waypt_new(); + + /* waypoint name */ + wpt_tmp->shortname = gbfgetpstr(mapsend_file_in); + + /* waypoint # */ + wpt_number = gbfgetint32(mapsend_file_in); + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + gbfread(&wpt_icon, 1, sizeof(wpt_icon), mapsend_file_in); + + if (wpt_icon < 26) { + sprintf(tbuf, "%c", wpt_icon + 'a'); + } else { + sprintf(tbuf, "a%c", wpt_icon - 26 + 'a'); + } + wpt_tmp->icon_descr = mag_find_descr_from_token(tbuf); + + route_add_wpt(rte_head, wpt_tmp); + } + } } static void mapsend_track_read(void) { - unsigned int trk_count; - int valid; - unsigned char centisecs; - route_head *track_head; - waypoint *wpt_tmp; - - track_head = route_head_alloc(); - track_head->rte_name = gbfgetpstr(mapsend_file_in); - track_add_head(track_head); - - trk_count = gbfgetuint32(mapsend_file_in); - - while (trk_count--) { - wpt_tmp = waypt_new(); - - wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); - wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); - - if (mapsend_infile_version < 36) { /* < version 4.0 */ - wpt_tmp->altitude = gbfgetint32(mapsend_file_in); - } else { - wpt_tmp->altitude = gbfgetflt(mapsend_file_in); - } - if (wpt_tmp->altitude < unknown_alt + 1) - wpt_tmp->altitude = unknown_alt; - wpt_tmp->creation_time = gbfgetint32(mapsend_file_in); - valid = gbfgetint32(mapsend_file_in); - - /* centiseconds only in >= version 3.0 */ - if (mapsend_infile_version >= 34) { - gbfread(¢isecs, 1, 1, mapsend_file_in); - } else { - centisecs = 0; - } - wpt_tmp->microseconds = CENTI_TO_MICRO(centisecs); - - track_add_wpt(track_head, wpt_tmp); - } + unsigned int trk_count; + int valid; + unsigned char centisecs; + route_head *track_head; + waypoint *wpt_tmp; + + track_head = route_head_alloc(); + track_head->rte_name = gbfgetpstr(mapsend_file_in); + track_add_head(track_head); + + trk_count = gbfgetuint32(mapsend_file_in); + + while (trk_count--) { + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = gbfgetdbl(mapsend_file_in); + wpt_tmp->latitude = -gbfgetdbl(mapsend_file_in); + + if (mapsend_infile_version < 36) { /* < version 4.0 */ + wpt_tmp->altitude = gbfgetint32(mapsend_file_in); + } else { + wpt_tmp->altitude = gbfgetflt(mapsend_file_in); + } + if (wpt_tmp->altitude < unknown_alt + 1) { + wpt_tmp->altitude = unknown_alt; + } + wpt_tmp->creation_time = gbfgetint32(mapsend_file_in); + valid = gbfgetint32(mapsend_file_in); + + /* centiseconds only in >= version 3.0 */ + if (mapsend_infile_version >= 34) { + gbfread(¢isecs, 1, 1, mapsend_file_in); + } else { + centisecs = 0; + } + wpt_tmp->microseconds = CENTI_TO_MICRO(centisecs); + + track_add_wpt(track_head, wpt_tmp); + } } static void mapsend_read(void) { - mapsend_hdr hdr; - int type, len; - char buf[3]; - - /* - * Because of the silly struct packing and the goofy variable-length - * strings, each member has to be read in one at a time. Grrr. - */ - - len = gbfread(&hdr, 1, sizeof(hdr), mapsend_file_in); - is_fatal(len < sizeof(hdr), MYNAME ": No mapsend or empty file!"); - - type = le_read16(&hdr.ms_type); - strncpy(buf, hdr.ms_version, 2); - buf[2] = '\0'; - - mapsend_infile_version = atoi(buf); - - switch(type) { - case ms_type_wpt: - mapsend_wpt_read(); - break; - case ms_type_track: - mapsend_track_read(); - break; - case ms_type_log: - fatal(MYNAME ", GPS logs not supported.\n"); - case ms_type_rgn: - fatal(MYNAME ", GPS regions not supported.\n"); - default: - fatal(MYNAME ", unknown file type %d\n", type); - } + mapsend_hdr hdr; + int type, len; + char buf[3]; + + /* + * Because of the silly struct packing and the goofy variable-length + * strings, each member has to be read in one at a time. Grrr. + */ + + len = gbfread(&hdr, 1, sizeof(hdr), mapsend_file_in); + is_fatal(len < sizeof(hdr), MYNAME ": No mapsend or empty file!"); + + type = le_read16(&hdr.ms_type); + strncpy(buf, hdr.ms_version, 2); + buf[2] = '\0'; + + mapsend_infile_version = atoi(buf); + + switch (type) { + case ms_type_wpt: + mapsend_wpt_read(); + break; + case ms_type_track: + mapsend_track_read(); + break; + case ms_type_log: + fatal(MYNAME ", GPS logs not supported.\n"); + case ms_type_rgn: + fatal(MYNAME ", GPS regions not supported.\n"); + default: + fatal(MYNAME ", unknown file type %d\n", type); + } } static void mapsend_waypt_pr(const waypoint *waypointp) { - unsigned char c; - double falt; - static int cnt = 0; - const char *iconp = NULL; - const char *sn = global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, waypointp) : - waypointp->shortname; - char *tmp; - - /* - * The format spec doesn't call out the character set of waypoint - * name and description. Empirically, we can see that it's 8859-1, - * but if we create mapsend files containing those, Mapsend becomes - * grumpy uploading the resulting waypoints and being unable to deal - * with the resulting comm errors. - * - * Ironically, our own Magellan serial module strips the "naughty" - * characters, keeping it more in definition with their own serial - * spec. :-) - * - * So we just decompose the utf8 strings to ascii before stuffing - * them into the Mapsend file. - */ - - - tmp = mkshort(wpt_handle, sn); - gbfputpstr(tmp, mapsend_file_out); - if (tmp) xfree(tmp); - - tmp = waypointp->description; - if (tmp) - c = strlen(tmp); - else - c = 0; - - if (c > 30) c = 30; - gbfputc(c, mapsend_file_out); - gbfwrite(tmp, 1, c, mapsend_file_out); - - /* #, icon, status */ - gbfputint32(++cnt, mapsend_file_out); - - if (waypointp->icon_descr) { - iconp = mag_find_token_from_descr(waypointp->icon_descr); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } else { - c = 0; - } - if (get_cache_icon(waypointp)) { - iconp = mag_find_token_from_descr(get_cache_icon(waypointp)); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } - - gbfwrite(&c, 1, 1, mapsend_file_out); - gbfputc(1, mapsend_file_out); - - falt = waypointp->altitude; - if (falt == unknown_alt) - falt = 0; - gbfputdbl(falt, mapsend_file_out); - - gbfputdbl(waypointp->longitude, mapsend_file_out); - gbfputdbl(-waypointp->latitude, mapsend_file_out); + unsigned char c; + double falt; + static int cnt = 0; + const char *iconp = NULL; + const char *sn = global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, waypointp) : + waypointp->shortname; + char *tmp; + + /* + * The format spec doesn't call out the character set of waypoint + * name and description. Empirically, we can see that it's 8859-1, + * but if we create mapsend files containing those, Mapsend becomes + * grumpy uploading the resulting waypoints and being unable to deal + * with the resulting comm errors. + * + * Ironically, our own Magellan serial module strips the "naughty" + * characters, keeping it more in definition with their own serial + * spec. :-) + * + * So we just decompose the utf8 strings to ascii before stuffing + * them into the Mapsend file. + */ + + + tmp = mkshort(wpt_handle, sn); + gbfputpstr(tmp, mapsend_file_out); + if (tmp) { + xfree(tmp); + } + + tmp = waypointp->description; + if (tmp) { + c = strlen(tmp); + } else { + c = 0; + } + + if (c > 30) { + c = 30; + } + gbfputc(c, mapsend_file_out); + gbfwrite(tmp, 1, c, mapsend_file_out); + + /* #, icon, status */ + gbfputint32(++cnt, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + if (get_cache_icon(waypointp)) { + iconp = mag_find_token_from_descr(get_cache_icon(waypointp)); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } + + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfputc(1, mapsend_file_out); + + falt = waypointp->altitude; + if (falt == unknown_alt) { + falt = 0; + } + gbfputdbl(falt, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); } -static void +static void mapsend_route_hdr(const route_head *rte) { - char * rname; - - /* route name -- mapsend really seems to want something here.. */ - if (!rte->rte_name) - rname = xstrdup("Route"); - else - rname = xstrdup(rte->rte_name); - gbfputpstr(rname, mapsend_file_out); - - xfree(rname); - - /* route # */ - gbfputint32(rte->rte_num, mapsend_file_out); - - /* # of waypoints to follow... */ - gbfputint32(rte->rte_waypt_ct, mapsend_file_out); + char * rname; + + /* route name -- mapsend really seems to want something here.. */ + if (!rte->rte_name) { + rname = xstrdup("Route"); + } else { + rname = xstrdup(rte->rte_name); + } + gbfputpstr(rname, mapsend_file_out); + + xfree(rname); + + /* route # */ + gbfputint32(rte->rte_num, mapsend_file_out); + + /* # of waypoints to follow... */ + gbfputint32(rte->rte_waypt_ct, mapsend_file_out); } -static void +static void mapsend_noop(const route_head *wp) { - /* no-op */ + /* no-op */ } -static void +static void mapsend_route_disp(const waypoint *waypointp) { - unsigned char c; - const char *iconp; - - route_wp_count++; - - /* waypoint name */ - c = waypointp->shortname ? strlen(waypointp->shortname) : 0; - gbfwrite(&c, 1, 1, mapsend_file_out); - gbfwrite(waypointp->shortname, 1, c, mapsend_file_out); - - /* waypoint number */ - gbfputint32(route_wp_count, mapsend_file_out); - - gbfputdbl(waypointp->longitude, mapsend_file_out); - gbfputdbl(-waypointp->latitude, mapsend_file_out); - - if (waypointp->icon_descr) { - iconp = mag_find_token_from_descr(waypointp->icon_descr); - if (1 == strlen(iconp)) { - c = iconp[0] - 'a'; - } else { - c = iconp[1] - 'a' + 26; - } - } else { - c = 0; - } - gbfwrite(&c, 1, 1, mapsend_file_out); + unsigned char c; + const char *iconp; + + route_wp_count++; + + /* waypoint name */ + c = waypointp->shortname ? strlen(waypointp->shortname) : 0; + gbfwrite(&c, 1, 1, mapsend_file_out); + gbfwrite(waypointp->shortname, 1, c, mapsend_file_out); + + /* waypoint number */ + gbfputint32(route_wp_count, mapsend_file_out); + + gbfputdbl(waypointp->longitude, mapsend_file_out); + gbfputdbl(-waypointp->latitude, mapsend_file_out); + + if (waypointp->icon_descr) { + iconp = mag_find_token_from_descr(waypointp->icon_descr); + if (1 == strlen(iconp)) { + c = iconp[0] - 'a'; + } else { + c = iconp[1] - 'a' + 26; + } + } else { + c = 0; + } + gbfwrite(&c, 1, 1, mapsend_file_out); } void mapsend_track_hdr(const route_head * trk) { - /* - * we write mapsend v3.0 tracks as mapsend v2.0 tracks get - * tremendously out of whack time/date wise. - */ - char *verstring = "30"; - queue *elem, *tmp; - char *tname; - int i; - mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0, 0, 0}}; - - switch (trk_version) { - case 20: verstring = "30"; break; - case 30: verstring = "34"; break; - case 40: - /* the signature seems to change with the versions, even though it - * shouldn't have according to the document. MapSend V4 doesn't - * like the old version. - */ - hdr.ms_signature[7] = '6'; - verstring = "36"; - break; - default: fatal("Unknown track version.\n"); break; - } - - hdr.ms_version[0] = verstring[0]; - hdr.ms_version[1] = verstring[1]; - - gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); - - /* track name */ - if (!trk->rte_name) - tname = xstrdup("Track"); - else - tname = xstrdup(trk->rte_name); - gbfputpstr(tname, mapsend_file_out); - - xfree(tname); - - /* total nodes (waypoints) this track */ - i = 0; - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - i++; - } - - gbfputint32(i, mapsend_file_out); - + /* + * we write mapsend v3.0 tracks as mapsend v2.0 tracks get + * tremendously out of whack time/date wise. + */ + char *verstring = "30"; + queue *elem, *tmp; + char *tname; + int i; + mapsend_hdr hdr = {13, "4D533334 MS", "30", ms_type_track, {0, 0, 0}}; + + switch (trk_version) { + case 20: + verstring = "30"; + break; + case 30: + verstring = "34"; + break; + case 40: + /* the signature seems to change with the versions, even though it + * shouldn't have according to the document. MapSend V4 doesn't + * like the old version. + */ + hdr.ms_signature[7] = '6'; + verstring = "36"; + break; + default: + fatal("Unknown track version.\n"); + break; + } + + hdr.ms_version[0] = verstring[0]; + hdr.ms_version[1] = verstring[1]; + + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + /* track name */ + if (!trk->rte_name) { + tname = xstrdup("Track"); + } else { + tname = xstrdup(trk->rte_name); + } + gbfputpstr(tname, mapsend_file_out); + + xfree(tname); + + /* total nodes (waypoints) this track */ + i = 0; + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + i++; + } + + gbfputint32(i, mapsend_file_out); + } void mapsend_track_disp(const waypoint * wpt) { - unsigned char c; - int t; - static int last_time; - - /* - * Firmware Ver 4.06 (at least) has a defect when it's set for .01km - * tracking that will sometimes result in timestamps in the track - * going BACKWARDS. When mapsend sees this, it (stupidly) advances - * the date by one, ignoring the date on the TRK lines. This looks - * for time travel and just uses the previous time - it's better to - * be thought to be standing still than to be time-travelling! - * - * This is rumoured (but yet unconfirmed) to be fixed in f/w 5.12. - */ - t = wpt->creation_time; - if (t < last_time) { - t = last_time; - } - - /* x = longitude */ - gbfputdbl(wpt->longitude, mapsend_file_out); - - /* x = latitude */ - gbfputdbl(-wpt->latitude, mapsend_file_out); - - /* altitude - * in V4.0+ this field is a float, it was previously an int - */ - if (trk_version < 40) { - gbfputint32((int) wpt->altitude, mapsend_file_out); - } else { - gbfputflt((float) wpt->altitude, mapsend_file_out); - } - - /* time */ - gbfputint32(t, mapsend_file_out); - last_time = t; - - /* validity */ - gbfputint32(1, mapsend_file_out); - - /* 0 centiseconds */ - if (trk_version >= 30) { - c = MICRO_TO_CENTI(wpt->microseconds); - gbfwrite(&c, 1, 1, mapsend_file_out); - } + unsigned char c; + int t; + static int last_time; + + /* + * Firmware Ver 4.06 (at least) has a defect when it's set for .01km + * tracking that will sometimes result in timestamps in the track + * going BACKWARDS. When mapsend sees this, it (stupidly) advances + * the date by one, ignoring the date on the TRK lines. This looks + * for time travel and just uses the previous time - it's better to + * be thought to be standing still than to be time-travelling! + * + * This is rumoured (but yet unconfirmed) to be fixed in f/w 5.12. + */ + t = wpt->creation_time; + if (t < last_time) { + t = last_time; + } + + /* x = longitude */ + gbfputdbl(wpt->longitude, mapsend_file_out); + + /* x = latitude */ + gbfputdbl(-wpt->latitude, mapsend_file_out); + + /* altitude + * in V4.0+ this field is a float, it was previously an int + */ + if (trk_version < 40) { + gbfputint32((int) wpt->altitude, mapsend_file_out); + } else { + gbfputflt((float) wpt->altitude, mapsend_file_out); + } + + /* time */ + gbfputint32(t, mapsend_file_out); + last_time = t; + + /* validity */ + gbfputint32(1, mapsend_file_out); + + /* 0 centiseconds */ + if (trk_version >= 30) { + c = MICRO_TO_CENTI(wpt->microseconds); + gbfwrite(&c, 1, 1, mapsend_file_out); + } } -void +void mapsend_track_write(void) { - track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp); + track_disp_all(mapsend_track_hdr, mapsend_noop, mapsend_track_disp); } static void mapsend_wpt_write(void) { - mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0, 0, 0}}; - int n = 0; - int wpt_count = waypt_count(); - - if (global_opts.objective == trkdata) { - mapsend_track_write(); - } else { - gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); - - if (global_opts.objective == wptdata) { - gbfputint32(wpt_count, mapsend_file_out); - waypt_disp_all(mapsend_waypt_pr); - } else - if (global_opts.objective == rtedata) { - - /* # of points - all routes */ - gbfputint32(route_waypt_count(), mapsend_file_out); - - /* write points - all routes */ - route_disp_all(mapsend_noop, mapsend_noop, mapsend_waypt_pr); - } - - n = route_count(); - - gbfputint32(n, mapsend_file_out); - - if (n) - route_disp_all(mapsend_route_hdr, mapsend_noop, mapsend_route_disp); - } + mapsend_hdr hdr = {13, {"4D533330 MS"}, {"30"}, ms_type_wpt, {0, 0, 0}}; + int n = 0; + int wpt_count = waypt_count(); + + if (global_opts.objective == trkdata) { + mapsend_track_write(); + } else { + gbfwrite(&hdr, sizeof(hdr), 1, mapsend_file_out); + + if (global_opts.objective == wptdata) { + gbfputint32(wpt_count, mapsend_file_out); + waypt_disp_all(mapsend_waypt_pr); + } else if (global_opts.objective == rtedata) { + + /* # of points - all routes */ + gbfputint32(route_waypt_count(), mapsend_file_out); + + /* write points - all routes */ + route_disp_all(mapsend_noop, mapsend_noop, mapsend_waypt_pr); + } + + n = route_count(); + + gbfputint32(n, mapsend_file_out); + + if (n) { + route_disp_all(mapsend_route_hdr, mapsend_noop, mapsend_route_disp); + } + } } ff_vecs_t mapsend_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - mapsend_rd_init, - mapsend_wr_init, - mapsend_rd_deinit, - mapsend_wr_deinit, - mapsend_read, - mapsend_wpt_write, - NULL, - mapsend_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mapsend_rd_init, + mapsend_wr_init, + mapsend_rd_deinit, + mapsend_wr_deinit, + mapsend_read, + mapsend_wpt_write, + NULL, + mapsend_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/mapsend.h b/gpsbabel/mapsend.h index 2d1ef9448..193b1832e 100644 --- a/gpsbabel/mapsend.h +++ b/gpsbabel/mapsend.h @@ -20,25 +20,25 @@ * * Information from: * Mapsend File Format Description Revision 1.1, March 6, 2002 from Thales. - * + * * Note this file format was clearly NOT designed for cross-architecture - * portability. In fact, because of the pascal nature of the 'string' - * data type described in that document, it's impractical to describe + * portability. In fact, because of the pascal nature of the 'string' + * data type described in that document, it's impractical to describe * a 'struct waypoint' in C. - * + * */ typedef struct { - char ms_length; - char ms_signature[11]; - char ms_version[2]; - char ms_type; - char _ms_type[3]; + char ms_length; + char ms_signature[11]; + char ms_version[2]; + char ms_type; + char _ms_type[3]; } mapsend_hdr; typedef enum { - ms_type_rgn = 0, - ms_type_wpt = 1, - ms_type_track = 2, - ms_type_log = 3 + ms_type_rgn = 0, + ms_type_wpt = 1, + ms_type_track = 2, + ms_type_log = 3 } ms_type; diff --git a/gpsbabel/mapsource.c b/gpsbabel/mapsource.c index 92eb2d595..0dbac67a2 100644 --- a/gpsbabel/mapsource.c +++ b/gpsbabel/mapsource.c @@ -55,7 +55,7 @@ static short_handle read_route_wpt_mkshort_handle; #define MPSDEFAULTWPTCLASS 0 #define MPSHIDDENROUTEWPTCLASS 8 -#define MYNAME "MAPSOURCE" +#define MYNAME "MAPSOURCE" #define ISME 0 #define NOTME 1 @@ -77,44 +77,54 @@ char *mpsuseprox = NULL; static arglist_t mps_args[] = { - {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, - { "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"mpsverout", &mpsverout, - "Version of mapsource file to generate (3,4,5)", NULL, - ARGTYPE_INT, ARG_NOMINMAX }, - {"mpsmergeout", &mpsmergeouts, "Merge output with existing file", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"mpsusedepth", &mpsusedepth, - "Use depth values on output (default is ignore)", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - {"mpsuseprox", &mpsuseprox, - "Use proximity values on output (default is ignore)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"snlen", &snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsverout", &mpsverout, + "Version of mapsource file to generate (3,4,5)", NULL, + ARGTYPE_INT, ARG_NOMINMAX + }, + { + "mpsmergeout", &mpsmergeouts, "Merge output with existing file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsusedepth", &mpsusedepth, + "Use depth values on output (default is ignore)", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "mpsuseprox", &mpsuseprox, + "Use proximity values on output (default is ignore)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void +static void mps_noop(const route_head *wp) { - /* no-op */ + /* no-op */ } void mps_wpt_q_init(queue *whichQueue) { - QUEUE_INIT(whichQueue); + QUEUE_INIT(whichQueue); } void mps_wpt_q_deinit(queue *whichQueue) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(whichQueue, elem, tmp) { - waypoint *q = (waypoint *) dequeue(elem); - waypt_free(q); - } + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypoint *q = (waypoint *) dequeue(elem); + waypt_free(q); + } } /* @@ -124,16 +134,16 @@ mps_wpt_q_deinit(queue *whichQueue) waypoint * mps_find_wpt_q_by_name(const queue *whichQueue, const char *name) { - queue *elem, *tmp; - waypoint *waypointp; - - QUEUE_FOR_EACH(whichQueue, elem, tmp) { - waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { - return waypointp; - } - } - return NULL; + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(whichQueue, elem, tmp) { + waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; } /* @@ -143,149 +153,171 @@ mps_find_wpt_q_by_name(const queue *whichQueue, const char *name) void mps_wpt_q_add(const queue *whichQueue, const waypoint *wpt) { - waypoint *written_wpt = waypt_dupe(wpt); - ENQUEUE_TAIL(whichQueue, &written_wpt->Q); + waypoint *written_wpt = waypt_dupe(wpt); + ENQUEUE_TAIL(whichQueue, &written_wpt->Q); } -static int +static int mps_converted_icon_number(const int icon_num, const int mpsver, garmin_formats_e garmin_format) { - int def_icon = DEFAULTICONVALUE; - - switch (garmin_format) { - case MAPSOURCE: - if (mpsver == 5) return icon_num; - if (mpsver == 4) { - /* Water hydrant */ - if (icon_num == 139) return def_icon; - else return icon_num; - } - else { - /* the Contact icons - V3 doesn't have anything like this */ - if ((icon_num >= 119) && (icon_num <= 138)) return def_icon; - /* the Geocache icons - V3 use the Circle with X */ - if ((icon_num >= 117) && (icon_num <= 118)) return 65; - /* Water hydrant */ - if (icon_num == 139) return def_icon; - return icon_num; - } - - case PCX: - case GARMIN_SERIAL: - if (mpsver == 5) return icon_num; - if (mpsver == 4) { - /* Water hydrant */ - if (icon_num == 8282) return def_icon; - else return icon_num; - } - /* the Contact icons - V3 doesn't have anything like this */ - if ((icon_num >= 8257) && (icon_num <= 8276)) return def_icon; - /* the Geocache icons - V3 use the Circle with X */ - if ((icon_num >= 8255) && (icon_num <= 8256)) return 179; - /* Water hydrant */ - if (icon_num == 8282) return def_icon; - return icon_num; - - default: - fatal(MYNAME ": unknown garmin format.\n"); - } - return def_icon; + int def_icon = DEFAULTICONVALUE; + + switch (garmin_format) { + case MAPSOURCE: + if (mpsver == 5) { + return icon_num; + } + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 139) { + return def_icon; + } else { + return icon_num; + } + } else { + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 119) && (icon_num <= 138)) { + return def_icon; + } + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 117) && (icon_num <= 118)) { + return 65; + } + /* Water hydrant */ + if (icon_num == 139) { + return def_icon; + } + return icon_num; + } + + case PCX: + case GARMIN_SERIAL: + if (mpsver == 5) { + return icon_num; + } + if (mpsver == 4) { + /* Water hydrant */ + if (icon_num == 8282) { + return def_icon; + } else { + return icon_num; + } + } + /* the Contact icons - V3 doesn't have anything like this */ + if ((icon_num >= 8257) && (icon_num <= 8276)) { + return def_icon; + } + /* the Geocache icons - V3 use the Circle with X */ + if ((icon_num >= 8255) && (icon_num <= 8256)) { + return 179; + } + /* Water hydrant */ + if (icon_num == 8282) { + return def_icon; + } + return icon_num; + + default: + fatal(MYNAME ": unknown garmin format.\n"); + } + return def_icon; } static void mps_rd_init(const char *fname) { - mps_file_in = gbfopen_le(fname, "rb", MYNAME); + mps_file_in = gbfopen_le(fname, "rb", MYNAME); - read_route_wpt_mkshort_handle = mkshort_new_handle(); - /* initialise the "private" queue of waypoints read for routes */ - mps_wpt_q_init(&read_route_wpt_head); + read_route_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints read for routes */ + mps_wpt_q_init(&read_route_wpt_head); } static void mps_rd_deinit(void) { - gbfclose(mps_file_in); - if ( read_route_wpt_mkshort_handle ) { - mkshort_del_handle( &read_route_wpt_mkshort_handle ); - } - /* flush the "private" queue of waypoints read for routes */ - mps_wpt_q_deinit(&read_route_wpt_head); + gbfclose(mps_file_in); + if (read_route_wpt_mkshort_handle) { + mkshort_del_handle(&read_route_wpt_mkshort_handle); + } + /* flush the "private" queue of waypoints read for routes */ + mps_wpt_q_deinit(&read_route_wpt_head); } static void mps_wr_init(const char *fname) { - fin_name = xstrdup(fname); - if (mpsmergeouts) { - mpsmergeout = atoi(mpsmergeouts); - } - - if (mpsmergeout) { - mps_file_out = gbfopen_le(fname, "rb", MYNAME); - if (mps_file_out == NULL) { - mpsmergeout = 0; - } - else { - gbfclose(mps_file_out); - srand((unsigned) current_time()); - - for (;;) { - /* create a temporary name based on a random char and the existing name */ - /* then test if it already exists, if so try again with another rand num */ - /* yeah, yeah, so there's probably a library function for this */ - xasprintf(&tempname, "%s.%08x", fname, rand()); - mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); - if (mps_file_temp == NULL) break; - gbfclose(mps_file_temp); - } - rename(fname, tempname); - mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); - } - } - - mps_file_out = gbfopen_le(fname, "wb", MYNAME); - - written_wpt_mkshort_handle = mkshort_new_handle(); - /* initialise the "private" queue of waypoints written */ - mps_wpt_q_init(&written_wpt_head); - mps_wpt_q_init(&written_route_wpt_head); + fin_name = xstrdup(fname); + if (mpsmergeouts) { + mpsmergeout = atoi(mpsmergeouts); + } + + if (mpsmergeout) { + mps_file_out = gbfopen_le(fname, "rb", MYNAME); + if (mps_file_out == NULL) { + mpsmergeout = 0; + } else { + gbfclose(mps_file_out); + srand((unsigned) current_time()); + + for (;;) { + /* create a temporary name based on a random char and the existing name */ + /* then test if it already exists, if so try again with another rand num */ + /* yeah, yeah, so there's probably a library function for this */ + xasprintf(&tempname, "%s.%08x", fname, rand()); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + if (mps_file_temp == NULL) { + break; + } + gbfclose(mps_file_temp); + } + rename(fname, tempname); + mps_file_temp = gbfopen_le(tempname, "rb", MYNAME); + } + } + + mps_file_out = gbfopen_le(fname, "wb", MYNAME); + + written_wpt_mkshort_handle = mkshort_new_handle(); + /* initialise the "private" queue of waypoints written */ + mps_wpt_q_init(&written_wpt_head); + mps_wpt_q_init(&written_route_wpt_head); } static void mps_wr_deinit(void) { - gbfclose(mps_file_out); - - if (mpsmergeout) { - gbfclose(mps_file_temp); - remove(tempname); - xfree(tempname); - } - - if ( written_wpt_mkshort_handle ) { - mkshort_del_handle( &written_wpt_mkshort_handle ); - } - /* flush the "private" queue of waypoints written */ - mps_wpt_q_deinit(&written_wpt_head); - mps_wpt_q_deinit(&written_route_wpt_head); - xfree(fin_name); + gbfclose(mps_file_out); + + if (mpsmergeout) { + gbfclose(mps_file_temp); + remove(tempname); + xfree(tempname); + } + + if (written_wpt_mkshort_handle) { + mkshort_del_handle(&written_wpt_mkshort_handle); + } + /* flush the "private" queue of waypoints written */ + mps_wpt_q_deinit(&written_wpt_head); + mps_wpt_q_deinit(&written_route_wpt_head); + xfree(fin_name); } /* - * get characters until and including terminating NULL from mps_file_in + * get characters until and including terminating NULL from mps_file_in * and write into buf. */ static void mps_readstr(gbfile *mps_file, char *buf, size_t sz) { - int c; - while (sz-- && (c = gbfgetc (mps_file)) != EOF) { - *buf++ = c; - if (c == 0) { - return; - } - } + int c; + while (sz-- && (c = gbfgetc(mps_file)) != EOF) { + *buf++ = c; + if (c == 0) { + return; + } + } } /* @@ -295,93 +327,97 @@ mps_readstr(gbfile *mps_file, char *buf, size_t sz) static void mps_fileHeader_r(gbfile *mps_file, int *mps_ver) { - char hdr[100]; - int reclen; - - mps_readstr(mps_file, hdr, sizeof(hdr)); - if ( strcmp( hdr, "MsRcd" )) { - fatal(MYNAME ": This doesn't look like a mapsource file.\n"); - } - /* Read record length of "format details" section */ - reclen = gbfgetint32(mps_file); - /* Read the "format details" in plus the trailing null */ - gbfread( hdr, 3, 1, mps_file); - if (hdr[0] != 'D') { - /* No flag for the "data" section */ - fatal(MYNAME ": This doesn't look like a mapsource file.\n"); - } - if (hdr[1] == 'd') { - *mps_ver = 3; - } - else if ((hdr[1] > 'd') && (hdr[1] <= 'h')) { - *mps_ver = 4; - } - else if ((hdr[1] > 'h') && (hdr[1] <= 'i')) { - *mps_ver = 5; - } - else { - fatal(MYNAME ": Unsuppported version of mapsource file.\n"); - } - /* Skip reliably over the "format details" section */ - gbfseek( mps_file, reclen+1-3, SEEK_CUR); - /* Read record length of "program signature" section */ - reclen = gbfgetint32(mps_file); - /* Skip reliably over the "program signature" section */ - if (reclen >= 0) gbfseek(mps_file, reclen+1, SEEK_CUR); + char hdr[100]; + int reclen; + + mps_readstr(mps_file, hdr, sizeof(hdr)); + if (strcmp(hdr, "MsRcd")) { + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + /* Read record length of "format details" section */ + reclen = gbfgetint32(mps_file); + /* Read the "format details" in plus the trailing null */ + gbfread(hdr, 3, 1, mps_file); + if (hdr[0] != 'D') { + /* No flag for the "data" section */ + fatal(MYNAME ": This doesn't look like a mapsource file.\n"); + } + if (hdr[1] == 'd') { + *mps_ver = 3; + } else if ((hdr[1] > 'd') && (hdr[1] <= 'h')) { + *mps_ver = 4; + } else if ((hdr[1] > 'h') && (hdr[1] <= 'i')) { + *mps_ver = 5; + } else { + fatal(MYNAME ": Unsuppported version of mapsource file.\n"); + } + /* Skip reliably over the "format details" section */ + gbfseek(mps_file, reclen+1-3, SEEK_CUR); + /* Read record length of "program signature" section */ + reclen = gbfgetint32(mps_file); + /* Skip reliably over the "program signature" section */ + if (reclen >= 0) { + gbfseek(mps_file, reclen+1, SEEK_CUR); + } } /* - * write out to file + * write out to file * MRCB */ static void mps_fileHeader_w(gbfile *mps_file, int mps_ver) { - char hdr[100]; - int reclen; - - strcpy (hdr, "MsRc"); - gbfwrite(hdr, 4, 1, mps_file); - - /* Between versions 3 & 5 this value is 'd', but might change in the future */ - strcpy(hdr, "d"); - gbfwrite(hdr, 2, 1, mps_file); /* include trailing NULL char */ - - /* Start of a "Data" section */ - hdr[0] = 'D'; - /* if (mps_ver == 3) */ - hdr[1] = 'd'; /* equates to V3.02 */ - if (mps_ver == 4) hdr[1] = 'g'; /* equates to V4.06 */ - if (mps_ver == 5) hdr[1] = 'i'; /* equates to V5.0 */ - hdr[2] = 0; - - reclen = 2; /* this is 3 byte record */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ - - hdr[0] = 'A'; - /* if (mps_ver == 3) */ - hdr[1] = 0x2E; hdr[2] = 0x01; /* equates to V3.02 */ - hdr[3] = 'S'; - hdr[4] = 'Q'; - hdr[5] = 'A'; - hdr[6] = 0; - strcpy(hdr+7,"Oct 20 1999"); - strcpy(hdr+19,"12:50:33"); - if (mps_ver == 4) { - hdr[1] = (char) 0x96; /* equates to V4.06 */ - strcpy(hdr+7,"Oct 22 2001"); - strcpy(hdr+19,"15:45:33"); - } - if (mps_ver == 5) { - hdr[1] = (char) 0xF4; /* equates to V5.0 */ - strcpy(hdr+7,"Jul 3 2003"); - strcpy(hdr+19,"08:35:33"); - } - - reclen = 27; /* pre measured! */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 28, 1, mps_file); /* reclen + 1 - can't use this as reclen may be wrongendian now */ + char hdr[100]; + int reclen; + + strcpy(hdr, "MsRc"); + gbfwrite(hdr, 4, 1, mps_file); + + /* Between versions 3 & 5 this value is 'd', but might change in the future */ + strcpy(hdr, "d"); + gbfwrite(hdr, 2, 1, mps_file); /* include trailing NULL char */ + + /* Start of a "Data" section */ + hdr[0] = 'D'; + /* if (mps_ver == 3) */ + hdr[1] = 'd'; /* equates to V3.02 */ + if (mps_ver == 4) { + hdr[1] = 'g'; /* equates to V4.06 */ + } + if (mps_ver == 5) { + hdr[1] = 'i'; /* equates to V5.0 */ + } + hdr[2] = 0; + + reclen = 2; /* this is 3 byte record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ + + hdr[0] = 'A'; + /* if (mps_ver == 3) */ + hdr[1] = 0x2E; + hdr[2] = 0x01; /* equates to V3.02 */ + hdr[3] = 'S'; + hdr[4] = 'Q'; + hdr[5] = 'A'; + hdr[6] = 0; + strcpy(hdr+7,"Oct 20 1999"); + strcpy(hdr+19,"12:50:33"); + if (mps_ver == 4) { + hdr[1] = (char) 0x96; /* equates to V4.06 */ + strcpy(hdr+7,"Oct 22 2001"); + strcpy(hdr+19,"15:45:33"); + } + if (mps_ver == 5) { + hdr[1] = (char) 0xF4; /* equates to V5.0 */ + strcpy(hdr+7,"Jul 3 2003"); + strcpy(hdr+19,"08:35:33"); + } + + reclen = 27; /* pre measured! */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 28, 1, mps_file); /* reclen + 1 - can't use this as reclen may be wrongendian now */ } /* @@ -391,28 +427,30 @@ mps_fileHeader_w(gbfile *mps_file, int mps_ver) static void mps_mapsegment_r(gbfile *mps_file, int mps_ver) { - int reclen; + int reclen; #if 0 - /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ - char hdr[100]; - gbfread(&CDid, 4, 1, mps_file); - reclen = le_read32(&CDid); - - gbfread(&CDSegmentid, 4, 1, mps_file); - reclen = le_read32(&CDSegmentid); - - mps_readstr(mps_file, CDName, sizeof(CDName)); - mps_readstr(mps_file, CDSegmentName, sizeof(CDSegmentName)); - mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); - - gbfread(hdr, 4, 1, mps_file); /* trailing long value */ -#endif - - gbfseek(mps_file, -5, SEEK_CUR); - reclen = gbfgetint32(mps_file); - if (reclen >= 0) gbfseek( mps_file, reclen+1, SEEK_CUR); - return; + /* At the moment we're not doing anything with map segments, but here's the template code as if we were */ + char hdr[100]; + gbfread(&CDid, 4, 1, mps_file); + reclen = le_read32(&CDid); + + gbfread(&CDSegmentid, 4, 1, mps_file); + reclen = le_read32(&CDSegmentid); + + mps_readstr(mps_file, CDName, sizeof(CDName)); + mps_readstr(mps_file, CDSegmentName, sizeof(CDSegmentName)); + mps_readstr(mps_file, CDAreaName, sizeof(CDAreaName)); + + gbfread(hdr, 4, 1, mps_file); /* trailing long value */ +#endif + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + if (reclen >= 0) { + gbfseek(mps_file, reclen+1, SEEK_CUR); + } + return; } @@ -424,20 +462,20 @@ mps_mapsegment_r(gbfile *mps_file, int mps_ver) static void mps_mapsetname_r(gbfile *mps_file, int mps_ver) { - int reclen; - - /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were - char hdr[100]; - mps_readstr(mps_file, hdr, sizeof(hdr)); - char mapsetnamename[very large number?]; - strcpy(mapsetnamename,hdr); - char mapsetnameAutonameFlag; - gbfread(&mapsetnameAutonameFlag, 1, 1, mps_file); */ - - gbfseek(mps_file, -5, SEEK_CUR); - reclen = gbfgetint32(mps_file); - gbfseek( mps_file, reclen+1, SEEK_CUR); - return; + int reclen; + + /* At the moment we're not doing anything with mapsetnames, but here's the template code as if we were + char hdr[100]; + mps_readstr(mps_file, hdr, sizeof(hdr)); + char mapsetnamename[very large number?]; + strcpy(mapsetnamename,hdr); + char mapsetnameAutonameFlag; + gbfread(&mapsetnameAutonameFlag, 1, 1, mps_file); */ + + gbfseek(mps_file, -5, SEEK_CUR); + reclen = gbfgetint32(mps_file); + gbfseek(mps_file, reclen+1, SEEK_CUR); + return; } @@ -449,15 +487,15 @@ mps_mapsetname_r(gbfile *mps_file, int mps_ver) static void mps_mapsetname_w(gbfile *mps_file, int mps_ver) { - char hdr[100]; - int reclen; - - hdr[0] = 'V'; /* mapsetname start of record indicator */ - hdr[1] = 0; /* zero length null terminated string */ - hdr[2] = 1; /* mapsetname autoname flag set to DO autoname */ - reclen = 2; /* three bytes of the V record */ - gbfputint32(reclen, mps_file); - gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ + char hdr[100]; + int reclen; + + hdr[0] = 'V'; /* mapsetname start of record indicator */ + hdr[1] = 0; /* zero length null terminated string */ + hdr[2] = 1; /* mapsetname autoname flag set to DO autoname */ + reclen = 2; /* three bytes of the V record */ + gbfputint32(reclen, mps_file); + gbfwrite(hdr, 3, 1, mps_file); /* reclen + 1 */ } @@ -468,99 +506,99 @@ mps_mapsetname_w(gbfile *mps_file, int mps_ver) static void mps_waypoint_r(gbfile *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpsclass) { - char tbuf[100]; - char wptname[MPSNAMEBUFFERLEN]; - char *wptdesc = NULL; - char *wptnotes = NULL; - int lat; - int lon; - int icon; - int dynamic; - - waypoint *thisWaypoint = NULL; - double mps_altitude = unknown_alt; - double mps_proximity = unknown_alt; - double mps_depth = unknown_alt; - - thisWaypoint = waypt_new(); - *wpt = thisWaypoint; - - mps_readstr(mps_file, wptname, sizeof(wptname)); - - (*mpsclass) = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - - gbfread(tbuf,17, 1, mps_file); /* subclass data (17) */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 5, 1, mps_file); /* additional subclass data (1) & terminator? (4) */ - } - - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - wptdesc = gbfgetcstr(mps_file); - - if (gbfgetc(mps_file) == 1) { /* proximity validity */ - mps_proximity = gbfgetdbl(mps_file); - } - else { - mps_proximity = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - (void) gbfgetint32(mps_file); /* display flag */ - (void) gbfgetint32(mps_file); /* colour */ - icon = gbfgetint32(mps_file); /* display symbol */ - - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* city */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* state */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /*facility */ - - gbfread(tbuf, 1, 1, mps_file); /* unknown */ - - if (gbfgetc(mps_file) == 1) { /* depth validity */ - mps_depth = gbfgetdbl( mps_file ); - } - else { - mps_depth = unknown_alt; - (void) gbfseek( mps_file, 8, SEEK_CUR ); - } - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 6, 1, mps_file); /* unknown */ - wptnotes = gbfgetcstr(mps_file); - } - else { - gbfread(tbuf, 2, 1, mps_file); /* unknown */ - } - - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->description = wptdesc; - thisWaypoint->notes = wptnotes; - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - if (mps_proximity != unknown_alt) WAYPT_SET(thisWaypoint, proximity, mps_proximity); - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - - /* might need to change this to handle version dependent icon handling */ - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); - thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; - - /* The following Now done elsewhere since it can be useful to read in and - perhaps not add to the list */ - /* waypt_add(thisWaypoint); */ - - return; + char tbuf[100]; + char wptname[MPSNAMEBUFFERLEN]; + char *wptdesc = NULL; + char *wptnotes = NULL; + int lat; + int lon; + int icon; + int dynamic; + + waypoint *thisWaypoint = NULL; + double mps_altitude = unknown_alt; + double mps_proximity = unknown_alt; + double mps_depth = unknown_alt; + + thisWaypoint = waypt_new(); + *wpt = thisWaypoint; + + mps_readstr(mps_file, wptname, sizeof(wptname)); + + (*mpsclass) = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + gbfread(tbuf,17, 1, mps_file); /* subclass data (17) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 5, 1, mps_file); /* additional subclass data (1) & terminator? (4) */ + } + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + wptdesc = gbfgetcstr(mps_file); + + if (gbfgetc(mps_file) == 1) { /* proximity validity */ + mps_proximity = gbfgetdbl(mps_file); + } else { + mps_proximity = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + (void) gbfgetint32(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ + icon = gbfgetint32(mps_file); /* display symbol */ + + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* city */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* state */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /*facility */ + + gbfread(tbuf, 1, 1, mps_file); /* unknown */ + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl(mps_file); + } else { + mps_depth = unknown_alt; + (void) gbfseek(mps_file, 8, SEEK_CUR); + } + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 6, 1, mps_file); /* unknown */ + wptnotes = gbfgetcstr(mps_file); + } else { + gbfread(tbuf, 2, 1, mps_file); /* unknown */ + } + + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->description = wptdesc; + thisWaypoint->notes = wptnotes; + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_proximity != unknown_alt) { + WAYPT_SET(thisWaypoint, proximity, mps_proximity); + } + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + + /* might need to change this to handle version dependent icon handling */ + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(icon, MAPSOURCE, &dynamic); + thisWaypoint->wpt_flags.icon_descr_is_dynamic = dynamic; + + /* The following Now done elsewhere since it can be useful to read in and + perhaps not add to the list */ + /* waypt_add(thisWaypoint); */ + + return; } /* @@ -570,134 +608,144 @@ mps_waypoint_r(gbfile *mps_file, int mps_ver, waypoint **wpt, unsigned int *mpsc static void mps_waypoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt, const int isRouteWpt) { - int reclen; - int lat, lon; - int icon; - char *src = ""; /* default to empty string */ - char *ident; - char *ascii_description; - char zbuf[25]; - char ffbuf[25]; - int display = 1; - int colour = 0; /* (unknown colour) black is 1, white is 16 */ - - double mps_altitude = wpt->altitude; - double mps_proximity = (mpsuseprox ? WAYPT_GET(wpt, proximity, unknown_alt) : unknown_alt); - double mps_depth = unknown_alt; - - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; - - if(wpt->description) src = wpt->description; - if(wpt->notes) src = wpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - wpt->shortname; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xff, sizeof(ffbuf)); - - /* might need to change this to handle version dependent icon handling */ - icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); - - if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); - } - - icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); - - /* two NULL (0x0) bytes at end of each string */ - ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); - reclen = strlen(ident) + strlen(ascii_description) + 2; - if ((mps_ver == 4) || (mps_ver == 5)) { - /* v4.06 & V5.0*/ - reclen += 85; /* "W" (1) + strlen(name) + NULL (1) + class(4) + country(sz) + + int reclen; + int lat, lon; + int icon; + char *src = ""; /* default to empty string */ + char *ident; + char *ascii_description; + char zbuf[25]; + char ffbuf[25]; + int display = 1; + int colour = 0; /* (unknown colour) black is 1, white is 16 */ + + double mps_altitude = wpt->altitude; + double mps_proximity = (mpsuseprox ? WAYPT_GET(wpt, proximity, unknown_alt) : unknown_alt); + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) { + mps_depth = wpt->depth; + } + + if (wpt->description) { + src = wpt->description; + } + if (wpt->notes) { + src = wpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + /* might need to change this to handle version dependent icon handling */ + icon = gt_find_icon_number_from_desc(wpt->icon_descr, MAPSOURCE); + + if (get_cache_icon(wpt) /* && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)*/) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), MAPSOURCE); + } + + icon = mps_converted_icon_number(icon, mps_ver, MAPSOURCE); + + /* two NULL (0x0) bytes at end of each string */ + ascii_description = wpt->description ? xstrdup(wpt->description) : xstrdup(""); + reclen = strlen(ident) + strlen(ascii_description) + 2; + if ((mps_ver == 4) || (mps_ver == 5)) { + /* v4.06 & V5.0*/ + reclen += 85; /* "W" (1) + strlen(name) + NULL (1) + class(4) + country(sz) + subclass(18) + unknown(4) + lat(4) + lon(4) + alt(9) + strlen(desc) - + NULL (1) + prox(9) + display(4) + colour(4) + symbol(4) + city(sz) + + + NULL (1) + prox(9) + display(4) + colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + unknown2(1) + depth(9) + unknown3(7) */ - /* -1 as reclen is interpreted from zero meaning a reclength of one */ - if (wpt->notes) reclen += strlen(wpt->notes); - } - else { - /* v3.02 */ - reclen += 75; /* "W" (1) + strlen(name) + NULL (1) + + class(4) + country(sz) + - subclass(17) + lat(4) + lon(4) + alt(9) + strlen(desc) + - NULL (1) + prox(9) + display(4) + - colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + if (wpt->notes) { + reclen += strlen(wpt->notes); + } + } else { + /* v3.02 */ + reclen += 75; /* "W" (1) + strlen(name) + NULL (1) + + class(4) + country(sz) + + subclass(17) + lat(4) + lon(4) + alt(9) + strlen(desc) + + NULL (1) + prox(9) + display(4) + + colour(4) + symbol(4) + city(sz) + state(sz) + facility(sz) + unknown2(1) + depth(9) + unknown3(2) */ - /* -1 as reclen is interpreted from zero meaning a reclength of one */ - } - - gbfputint32(reclen, mps_file); - gbfwrite("W", 1, 1, mps_file); - gbfputs(ident, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ - - if (isRouteWpt) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; - else zbuf[0] = (char)MPSDEFAULTWPTCLASS; - gbfwrite(zbuf, 4, 1, mps_file); /* class */ - - zbuf[0]=0; - gbfwrite(zbuf, 1, 1, mps_file); /* country empty string */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ - gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ - } - else { - gbfwrite(zbuf, 8, 1, mps_file); - gbfwrite(ffbuf, 8, 1, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); - } - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - if (wpt->description) gbfputs(ascii_description, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination */ - xfree(ascii_description); - ascii_description = NULL; - - if (mps_proximity == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl( mps_proximity, mps_file ); - } - - gbfputint32(display, mps_file); /* Show waypoint w/ name */ - gbfputint32(colour, mps_file); - gbfputint32(icon, mps_file); - - gbfwrite(zbuf, 3, 1, mps_file); /* city, state, facility */ - - gbfwrite(zbuf, 1, 1, mps_file); /* unknown */ - - if (mps_depth == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_depth, mps_file); - } - - gbfwrite(zbuf, 2, 1, mps_file); /* unknown */ - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* unknown */ - if (wpt->notes) gbfputs(wpt->notes, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* string termination */ - } + /* -1 as reclen is interpreted from zero meaning a reclength of one */ + } + + gbfputint32(reclen, mps_file); + gbfwrite("W", 1, 1, mps_file); + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + if (isRouteWpt) { + zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + } else { + zbuf[0] = (char)MPSDEFAULTWPTCLASS; + } + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + } else { + gbfwrite(zbuf, 8, 1, mps_file); + gbfwrite(ffbuf, 8, 1, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); + } + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + if (wpt->description) { + gbfputs(ascii_description, mps_file); + } + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination */ + xfree(ascii_description); + ascii_description = NULL; + + if (mps_proximity == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_proximity, mps_file); + } + + gbfputint32(display, mps_file); /* Show waypoint w/ name */ + gbfputint32(colour, mps_file); + gbfputint32(icon, mps_file); + + gbfwrite(zbuf, 3, 1, mps_file); /* city, state, facility */ + + gbfwrite(zbuf, 1, 1, mps_file); /* unknown */ + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file); + } + + gbfwrite(zbuf, 2, 1, mps_file); /* unknown */ + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* unknown */ + if (wpt->notes) { + gbfputs(wpt->notes, mps_file); + } + gbfwrite(zbuf, 1, 1, mps_file); /* string termination */ + } } /* @@ -709,22 +757,23 @@ mps_waypoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt, const int isR static void mps_waypoint_w_unique_wrapper(const waypoint *wpt) { - waypoint *wptfound = NULL; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - /* is the next line necessary? Assumes we know who's called us and in what order */ - if (wptfound == NULL) - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - /* if this waypoint hasn't been written then it is okay to do so */ - if (wptfound == NULL) { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - - /* ensure we record in our "private" queue what has been - written so that we don't write it again */ - mps_wpt_q_add(&written_wpt_head, wpt); - } + waypoint *wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + /* if this waypoint hasn't been written then it is okay to do so */ + if (wptfound == NULL) { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + + /* ensure we record in our "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } } /* @@ -738,33 +787,34 @@ mps_waypoint_w_unique_wrapper(const waypoint *wpt) static void mps_route_wpt_w_unique_wrapper(const waypoint *wpt) { - waypoint *wptfound = NULL; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - if (wptfound == NULL) - /* so, not a real wpt, so must check route wpts already written as reals */ - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - /* if this waypoint hasn't been written then it is okay to do so - but assume it is only required for the route + waypoint *wptfound = NULL; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + if (wptfound == NULL) + /* so, not a real wpt, so must check route wpts already written as reals */ + { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + /* if this waypoint hasn't been written then it is okay to do so + but assume it is only required for the route */ - if (wptfound == NULL) { - /* Although we haven't written one out, this might still be a "real" waypoint - If so, we need to write it out now accordingly */ - wptfound = find_waypt_by_name (wpt->shortname); - - if (wptfound == NULL) { - /* well, we tried to find: it wasn't written and isn't a real waypoint */ - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==1)); - mps_wpt_q_add(&written_route_wpt_head, wpt); - } - else { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - /* Simulated real user waypoint */ - mps_wpt_q_add(&written_wpt_head, wpt); - } - } + if (wptfound == NULL) { + /* Although we haven't written one out, this might still be a "real" waypoint + If so, we need to write it out now accordingly */ + wptfound = find_waypt_by_name(wpt->shortname); + + if (wptfound == NULL) { + /* well, we tried to find: it wasn't written and isn't a real waypoint */ + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==1)); + mps_wpt_q_add(&written_route_wpt_head, wpt); + } else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* Simulated real user waypoint */ + mps_wpt_q_add(&written_wpt_head, wpt); + } + } } #if 0 /* @@ -776,38 +826,38 @@ mps_route_wpt_w_unique_wrapper(const waypoint *wpt) static void mps_waypoint_w_uniqloc_wrapper(waypoint *wpt) { - waypoint *wptfound = NULL; - char *newName; - - /* Search for this waypoint in the ones already written */ - wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); - /* is the next line necessary? Assumes we know who's called us and in what order */ - if (wptfound == NULL) - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); - - if (wptfound != NULL) { - /* check if this is the same waypoint by looking at the lat lon - not ideal, but better then having two same named waypoints - that kills MapSource. If it is the same then don't bother - adding it in. If it isn't, then rename it - */ - if (((wpt->latitude - wptfound->latitude) != 0) || - ((wpt->longitude - wptfound->longitude) != 0)) { - /* Not the same lat lon, so rename and add */ - newName = mkshort(written_wpt_mkshort_handle, wpt->shortname); - wptfound = waypt_dupe(wpt); - xfree(wptfound->shortname); - wptfound->shortname = newName; - mps_waypoint_w(mps_file_out, mps_ver_out, wptfound, (1==0)); - mps_wpt_q_add(&written_wpt_head, wpt); - } - } - else { - mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); - /* ensure we record in out "private" queue what has been - written so that we don't write it again */ - mps_wpt_q_add(&written_wpt_head, wpt); - } + waypoint *wptfound = NULL; + char *newName; + + /* Search for this waypoint in the ones already written */ + wptfound = mps_find_wpt_q_by_name(&written_wpt_head, wpt->shortname); + /* is the next line necessary? Assumes we know who's called us and in what order */ + if (wptfound == NULL) { + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, wpt->shortname); + } + + if (wptfound != NULL) { + /* check if this is the same waypoint by looking at the lat lon + not ideal, but better then having two same named waypoints + that kills MapSource. If it is the same then don't bother + adding it in. If it isn't, then rename it + */ + if (((wpt->latitude - wptfound->latitude) != 0) || + ((wpt->longitude - wptfound->longitude) != 0)) { + /* Not the same lat lon, so rename and add */ + newName = mkshort(written_wpt_mkshort_handle, wpt->shortname); + wptfound = waypt_dupe(wpt); + xfree(wptfound->shortname); + wptfound->shortname = newName; + mps_waypoint_w(mps_file_out, mps_ver_out, wptfound, (1==0)); + mps_wpt_q_add(&written_wpt_head, wpt); + } + } else { + mps_waypoint_w(mps_file_out, mps_ver_out, wpt, (1==0)); + /* ensure we record in out "private" queue what has been + written so that we don't write it again */ + mps_wpt_q_add(&written_wpt_head, wpt); + } } #endif @@ -818,248 +868,242 @@ mps_waypoint_w_uniqloc_wrapper(waypoint *wpt) static void mps_route_r(gbfile *mps_file, int mps_ver, route_head **rte) { - char tbuf[100]; - char *rtename; - char wptname[MPSNAMEBUFFERLEN]; - int lat = 0; - int lon = 0; - char rte_autoname; - int interlinkStepCount; - int thisInterlinkStep; - unsigned int mpsclass; - - route_head *rte_head; - int rte_count; - - waypoint *thisWaypoint; - waypoint *tempWpt; - - double mps_altitude = unknown_alt; - double mps_depth = unknown_alt; - - rtename = gbfgetcstr(mps_file); + char tbuf[100]; + char *rtename; + char wptname[MPSNAMEBUFFERLEN]; + int lat = 0; + int lon = 0; + char rte_autoname; + int interlinkStepCount; + int thisInterlinkStep; + unsigned int mpsclass; + + route_head *rte_head; + int rte_count; + + waypoint *thisWaypoint; + waypoint *tempWpt; + + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; + + rtename = gbfgetcstr(mps_file); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading route %s\n", rtename); + fprintf(stderr, "mps_route_r: reading route %s\n", rtename); #endif - gbfread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ + gbfread(&rte_autoname, 1, 1, mps_file); /* autoname flag */ - gbfread(tbuf, 1, 1, mps_file); /* skip min/max values */ - if (tbuf[0] == 0) { + gbfread(tbuf, 1, 1, mps_file); /* skip min/max values */ + if (tbuf[0] == 0) { - lat = gbfgetint32(mps_file); /* max lat of whole route */ - lon = gbfgetint32(mps_file); /* max lon of whole route */ + lat = gbfgetint32(mps_file); /* max lat of whole route */ + lon = gbfgetint32(mps_file); /* max lon of whole route */ - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } - lat = gbfgetint32(mps_file); /* min lat of whole route */ - lon = gbfgetint32(mps_file); /* min lon of whole route */ + lat = gbfgetint32(mps_file); /* min lat of whole route */ + lon = gbfgetint32(mps_file); /* min lon of whole route */ - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - } + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + } - rte_count = gbfgetint32(mps_file); /* number of waypoints in route */ + rte_count = gbfgetint32(mps_file); /* number of waypoints in route */ - /* This might be rather presumptuous, but is it valid in any format to have route with no points? */ - /* Let's assume not, so if the route count is zero or less, let's get out of here and allow the */ - /* caller to do any file resync */ - if (rte_count < 0) return; + /* This might be rather presumptuous, but is it valid in any format to have route with no points? */ + /* Let's assume not, so if the route count is zero or less, let's get out of here and allow the */ + /* caller to do any file resync */ + if (rte_count < 0) { + return; + } #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: route contains %d waypoints\n", rte_count); + fprintf(stderr, "mps_route_r: route contains %d waypoints\n", rte_count); #endif - rte_head = route_head_alloc(); - rte_head->rte_name = rtename; - route_add_head(rte_head); - *rte = rte_head; + rte_head = route_head_alloc(); + rte_head->rte_name = rtename; + route_add_head(rte_head); + *rte = rte_head; - rte_count--; /* need to loop round for one less than the number of waypoints */ + rte_count--; /* need to loop round for one less than the number of waypoints */ - while (rte_count--) { + while (rte_count--) { - mps_readstr(mps_file, wptname, sizeof(wptname)); + mps_readstr(mps_file, wptname, sizeof(wptname)); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading route waypoint %s\n", wptname); + fprintf(stderr, "mps_route_r: reading route waypoint %s\n", wptname); #endif - mpsclass = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ - /* This is a bit unpleasant. Routes have a variable length of - data (min 22 bytes) terminated by a zero */ - do { - gbfread(tbuf, 1, 1, mps_file); - } while (tbuf[0]); + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); - /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ - gbfread(tbuf, 18, 1, mps_file); - } - else { - gbfread(tbuf, 17, 1, mps_file); /* subclass data */ - gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ - } + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } - /* link details */ - interlinkStepCount = gbfgetint32(mps_file); /* NOT always 2, but will assume > 0 */ + /* link details */ + interlinkStepCount = gbfgetint32(mps_file); /* NOT always 2, but will assume > 0 */ #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: interlink steps are %d\n", interlinkStepCount); + fprintf(stderr, "mps_route_r: interlink steps are %d\n", interlinkStepCount); #endif - /* Basically we're knackered if the step count is less than one since we hard code reading of the */ - /* first, so if there isn't one, we'd lose sync on the file and read junk */ - /* Given we've already done some route head allocation, do we return or do we die? It'd be good */ - /* do some clean up before returning. */ - if (interlinkStepCount < 1) { - /* For RJL - are the following lines correct ? */ - /* route_free(rte_head); - route_del_head(rte_head); */ - return; - } - - /* first end of link */ - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl(mps_file); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there - if found. With MapSource, one should consider the real waypoint list as definitive */ - tempWpt = find_waypt_by_name(wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - /* should never reach here, but we do need a fallback position */ + /* Basically we're knackered if the step count is less than one since we hard code reading of the */ + /* first, so if there isn't one, we'd lose sync on the file and read junk */ + /* Given we've already done some route head allocation, do we return or do we die? It'd be good */ + /* do some clean up before returning. */ + if (interlinkStepCount < 1) { + /* For RJL - are the following lines correct ? */ + /* route_free(rte_head); + route_del_head(rte_head); */ + return; + } + + /* first end of link */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found. With MapSource, one should consider the real waypoint list as definitive */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + /* should never reach here, but we do need a fallback position */ #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reached the point we never should\n"); + fprintf(stderr, "mps_route_r: reached the point we never should\n"); #endif - thisWaypoint = waypt_new(); - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - } - } - - route_add_wpt(rte_head, thisWaypoint); - - /* take two off the count since we separately read the start and end parts of the link */ - /* MRCB 2004/09/15 - NOPE, sorry, this needs to one, since interlink steps can be > 0 */ - for (thisInterlinkStep = interlinkStepCount - 1; thisInterlinkStep > 0; thisInterlinkStep--) { - /* Could do this by doing a calculation on length of each co-ordinate and just doing one read - but doing it this way makes it easier in the future to make use of this data */ - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl( mps_file ); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - } - - gbfread(tbuf, 1, 1, mps_file); /* NULL */ - - gbfread(tbuf, 4, 1, mps_file); /* link max lat */ - gbfread(tbuf, 4, 1, mps_file); /* link max lon */ - gbfread(tbuf, 9, 1, mps_file); /* link max alt validity + alt */ - - gbfread(tbuf, 4, 1, mps_file); /* link min lat */ - gbfread(tbuf, 4, 1, mps_file); /* link min lon */ - gbfread(tbuf, 9, 1, mps_file); /* link min alt validity + alt */ - - } /* while (trk_count--) */ - - /* when the loop is done, there's still one waypoint to read with a small trailer */ - /* all we want is the waypoint name; lat, lon and alt are already set from above */ - mps_readstr(mps_file, wptname, sizeof(wptname)); + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + } + } + + route_add_wpt(rte_head, thisWaypoint); + + /* take two off the count since we separately read the start and end parts of the link */ + /* MRCB 2004/09/15 - NOPE, sorry, this needs to one, since interlink steps can be > 0 */ + for (thisInterlinkStep = interlinkStepCount - 1; thisInterlinkStep > 0; thisInterlinkStep--) { + /* Could do this by doing a calculation on length of each co-ordinate and just doing one read + but doing it this way makes it easier in the future to make use of this data */ + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + } + + gbfread(tbuf, 1, 1, mps_file); /* NULL */ + + gbfread(tbuf, 4, 1, mps_file); /* link max lat */ + gbfread(tbuf, 4, 1, mps_file); /* link max lon */ + gbfread(tbuf, 9, 1, mps_file); /* link max alt validity + alt */ + + gbfread(tbuf, 4, 1, mps_file); /* link min lat */ + gbfread(tbuf, 4, 1, mps_file); /* link min lon */ + gbfread(tbuf, 9, 1, mps_file); /* link min alt validity + alt */ + + } /* while (trk_count--) */ + + /* when the loop is done, there's still one waypoint to read with a small trailer */ + /* all we want is the waypoint name; lat, lon and alt are already set from above */ + mps_readstr(mps_file, wptname, sizeof(wptname)); #ifdef MPS_DEBUG - fprintf(stderr, "mps_route_r: reading final route waypoint %s\n", wptname); + fprintf(stderr, "mps_route_r: reading final route waypoint %s\n", wptname); #endif - mpsclass = gbfgetint32(mps_file); /* class */ - mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfread(tbuf, 22, 1, mps_file); /* subclass data */ - - /* This is a bit unpleasant. Routes have a variable length of - data (min 22 bytes) terminated by a zero */ - do { - gbfread(tbuf, 1, 1, mps_file); - } while (tbuf[0]); - - /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ - gbfread(tbuf, 18, 1, mps_file); - } - else { - gbfread(tbuf, 17, 1, mps_file); /* subclass data */ - gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ - } - - gbfread(tbuf, 5, 1, mps_file); /* 5 byte trailer */ - /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there - if found because there is more info held in a real waypoint than in its route counterpart, - e.g. the display symbol (aka icon) - */ - tempWpt = find_waypt_by_name(wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); - - if (tempWpt != NULL) { - thisWaypoint = waypt_dupe(tempWpt); - } - else { - /* should never reach here, but we do need a fallback position */ - thisWaypoint = waypt_new(); - thisWaypoint->shortname = xstrdup(wptname); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->altitude = mps_altitude; - } - } - - route_add_wpt(rte_head, thisWaypoint); - - return; + mpsclass = gbfgetint32(mps_file); /* class */ + mps_readstr(mps_file, tbuf, sizeof(tbuf)); /* country */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfread(tbuf, 22, 1, mps_file); /* subclass data */ + + /* This is a bit unpleasant. Routes have a variable length of + data (min 22 bytes) terminated by a zero */ + do { + gbfread(tbuf, 1, 1, mps_file); + } while (tbuf[0]); + + /* The next thing is the unknown 0x03 0x00 .. 0x00 (18 bytes) */ + gbfread(tbuf, 18, 1, mps_file); + } else { + gbfread(tbuf, 17, 1, mps_file); /* subclass data */ + gbfread(tbuf, 18, 1, mps_file); /* unknown 0x00 0x03 0x00 .. 0x00 */ + } + + gbfread(tbuf, 5, 1, mps_file); /* 5 byte trailer */ + /* with MapSource routes, the real waypoint details are held as a separate waypoint, so copy from there + if found because there is more info held in a real waypoint than in its route counterpart, + e.g. the display symbol (aka icon) + */ + tempWpt = find_waypt_by_name(wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + tempWpt = mps_find_wpt_q_by_name(&read_route_wpt_head, wptname); + + if (tempWpt != NULL) { + thisWaypoint = waypt_dupe(tempWpt); + } else { + /* should never reach here, but we do need a fallback position */ + thisWaypoint = waypt_new(); + thisWaypoint->shortname = xstrdup(wptname); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->altitude = mps_altitude; + } + } + + route_add_wpt(rte_head, thisWaypoint); + + return; } /* @@ -1069,149 +1113,162 @@ mps_route_r(gbfile *mps_file, int mps_ver, route_head **rte) static void mps_routehdr_w(gbfile *mps_file, int mps_ver, const route_head *rte) { - unsigned int reclen; - unsigned int rte_datapoints; - int rname_len; - char *rname; - char hdr[20]; - char zbuf[20]; - char *src = ""; - char *ident; - - waypoint *testwpt; - time_t uniqueValue = 0; - int allWptNameLengths; - - double maxlat=-90.0; - double maxlon=-180.0; - double minlat=90.0; - double minlon=180.0; - double maxalt=unknown_alt; - double minalt=-unknown_alt; - - int lat; - int lon; - - queue *elem, *tmp; - - prevRouteWpt = NULL; /* clear the stateful flag used to know when the start of route wpts happens */ - - memset(zbuf, 0, sizeof(zbuf)); - - /* total nodes (waypoints) this route */ - rte_datapoints = 0; - allWptNameLengths = 0; - - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - testwpt = (waypoint *)elem; - if (rte_datapoints == 0) { - uniqueValue = testwpt->creation_time; - } - if (testwpt->latitude > maxlat) maxlat = testwpt->latitude; - if (testwpt->latitude < minlat) minlat = testwpt->latitude; - if (testwpt->longitude > maxlon) maxlon = testwpt->longitude; - if (testwpt->longitude < minlon) minlon = testwpt->longitude; - if (testwpt->altitude != unknown_alt) { - if ((testwpt->altitude > maxalt) || - (maxalt == unknown_alt)) maxalt = testwpt->altitude; - if ((testwpt->altitude < minalt) || - (minalt == -unknown_alt)) minalt = testwpt->altitude; - } - - if(testwpt->description) src = testwpt->description; - if(testwpt->notes) src = testwpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - testwpt->shortname; - allWptNameLengths += strlen(ident) + 1; - - rte_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* route name */ - if (!rte->rte_name) { - sprintf(hdr, "Route%04x", (unsigned) uniqueValue); - rname = xstrdup(hdr); - } - else - rname = xstrdup(rte->rte_name); - - rname_len = strlen(rname); - reclen = rname_len + 42; /* "T" (1) + strlen(tname) + NULL (1) + autoname flag (2) + + unsigned int reclen; + unsigned int rte_datapoints; + int rname_len; + char *rname; + char hdr[20]; + char zbuf[20]; + char *src = ""; + char *ident; + + waypoint *testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + double maxlat=-90.0; + double maxlon=-180.0; + double minlat=90.0; + double minlon=180.0; + double maxalt=unknown_alt; + double minalt=-unknown_alt; + + int lat; + int lon; + + queue *elem, *tmp; + + prevRouteWpt = NULL; /* clear the stateful flag used to know when the start of route wpts happens */ + + memset(zbuf, 0, sizeof(zbuf)); + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint *)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + if (testwpt->latitude > maxlat) { + maxlat = testwpt->latitude; + } + if (testwpt->latitude < minlat) { + minlat = testwpt->latitude; + } + if (testwpt->longitude > maxlon) { + maxlon = testwpt->longitude; + } + if (testwpt->longitude < minlon) { + minlon = testwpt->longitude; + } + if (testwpt->altitude != unknown_alt) { + if ((testwpt->altitude > maxalt) || + (maxalt == unknown_alt)) { + maxalt = testwpt->altitude; + } + if ((testwpt->altitude < minalt) || + (minalt == -unknown_alt)) { + minalt = testwpt->altitude; + } + } + + if (testwpt->description) { + src = testwpt->description; + } + if (testwpt->notes) { + src = testwpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + testwpt->shortname; + allWptNameLengths += strlen(ident) + 1; + + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } else { + rname = xstrdup(rte->rte_name); + } + + rname_len = strlen(rname); + reclen = rname_len + 42; /* "T" (1) + strlen(tname) + NULL (1) + autoname flag (2) + route lat lon max (2x4) + route max alt (9) + route lat lon min (2x4) + route min alt (9) + num route datapoints value (4) */ - - /* V3 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + - subclass (17) + unknown (18) */ - /* V4,5 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + - subclass (18) + unknown (4) + unknown (19) */ - /* V* - each route link: 0x00000002 (4) + end 1 lat (4) + end 1 lon (4) + end 1 alt (9) + - end 2 lat (4) + end 2 lon (4) + end 2 alt (9) + NULL (1) + - link max lat (4) + link max lon (4) + link max alt (9) + - link min lat (4) + link min lon (4) + link min alt (9) */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - reclen += allWptNameLengths + rte_datapoints * 46 + - (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ - } - else { - reclen += allWptNameLengths + rte_datapoints * 40 + - (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ - } - - gbfputint32(reclen, mps_file); - gbfputc('R', mps_file); - gbfwrite(rname, 1, rname_len, mps_file); - - xfree(rname); - - hdr[0] = 0; /* NULL of string termination */ - hdr[1] = 0; /* don't autoname */ - hdr[2] = 0; /* MSB of don't autoname */ - gbfwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ - - lat = GPS_Math_Deg_To_Semi(maxlat); - lon = GPS_Math_Deg_To_Semi(maxlon); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (maxalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(maxalt, mps_file); - } - - lat = GPS_Math_Deg_To_Semi(minlat); - lon = GPS_Math_Deg_To_Semi(minlon); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (minalt == -unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(minalt, mps_file); - } - - gbfputint32(rte_datapoints, mps_file); - } + + /* V3 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (17) + unknown (18) */ + /* V4,5 - each waypoint: waypoint name + NULL (1) + class (4) + country + NULL (1) + + subclass (18) + unknown (4) + unknown (19) */ + /* V* - each route link: 0x00000002 (4) + end 1 lat (4) + end 1 lon (4) + end 1 alt (9) + + end 2 lat (4) + end 2 lon (4) + end 2 alt (9) + NULL (1) + + link max lat (4) + link max lon (4) + link max alt (9) + + link min lat (4) + link min lon (4) + link min alt (9) */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + reclen += allWptNameLengths + rte_datapoints * 46 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } else { + reclen += allWptNameLengths + rte_datapoints * 40 + + (rte_datapoints - 1) * 73 + 4; /* link details plus overall trailing bytes */ + } + + gbfputint32(reclen, mps_file); + gbfputc('R', mps_file); + gbfwrite(rname, 1, rname_len, mps_file); + + xfree(rname); + + hdr[0] = 0; /* NULL of string termination */ + hdr[1] = 0; /* don't autoname */ + hdr[2] = 0; /* MSB of don't autoname */ + gbfwrite(hdr, 3, 1, mps_file); /* NULL string terminator + route autoname flag */ + + lat = GPS_Math_Deg_To_Semi(maxlat); + lon = GPS_Math_Deg_To_Semi(maxlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + lat = GPS_Math_Deg_To_Semi(minlat); + lon = GPS_Math_Deg_To_Semi(minlon); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (minalt == -unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file); + } + + gbfputint32(rte_datapoints, mps_file); + } } static void mps_routehdr_w_wrapper(const route_head *rte) { - mps_routehdr_w(mps_file_out, mps_ver_out, rte); + mps_routehdr_w(mps_file_out, mps_ver_out, rte); } @@ -1222,164 +1279,172 @@ mps_routehdr_w_wrapper(const route_head *rte) static void mps_routedatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *rtewpt) { - int lat; - int lon; - char zbuf[20]; - char ffbuf[20]; - char *src = ""; - char *ident; - int reclen; - - int maxlat; - int maxlon; - int minlat; - int minlon; - double maxalt=unknown_alt; - double minalt=-unknown_alt; - - double mps_altitude; - waypoint *wptfound; - - memset(zbuf, 0, sizeof(zbuf)); - memset(ffbuf, 0xff, sizeof(ffbuf)); - - if (prevRouteWpt != NULL) { - /* output the route link details */ - reclen = 2; - gbfputint32(reclen, mps_file); - - /* output end point 1 */ - lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - mps_altitude = prevRouteWpt->altitude; - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file ); - } - - /* output end point 2 */ - lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - mps_altitude = rtewpt->altitude; - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - - if (rtewpt->latitude > prevRouteWpt->latitude) { - maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - } - else { - minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); - maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); - } - - if (rtewpt->longitude > prevRouteWpt->longitude) { - maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - } - else { - minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); - maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); - } - - if (rtewpt->altitude != unknown_alt) maxalt = rtewpt->altitude; - if (rtewpt->altitude != unknown_alt) minalt = rtewpt->altitude; - if (prevRouteWpt->altitude != unknown_alt) { - if ((prevRouteWpt->altitude > maxalt) || - (maxalt == unknown_alt)) maxalt = prevRouteWpt->altitude; - if ((prevRouteWpt->altitude < minalt) || - (minalt == -unknown_alt)) minalt = prevRouteWpt->altitude; - } - - gbfwrite (zbuf, 1, 1, mps_file); - - /* output max coords of the link */ - gbfputint32(maxlat, mps_file); - gbfputint32(maxlon, mps_file); - - if (maxalt == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(maxalt, mps_file); - } - - /* output min coords of the link */ - gbfputint32(minlat, mps_file); - gbfputint32(minlon, mps_file); - - if (minalt == -unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(minalt, mps_file ); - } - - } - - if(rtewpt->description) src = rtewpt->description; - if(rtewpt->notes) src = rtewpt->notes; - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - rtewpt->shortname; - - gbfputs(ident, mps_file); - gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ - - wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, ident); - if (wptfound != NULL) zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; - else zbuf[0] = (char)MPSDEFAULTWPTCLASS; - gbfwrite(zbuf, 4, 1, mps_file); /* class */ - - zbuf[0]=0; - gbfwrite(zbuf, 1, 1, mps_file); /* country - i.e. empty string */ - - if ((mps_ver == 4) || (mps_ver == 5)) { - gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ - gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ - - gbfwrite(zbuf, 1, 1, mps_file); - gbfputc(3, mps_file); - gbfwrite(zbuf, 17, 1, mps_file); - } - else { - gbfwrite(zbuf, 8, 1, mps_file); /* subclass part 1 */ - gbfwrite(ffbuf, 8, 1, mps_file); /* subclass part 2 */ - gbfwrite(zbuf, 1, 1, mps_file); /* subclass part 3 */ - - /* unknown */ - gbfwrite(zbuf, 1, 1, mps_file); - gbfputc(3, mps_file); - gbfwrite(zbuf, 16, 1, mps_file); - } - - prevRouteWpt = rtewpt; + int lat; + int lon; + char zbuf[20]; + char ffbuf[20]; + char *src = ""; + char *ident; + int reclen; + + int maxlat; + int maxlon; + int minlat; + int minlon; + double maxalt=unknown_alt; + double minalt=-unknown_alt; + + double mps_altitude; + waypoint *wptfound; + + memset(zbuf, 0, sizeof(zbuf)); + memset(ffbuf, 0xff, sizeof(ffbuf)); + + if (prevRouteWpt != NULL) { + /* output the route link details */ + reclen = 2; + gbfputint32(reclen, mps_file); + + /* output end point 1 */ + lat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + lon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = prevRouteWpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + /* output end point 2 */ + lat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + lon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + mps_altitude = rtewpt->altitude; + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (rtewpt->latitude > prevRouteWpt->latitude) { + maxlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + minlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } else { + minlat = GPS_Math_Deg_To_Semi(rtewpt->latitude); + maxlat = GPS_Math_Deg_To_Semi(prevRouteWpt->latitude); + } + + if (rtewpt->longitude > prevRouteWpt->longitude) { + maxlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + minlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } else { + minlon = GPS_Math_Deg_To_Semi(rtewpt->longitude); + maxlon = GPS_Math_Deg_To_Semi(prevRouteWpt->longitude); + } + + if (rtewpt->altitude != unknown_alt) { + maxalt = rtewpt->altitude; + } + if (rtewpt->altitude != unknown_alt) { + minalt = rtewpt->altitude; + } + if (prevRouteWpt->altitude != unknown_alt) { + if ((prevRouteWpt->altitude > maxalt) || + (maxalt == unknown_alt)) { + maxalt = prevRouteWpt->altitude; + } + if ((prevRouteWpt->altitude < minalt) || + (minalt == -unknown_alt)) { + minalt = prevRouteWpt->altitude; + } + } + + gbfwrite(zbuf, 1, 1, mps_file); + + /* output max coords of the link */ + gbfputint32(maxlat, mps_file); + gbfputint32(maxlon, mps_file); + + if (maxalt == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(maxalt, mps_file); + } + + /* output min coords of the link */ + gbfputint32(minlat, mps_file); + gbfputint32(minlon, mps_file); + + if (minalt == -unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(minalt, mps_file); + } + + } + + if (rtewpt->description) { + src = rtewpt->description; + } + if (rtewpt->notes) { + src = rtewpt->notes; + } + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + rtewpt->shortname; + + gbfputs(ident, mps_file); + gbfwrite(zbuf, 1, 1, mps_file); /* NULL termination to ident */ + + wptfound = mps_find_wpt_q_by_name(&written_route_wpt_head, ident); + if (wptfound != NULL) { + zbuf[0] = (char)MPSHIDDENROUTEWPTCLASS; + } else { + zbuf[0] = (char)MPSDEFAULTWPTCLASS; + } + gbfwrite(zbuf, 4, 1, mps_file); /* class */ + + zbuf[0]=0; + gbfwrite(zbuf, 1, 1, mps_file); /* country - i.e. empty string */ + + if ((mps_ver == 4) || (mps_ver == 5)) { + gbfwrite(zbuf, 4, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 12, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 2, 1, mps_file); /* subclass part 3 */ + gbfwrite(ffbuf, 4, 1, mps_file); /* unknown */ + + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 17, 1, mps_file); + } else { + gbfwrite(zbuf, 8, 1, mps_file); /* subclass part 1 */ + gbfwrite(ffbuf, 8, 1, mps_file); /* subclass part 2 */ + gbfwrite(zbuf, 1, 1, mps_file); /* subclass part 3 */ + + /* unknown */ + gbfwrite(zbuf, 1, 1, mps_file); + gbfputc(3, mps_file); + gbfwrite(zbuf, 16, 1, mps_file); + } + + prevRouteWpt = rtewpt; } static void mps_routedatapoint_w_wrapper(const waypoint *rte) { - mps_routedatapoint_w(mps_file_out, mps_ver_out, rte); + mps_routedatapoint_w(mps_file_out, mps_ver_out, rte); } @@ -1390,21 +1455,21 @@ mps_routedatapoint_w_wrapper(const waypoint *rte) static void mps_routetrlr_w(gbfile *mps_file, int mps_ver, const route_head *rte) { - char hdr[2]; - int value = 0; + char hdr[2]; + int value = 0; - hdr[0] = 1; + hdr[0] = 1; - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - gbfwrite(&value, 4, 1, mps_file); - gbfwrite(hdr, 1, 1, mps_file); - } + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + gbfwrite(&value, 4, 1, mps_file); + gbfwrite(hdr, 1, 1, mps_file); + } } - + static void mps_routetrlr_w_wrapper(const route_head *rte) { - mps_routetrlr_w(mps_file_out, mps_ver_out, rte); + mps_routetrlr_w(mps_file_out, mps_ver_out, rte); } @@ -1415,82 +1480,83 @@ mps_routetrlr_w_wrapper(const route_head *rte) static void mps_track_r(gbfile *mps_file, int mps_ver, route_head **trk) { - char *trkname; - int lat; - int lon; + char *trkname; + int lat; + int lon; - int dateTime = 0; - route_head *track_head; - int trk_count; + int dateTime = 0; + route_head *track_head; + int trk_count; - waypoint *thisWaypoint; - double mps_altitude = unknown_alt; - double mps_depth = unknown_alt; + waypoint *thisWaypoint; + double mps_altitude = unknown_alt; + double mps_depth = unknown_alt; - trkname = gbfgetcstr(mps_file); + trkname = gbfgetcstr(mps_file); #ifdef MPS_DEBUG - fprintf(stderr, "mps_track_r: reading track %s\n", trkname); + fprintf(stderr, "mps_track_r: reading track %s\n", trkname); #endif - (void) gbfgetc(mps_file); /* display flag */ - (void) gbfgetint32(mps_file); /* colour */ + (void) gbfgetc(mps_file); /* display flag */ + (void) gbfgetint32(mps_file); /* colour */ - trk_count = gbfgetint32(mps_file); /* number of datapoints in tracklog */ + trk_count = gbfgetint32(mps_file); /* number of datapoints in tracklog */ - /* I don't know, but perhaps it's valid to have a track with no waypoints */ - /* Seems dumb, but truth is stranger than fiction. Of course, it could be */ - /* that there are more than MAXINT / 2 waypoints, yeah sure */ - /* Allow the caller the perform the file resync caused by bombing out early */ - if (trk_count < 0) return; + /* I don't know, but perhaps it's valid to have a track with no waypoints */ + /* Seems dumb, but truth is stranger than fiction. Of course, it could be */ + /* that there are more than MAXINT / 2 waypoints, yeah sure */ + /* Allow the caller the perform the file resync caused by bombing out early */ + if (trk_count < 0) { + return; + } #ifdef MPS_DEBUG - fprintf(stderr, "mps_track_r: there are %d track waypoints %d\n", trk_count); + fprintf(stderr, "mps_track_r: there are %d track waypoints %d\n", trk_count); #endif - track_head = route_head_alloc(); - track_head->rte_name = trkname; - track_add_head(track_head); - *trk = track_head; - - while (trk_count--) { - - lat = gbfgetint32(mps_file); - lon = gbfgetint32(mps_file); - - if (gbfgetc(mps_file) == 1) { /* altitude validity */ - mps_altitude = gbfgetdbl( mps_file ); - } - else { - mps_altitude = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - if (gbfgetc(mps_file) == 1) { /* date/time validity */ - dateTime = gbfgetint32(mps_file); - } - else { - (void) gbfgetint32(mps_file); - } - - if (gbfgetc(mps_file) == 1) { /* depth validity */ - mps_depth = gbfgetdbl(mps_file ); - } - else { - mps_depth = unknown_alt; - gbfseek( mps_file, 8, SEEK_CUR ); - } - - thisWaypoint = waypt_new(); - thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); - thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); - thisWaypoint->creation_time = dateTime; - thisWaypoint->microseconds = 0; - thisWaypoint->altitude = mps_altitude; - if (mps_depth != unknown_alt) WAYPT_SET(thisWaypoint, depth, mps_depth); - track_add_wpt(track_head, thisWaypoint); - - } /* while (trk_count--) */ - - return; + track_head = route_head_alloc(); + track_head->rte_name = trkname; + track_add_head(track_head); + *trk = track_head; + + while (trk_count--) { + + lat = gbfgetint32(mps_file); + lon = gbfgetint32(mps_file); + + if (gbfgetc(mps_file) == 1) { /* altitude validity */ + mps_altitude = gbfgetdbl(mps_file); + } else { + mps_altitude = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + if (gbfgetc(mps_file) == 1) { /* date/time validity */ + dateTime = gbfgetint32(mps_file); + } else { + (void) gbfgetint32(mps_file); + } + + if (gbfgetc(mps_file) == 1) { /* depth validity */ + mps_depth = gbfgetdbl(mps_file); + } else { + mps_depth = unknown_alt; + gbfseek(mps_file, 8, SEEK_CUR); + } + + thisWaypoint = waypt_new(); + thisWaypoint->latitude = GPS_Math_Semi_To_Deg(lat); + thisWaypoint->longitude = GPS_Math_Semi_To_Deg(lon); + thisWaypoint->creation_time = dateTime; + thisWaypoint->microseconds = 0; + thisWaypoint->altitude = mps_altitude; + if (mps_depth != unknown_alt) { + WAYPT_SET(thisWaypoint, depth, mps_depth); + } + track_add_wpt(track_head, thisWaypoint); + + } /* while (trk_count--) */ + + return; } @@ -1501,67 +1567,67 @@ mps_track_r(gbfile *mps_file, int mps_ver, route_head **trk) static void mps_trackhdr_w(gbfile *mps_file, int mps_ver, const route_head *trk) { - unsigned int reclen; - unsigned int trk_datapoints; - unsigned int colour = 0; /* unknown colour */ - int tname_len; - char *tname; - char hdr[20]; - waypoint *testwpt; - time_t uniqueValue = 0; - - queue *elem, *tmp; - - /* total nodes (waypoints) this track */ - trk_datapoints = 0; - if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - if (trk_datapoints == 0) { - testwpt = (waypoint *)elem; - uniqueValue = testwpt->creation_time; - } - trk_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* track name */ - if (!trk->rte_name) { - sprintf(hdr, "Track%04x", (unsigned) uniqueValue); - tname = xstrdup(hdr); - } - else - tname = xstrdup(trk->rte_name); - - tname_len = strlen(tname); - reclen = tname_len + 11; /* "T" (1) + strlen(tname) + NULL (1) + display flag (1) + colour (4) + + unsigned int reclen; + unsigned int trk_datapoints; + unsigned int colour = 0; /* unknown colour */ + int tname_len; + char *tname; + char hdr[20]; + waypoint *testwpt; + time_t uniqueValue = 0; + + queue *elem, *tmp; + + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint *)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } else { + tname = xstrdup(trk->rte_name); + } + + tname_len = strlen(tname); + reclen = tname_len + 11; /* "T" (1) + strlen(tname) + NULL (1) + display flag (1) + colour (4) + num track datapoints value (4) */ - - reclen += (trk_datapoints * 31) - 1; /* lat (4) + lon (4) + alt (9) + date (5) + depth (9) ;*/ - /* -1 is because reclen starts from 0 which means a length of 1 */ - gbfputint32(reclen, mps_file); - gbfputc('T', mps_file); - gbfwrite(tname, 1, tname_len, mps_file); - xfree(tname); + reclen += (trk_datapoints * 31) - 1; /* lat (4) + lon (4) + alt (9) + date (5) + depth (9) ;*/ + /* -1 is because reclen starts from 0 which means a length of 1 */ + gbfputint32(reclen, mps_file); + gbfputc('T', mps_file); + gbfwrite(tname, 1, tname_len, mps_file); + + xfree(tname); - hdr[0] = 0; - hdr[1] = 1; - gbfwrite(hdr, 2, 1, mps_file); /* NULL string terminator + display flag */ + hdr[0] = 0; + hdr[1] = 1; + gbfwrite(hdr, 2, 1, mps_file); /* NULL string terminator + display flag */ - gbfputint32(colour, mps_file); + gbfputint32(colour, mps_file); - gbfputint32(trk_datapoints, mps_file); - } + gbfputint32(trk_datapoints, mps_file); + } } static void mps_trackhdr_w_wrapper(const route_head *trk) { - mps_trackhdr_w(mps_file_out, mps_ver_out, trk); + mps_trackhdr_w(mps_file_out, mps_ver_out, trk); } @@ -1572,449 +1638,463 @@ mps_trackhdr_w_wrapper(const route_head *trk) static void mps_trackdatapoint_w(gbfile *mps_file, int mps_ver, const waypoint *wpt) { - int lat, lon; - time_t t = wpt->creation_time; - char zbuf[10]; - - double mps_altitude = wpt->altitude; - double mps_depth = unknown_alt; - - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (WAYPT_HAS(wpt, depth) && mpsusedepth) mps_depth = wpt->depth; - - memset(zbuf, 0, sizeof(zbuf)); - - gbfputint32(lat, mps_file); - gbfputint32(lon, mps_file); - - if (mps_altitude == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_altitude, mps_file); - } - - if (t > 0) { /* a valid time is assumed to > 0 */ - gbfputc(1, mps_file); - gbfputint32(t, mps_file); - } - else { - gbfwrite(zbuf, 5, 1, mps_file); - } - - if (mps_depth == unknown_alt) { - gbfwrite(zbuf, 9, 1, mps_file); - } - else { - gbfputc(1, mps_file); - gbfputdbl(mps_depth, mps_file ); - } + int lat, lon; + time_t t = wpt->creation_time; + char zbuf[10]; + + double mps_altitude = wpt->altitude; + double mps_depth = unknown_alt; + + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); + if (WAYPT_HAS(wpt, depth) && mpsusedepth) { + mps_depth = wpt->depth; + } + + memset(zbuf, 0, sizeof(zbuf)); + + gbfputint32(lat, mps_file); + gbfputint32(lon, mps_file); + + if (mps_altitude == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_altitude, mps_file); + } + + if (t > 0) { /* a valid time is assumed to > 0 */ + gbfputc(1, mps_file); + gbfputint32(t, mps_file); + } else { + gbfwrite(zbuf, 5, 1, mps_file); + } + + if (mps_depth == unknown_alt) { + gbfwrite(zbuf, 9, 1, mps_file); + } else { + gbfputc(1, mps_file); + gbfputdbl(mps_depth, mps_file); + } } static void mps_trackdatapoint_w_wrapper(const waypoint *wpt) { - mps_trackdatapoint_w(mps_file_out, mps_ver_out, wpt); + mps_trackdatapoint_w(mps_file_out, mps_ver_out, wpt); } static void mps_read(void) { - waypoint *wpt; - route_head *rte; - route_head *trk; + waypoint *wpt; + route_head *rte; + route_head *trk; - char recType; - int reclen; - int morework; - unsigned int mpsWptClass; - long mpsFileInPos; + char recType; + int reclen; + int morework; + unsigned int mpsWptClass; + long mpsFileInPos; - mps_ver_in = 0; /* although initialised at declaration, what happens if there are two mapsource + mps_ver_in = 0; /* although initialised at declaration, what happens if there are two mapsource input files? */ - mps_fileHeader_r(mps_file_in, &mps_ver_in); + mps_fileHeader_r(mps_file_in, &mps_ver_in); #ifdef DUMP_ICON_TABLE - printf("static icon_mapping_t garmin_icon_table[] = {\n"); + printf("static icon_mapping_t garmin_icon_table[] = {\n"); #endif - morework = 1; - while (morework && !gbfeof(mps_file_in)) { + morework = 1; + while (morework && !gbfeof(mps_file_in)) { - /* Read record length of next section */ - reclen = gbfgetint32(mps_file_in); + /* Read record length of next section */ + reclen = gbfgetint32(mps_file_in); - if (reclen < 0) fatal (MYNAME ": a record length read from the input file is invalid. \nEither the file is corrupt or unsupported.\n"); + if (reclen < 0) { + fatal(MYNAME ": a record length read from the input file is invalid. \nEither the file is corrupt or unsupported.\n"); + } - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_in); - mpsFileInPos = gbftell(mps_file_in); - switch (recType) { - case 'W': - /* Waypoint record */ - /* With routes, we need the waypoint info that reveals, for example, the symbol type */ - mps_waypoint_r(mps_file_in, mps_ver_in, &wpt, &mpsWptClass); + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_in); + mpsFileInPos = gbftell(mps_file_in); + switch (recType) { + case 'W': + /* Waypoint record */ + /* With routes, we need the waypoint info that reveals, for example, the symbol type */ + mps_waypoint_r(mps_file_in, mps_ver_in, &wpt, &mpsWptClass); #ifdef MPS_DEBUG - fprintf(stderr,"Read a waypoint - %s\n", wpt->shortname); + fprintf(stderr,"Read a waypoint - %s\n", wpt->shortname); #endif - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading waypoint - %s\n", wpt->shortname); + fprintf(stderr,"Lost sync with the file reading waypoint - %s\n", wpt->shortname); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - waypt_free( wpt ); - } - else { - /* only add to the "real" list if a "user" waypoint otherwise add to the private list */ - if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt); - else { - mps_wpt_q_add(&read_route_wpt_head, wpt); - waypt_free( wpt ); - } + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + waypt_free(wpt); + } else { + /* only add to the "real" list if a "user" waypoint otherwise add to the private list */ + if (mpsWptClass == MPSDEFAULTWPTCLASS) { + waypt_add(wpt); + } else { + mps_wpt_q_add(&read_route_wpt_head, wpt); + waypt_free(wpt); + } #ifdef DUMP_ICON_TABLE - printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); #endif - } - break; - - case 'R': - /* Route record */ - mps_route_r(mps_file_in, mps_ver_in, &rte); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + } + break; + + case 'R': + /* Route record */ + mps_route_r(mps_file_in, mps_ver_in, &rte); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading route - %s\n", rte->rte_name); + fprintf(stderr,"Lost sync with the file reading route - %s\n", rte->rte_name); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'T': - /* Track record */ - mps_track_r(mps_file_in, mps_ver_in, &trk); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'T': + /* Track record */ + mps_track_r(mps_file_in, mps_ver_in, &trk); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ #ifdef MPS_DEBUG - fprintf(stderr,"Lost sync with the file reading track - %s\n", trk->rte_name); + fprintf(stderr,"Lost sync with the file reading track - %s\n", trk->rte_name); #endif - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'L': - /* Map segment record */ - mps_mapsegment_r(mps_file_in, mps_ver_in); - if (gbftell(mps_file_in) != mpsFileInPos + reclen) { - /* should junk this record and not save it since we're out of sync with the file */ - /* Should and how do we warn the user? */ - gbfseek (mps_file_in, mpsFileInPos + reclen, SEEK_SET); - } - break; - - case 'V': - /* Mapset record */ - mps_mapsetname_r(mps_file_in, mps_ver_in); - /* Last record in the file */ - morework = 0; - break; - default: - /* Unknown record type. Skip over it. */ - gbfseek(mps_file_in, reclen, SEEK_CUR); - } - - } /* while (!gbfeof(mps_file_in)) */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'L': + /* Map segment record */ + mps_mapsegment_r(mps_file_in, mps_ver_in); + if (gbftell(mps_file_in) != mpsFileInPos + reclen) { + /* should junk this record and not save it since we're out of sync with the file */ + /* Should and how do we warn the user? */ + gbfseek(mps_file_in, mpsFileInPos + reclen, SEEK_SET); + } + break; + + case 'V': + /* Mapset record */ + mps_mapsetname_r(mps_file_in, mps_ver_in); + /* Last record in the file */ + morework = 0; + break; + default: + /* Unknown record type. Skip over it. */ + gbfseek(mps_file_in, reclen, SEEK_CUR); + } + + } /* while (!gbfeof(mps_file_in)) */ #ifdef DUMP_ICON_TABLE - printf("\t{ -1, NULL },\n"); - printf("};\n"); + printf("\t{ -1, NULL },\n"); + printf("};\n"); #endif - return ; + return ; } void mps_write(void) { - int short_length; - waypoint *wpt; - route_head *rte; - route_head *trk; - - char recType; - int reclen; - /* TODO: This kills a compiler warning but I'm not sure it's right */ - int reclen2 = 0; - unsigned int tocopy; - unsigned int block; - - long tempFilePos; - unsigned int mpsWptClass; - - unsigned char copybuf[8192]; - - short_length = atoi(snlen); - - if (mpsmergeout) { - /* need to skip over the merging header and test merge version */ - mps_fileHeader_r(mps_file_temp, &mps_ver_temp); - - if (mpsverout) { - if (mps_ver_temp != atoi(mpsverout)) { - /* Need to clean up after a junk version specified */ - /* close the real output file + renamed original output file */ - /* then delete the "real" file and rename the temporarily renamed file back */ - gbfclose(mps_file_temp); - gbfclose(mps_file_out); - remove(fin_name); - rename(tempname, fin_name); - fatal (MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); - } - } - else { - mpsverout = xmalloc(10); - sprintf(mpsverout,"%d", mps_ver_temp); - } - } - - if (mpsverout) - mps_ver_out = atoi(mpsverout); - else - mps_ver_out = 5; - - mkshort_handle = mkshort_new_handle(); - - setshort_length(mkshort_handle, short_length); - - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); - else - setshort_whitespace_ok(mkshort_handle, 0); - - mps_fileHeader_w(mps_file_out, mps_ver_out); - - /* .mps file order is wpts, rtes, trks then mapsets. If we've not been asked to write - wpts, but we are merging, then read in the waypoints from the original file and - write them out, prior to doing rtes. - */ - /* if ((mpsmergeout) && (global_opts.objective != wptdata)) { */ - if ((mpsmergeout) && (! doing_wpts)) { - while (!gbfeof(mps_file_temp)) { - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - if (recType == 'W') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - tempFilePos = gbftell(mps_file_temp); - /* need to read in the waypoint info only because later we may need to check for uniqueness - since we're here because the user didn't request waypoints, this should be acceptable */ - mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); - mps_wpt_q_add(&written_wpt_head, wpt); - waypt_free( wpt ); - /* now return to the start of the waypoint data to do a "clean" copy */ - gbfseek(mps_file_temp, tempFilePos, SEEK_SET); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* irrespective of merging, now write out any waypoints */ - /* if (global_opts.objective == wptdata) { */ - if (doing_wpts) { - - if (mpsmergeout) { - /* since we're processing waypoints, we should read in from whatever version and write out */ - /* in the selected version */ - while (!gbfeof(mps_file_temp)) { - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - if (recType == 'W') { - /* need to be careful that we aren't duplicating a wpt defined from elsewhere */ - mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); - if (mpsWptClass == MPSDEFAULTWPTCLASS) waypt_add(wpt);else waypt_free(wpt); - } - else break; - } - } - waypt_disp_all(mps_waypoint_w_unique_wrapper); - } - - /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes - from the original file and then write them out, ready for tracks to follow - */ - - /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */ - if ((mpsmergeout) && (! doing_rtes)) { - while (!gbfeof(mps_file_temp)) { - - /* this might all fail if the relevant waypoints haven't been written */ - if (recType == 'R') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* routes are next in the wpts, rtes, trks, mapset sequence */ - /* if (global_opts.objective == rtedata) { */ - if (doing_rtes) { - - if (mpsmergeout) { - /* since we're processing routes, we should read in from whatever version and write out */ - /* in the selected version */ - while (!gbfeof(mps_file_temp)) { - - if (recType == 'R') { - mps_route_r(mps_file_temp, mps_ver_temp, &rte); - } - else break; - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - } - /* need to make sure there is a "real" waypoint for each route waypoint - Need to be careful about creating duplicate wpts as MapSource chokes on these - so, if the user requested waypoints to be output too, then write the route - waypoints only if unique in the total list of waypoints ("real" and route derived) - If the user didn't request waypoints to be output, then output the route derived - waypoints without consideration for uniqueness for "real" waypoints that haven't - been output (phew!) - */ - route_disp_all(mps_noop, mps_noop, mps_route_wpt_w_unique_wrapper); - - route_disp_all(mps_routehdr_w_wrapper, mps_routetrlr_w_wrapper, mps_routedatapoint_w_wrapper); - } - - /* If merging but we haven't been requested to write out tracks, then read in tracks from - the original file and write these out prior to any mapset writes later on - */ - /* if ((mpsmergeout) && (global_opts.objective != trkdata)) { */ - if ((mpsmergeout) && (! doing_trks)) { - while (!gbfeof(mps_file_temp)) { - - if (recType == 'T') { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - } - else break; - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - - } /* while (!gbfeof(mps_file_temp)) */ - } /* if (mpsmergeout) */ - - /* tracks are next in the wpts, rte, trks, mapset sequence in .mps files */ - /* if (global_opts.objective == trkdata) { */ - if (doing_trks) { - if (mpsmergeout) { - /* since we're processing tracks, we should read in from whatever version and write out - in the selected version */ - while (!gbfeof(mps_file_temp)) { - - if (recType == 'T') { - mps_track_r(mps_file_temp, mps_ver_temp, &trk); - } - else break; - - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - } - track_disp_all(mps_trackhdr_w_wrapper, mps_noop, mps_trackdatapoint_w_wrapper); - } - - if (mpsmergeout) { - /* should now be reading a either a map segment or a mapset - since we would write out an empty one, - let's use the one from the merge file which may well have decent data in */ - for (;;) { - gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ - gbfwrite(&recType, 1, 1, mps_file_out); - - /* copy the data using a "reasonably" sized buffer */ - for(tocopy = reclen2; tocopy > 0; tocopy -= block) { - block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); - gbfread(copybuf, block, 1, mps_file_temp); - gbfwrite(copybuf, block, 1, mps_file_out); - } - - if (recType != 'V') { - reclen2 = gbfgetint32(mps_file_temp); - - /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ - gbfread(&recType, 1, 1, mps_file_temp); - } - else break; - } - - } - else mps_mapsetname_w(mps_file_out, mps_ver_out); - - mkshort_del_handle(&mkshort_handle); + int short_length; + waypoint *wpt; + route_head *rte; + route_head *trk; + + char recType; + int reclen; + /* TODO: This kills a compiler warning but I'm not sure it's right */ + int reclen2 = 0; + unsigned int tocopy; + unsigned int block; + + long tempFilePos; + unsigned int mpsWptClass; + + unsigned char copybuf[8192]; + + short_length = atoi(snlen); + + if (mpsmergeout) { + /* need to skip over the merging header and test merge version */ + mps_fileHeader_r(mps_file_temp, &mps_ver_temp); + + if (mpsverout) { + if (mps_ver_temp != atoi(mpsverout)) { + /* Need to clean up after a junk version specified */ + /* close the real output file + renamed original output file */ + /* then delete the "real" file and rename the temporarily renamed file back */ + gbfclose(mps_file_temp); + gbfclose(mps_file_out); + remove(fin_name); + rename(tempname, fin_name); + fatal(MYNAME ": merge source version is %d, requested out version is %d\n", mps_ver_temp, atoi(mpsverout)); + } + } else { + mpsverout = xmalloc(10); + sprintf(mpsverout,"%d", mps_ver_temp); + } + } + + if (mpsverout) { + mps_ver_out = atoi(mpsverout); + } else { + mps_ver_out = 5; + } + + mkshort_handle = mkshort_new_handle(); + + setshort_length(mkshort_handle, short_length); + + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } else { + setshort_whitespace_ok(mkshort_handle, 0); + } + + mps_fileHeader_w(mps_file_out, mps_ver_out); + + /* .mps file order is wpts, rtes, trks then mapsets. If we've not been asked to write + wpts, but we are merging, then read in the waypoints from the original file and + write them out, prior to doing rtes. + */ + /* if ((mpsmergeout) && (global_opts.objective != wptdata)) { */ + if ((mpsmergeout) && (! doing_wpts)) { + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + tempFilePos = gbftell(mps_file_temp); + /* need to read in the waypoint info only because later we may need to check for uniqueness + since we're here because the user didn't request waypoints, this should be acceptable */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + mps_wpt_q_add(&written_wpt_head, wpt); + waypt_free(wpt); + /* now return to the start of the waypoint data to do a "clean" copy */ + gbfseek(mps_file_temp, tempFilePos, SEEK_SET); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* irrespective of merging, now write out any waypoints */ + /* if (global_opts.objective == wptdata) { */ + if (doing_wpts) { + + if (mpsmergeout) { + /* since we're processing waypoints, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + if (recType == 'W') { + /* need to be careful that we aren't duplicating a wpt defined from elsewhere */ + mps_waypoint_r(mps_file_temp, mps_ver_temp, &wpt, &mpsWptClass); + if (mpsWptClass == MPSDEFAULTWPTCLASS) { + waypt_add(wpt); + } else { + waypt_free(wpt); + } + } else { + break; + } + } + } + waypt_disp_all(mps_waypoint_w_unique_wrapper); + } + + /* prior to writing any tracks as requested, if we're doing a merge, read in the rtes + from the original file and then write them out, ready for tracks to follow + */ + + /* if ((mpsmergeout) && (global_opts.objective != rtedata)) { */ + if ((mpsmergeout) && (! doing_rtes)) { + while (!gbfeof(mps_file_temp)) { + + /* this might all fail if the relevant waypoints haven't been written */ + if (recType == 'R') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* routes are next in the wpts, rtes, trks, mapset sequence */ + /* if (global_opts.objective == rtedata) { */ + if (doing_rtes) { + + if (mpsmergeout) { + /* since we're processing routes, we should read in from whatever version and write out */ + /* in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'R') { + mps_route_r(mps_file_temp, mps_ver_temp, &rte); + } else { + break; + } + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + /* need to make sure there is a "real" waypoint for each route waypoint + Need to be careful about creating duplicate wpts as MapSource chokes on these + so, if the user requested waypoints to be output too, then write the route + waypoints only if unique in the total list of waypoints ("real" and route derived) + If the user didn't request waypoints to be output, then output the route derived + waypoints without consideration for uniqueness for "real" waypoints that haven't + been output (phew!) + */ + route_disp_all(mps_noop, mps_noop, mps_route_wpt_w_unique_wrapper); + + route_disp_all(mps_routehdr_w_wrapper, mps_routetrlr_w_wrapper, mps_routedatapoint_w_wrapper); + } + + /* If merging but we haven't been requested to write out tracks, then read in tracks from + the original file and write these out prior to any mapset writes later on + */ + /* if ((mpsmergeout) && (global_opts.objective != trkdata)) { */ + if ((mpsmergeout) && (! doing_trks)) { + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + } else { + break; + } + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + + } /* while (!gbfeof(mps_file_temp)) */ + } /* if (mpsmergeout) */ + + /* tracks are next in the wpts, rte, trks, mapset sequence in .mps files */ + /* if (global_opts.objective == trkdata) { */ + if (doing_trks) { + if (mpsmergeout) { + /* since we're processing tracks, we should read in from whatever version and write out + in the selected version */ + while (!gbfeof(mps_file_temp)) { + + if (recType == 'T') { + mps_track_r(mps_file_temp, mps_ver_temp, &trk); + } else { + break; + } + + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } + } + track_disp_all(mps_trackhdr_w_wrapper, mps_noop, mps_trackdatapoint_w_wrapper); + } + + if (mpsmergeout) { + /* should now be reading a either a map segment or a mapset - since we would write out an empty one, + let's use the one from the merge file which may well have decent data in */ + for (;;) { + gbfwrite(&reclen, 4, 1, mps_file_out); /* write out untouched */ + gbfwrite(&recType, 1, 1, mps_file_out); + + /* copy the data using a "reasonably" sized buffer */ + for (tocopy = reclen2; tocopy > 0; tocopy -= block) { + block = (tocopy > sizeof(copybuf) ? sizeof(copybuf) : tocopy); + gbfread(copybuf, block, 1, mps_file_temp); + gbfwrite(copybuf, block, 1, mps_file_out); + } + + if (recType != 'V') { + reclen2 = gbfgetint32(mps_file_temp); + + /* Read the record type "flag" in - using gbfread in case in the future need more than one char */ + gbfread(&recType, 1, 1, mps_file_temp); + } else { + break; + } + } + + } else { + mps_mapsetname_w(mps_file_out, mps_ver_out); + } + + mkshort_del_handle(&mkshort_handle); } ff_vecs_t mps_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - mps_rd_init, - mps_wr_init, - mps_rd_deinit, - mps_wr_deinit, - mps_read, - mps_write, - NULL, - mps_args, - CET_CHARSET_MS_ANSI /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + mps_rd_init, + mps_wr_init, + mps_rd_deinit, + mps_wr_deinit, + mps_read, + mps_write, + NULL, + mps_args, + CET_CHARSET_MS_ANSI /* CET-REVIEW */ }; diff --git a/gpsbabel/mkicondoc.c b/gpsbabel/mkicondoc.c index ac4d30b8f..b38ad6850 100644 --- a/gpsbabel/mkicondoc.c +++ b/gpsbabel/mkicondoc.c @@ -10,58 +10,58 @@ tbl_ent(int n, ...) { - int i; - char *t; - va_list args; - va_start(args, n); + int i; + char *t; + va_list args; + va_start(args, n); #if 0 - for (i = 0; i < n; i++) { - t = va_arg(args, char *); -printf("%s%s", i > 0 ? "," : "", t); - - } + for (i = 0; i < n; i++) { + t = va_arg(args, char *); + printf("%s%s", i > 0 ? "," : "", t); + + } #else - t = va_arg(args, char*); - printf("%s", t); + t = va_arg(args, char*); + printf("%s", t); #endif -printf("\n"); - va_end(args); - - + printf("\n"); + va_end(args); + + } #include "garmin_tables.c" sort_garmin(const void *a, const void *b) { - const icon_mapping_t *ap = a; - const icon_mapping_t *bp = b; - return (case_ignore_strcmp((ap)->icon, (bp)->icon)); + const icon_mapping_t *ap = a; + const icon_mapping_t *bp = b; + return (case_ignore_strcmp((ap)->icon, (bp)->icon)); } garmin() { - icon_mapping_t *i; - int n = 0; - char pbuf[100]; - char mbuf[100]; + icon_mapping_t *i; + int n = 0; + char pbuf[100]; + char mbuf[100]; - for (i = garmin_icon_table; i->icon; i++) { - n++; - } + for (i = garmin_icon_table; i->icon; i++) { + n++; + } - qsort(garmin_icon_table, - n, - sizeof(garmin_icon_table[0]), - sort_garmin); + qsort(garmin_icon_table, + n, + sizeof(garmin_icon_table[0]), + sort_garmin); - for (i = garmin_icon_table; i->icon; i++) { - snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); - snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); - tbl_ent(3, i->icon, pbuf, mbuf); - } + for (i = garmin_icon_table; i->icon; i++) { + snprintf(pbuf, sizeof(pbuf), "%d", i->pcxsymnum); + snprintf(mbuf, sizeof(mbuf), "%d", i->mpssymnum); + tbl_ent(3, i->icon, pbuf, mbuf); + } } main() { - garmin(); + garmin(); } diff --git a/gpsbabel/mkshort.c b/gpsbabel/mkshort.c index 33b1cb9d5..f177fdc76 100644 --- a/gpsbabel/mkshort.c +++ b/gpsbabel/mkshort.c @@ -35,62 +35,62 @@ static const char vowels[] = "aeiouAEIOU"; static const char *DEFAULT_BADCHARS = "\"$.,'!-"; /* - * Hash table tunings. The reality is that our hash doesn't have to be + * Hash table tunings. The reality is that our hash doesn't have to be * terribly complex; our strings are short (typically 8-20 bytes) and the * string hash mixes things up enough that strcmp can generally bail on the - * first byte or two for a mismatch. + * first byte or two for a mismatch. */ #define PRIME 37 typedef struct { - unsigned int target_len; - char *badchars; - char *goodchars; - char *defname; - queue namelist[PRIME]; - - /* Various internal flags at end to allow alignment flexibility. */ - unsigned int mustupper:1; - unsigned int whitespaceok:1; - unsigned int repeating_whitespaceok:1; - unsigned int must_uniq:1; - unsigned int is_utf8:1; + unsigned int target_len; + char *badchars; + char *goodchars; + char *defname; + queue namelist[PRIME]; + + /* Various internal flags at end to allow alignment flexibility. */ + unsigned int mustupper:1; + unsigned int whitespaceok:1; + unsigned int repeating_whitespaceok:1; + unsigned int must_uniq:1; + unsigned int is_utf8:1; } mkshort_handle; typedef struct { - queue list; - char *orig_shortname; - int conflictctr; + queue list; + char *orig_shortname; + int conflictctr; } uniq_shortname; static struct replacements { - const char *orig; - const char *replacement; + const char *orig; + const char *replacement; } replacements[] = { - {"zero", "0"}, - {"one", "1"}, - {"two", "2"}, - {"three", "3"}, - {"four", "4"}, - {"five", "5"}, - {"six", "6"}, - {"seven", "7"}, - {"eight", "8"}, - {"nine", "9"}, - {NULL, NULL} + {"zero", "0"}, + {"one", "1"}, + {"two", "2"}, + {"three", "3"}, + {"four", "4"}, + {"five", "5"}, + {"six", "6"}, + {"seven", "7"}, + {"eight", "8"}, + {"nine", "9"}, + {NULL, NULL} }; -/* +/* * We hash all strings as upper case. */ unsigned int hash_string(const char *key) { - unsigned int hash = 0; - while (*key) { - hash = ((hash<<5) ^ (hash>>27)) ^ toupper(*key++); - } - hash = hash % PRIME; - return hash; + unsigned int hash = 0; + while (*key) { + hash = ((hash<<5) ^ (hash>>27)) ^ toupper(*key++); + } + hash = hash % PRIME; + return hash; } void * @@ -100,143 +100,146 @@ MKSHORT_NEW_HANDLE(DEBUG_PARAMS) mkshort_new_handle() #endif { - int i; - mkshort_handle *h = (mkshort_handle *) xxcalloc(sizeof *h, 1, file, line); + int i; + mkshort_handle *h = (mkshort_handle *) xxcalloc(sizeof *h, 1, file, line); - for (i = 0; i < PRIME; i++) - QUEUE_INIT(&h->namelist[i]); + for (i = 0; i < PRIME; i++) { + QUEUE_INIT(&h->namelist[i]); + } - h->whitespaceok = 1; - h->badchars = xstrdup(DEFAULT_BADCHARS); - h->target_len = DEFAULT_TARGET_LEN; - h->must_uniq = 1; - h->defname = xstrdup("WPT"); - h->is_utf8 = (global_opts.charset == &cet_cs_vec_utf8); + h->whitespaceok = 1; + h->badchars = xstrdup(DEFAULT_BADCHARS); + h->target_len = DEFAULT_TARGET_LEN; + h->must_uniq = 1; + h->defname = xstrdup("WPT"); + h->is_utf8 = (global_opts.charset == &cet_cs_vec_utf8); - return h; + return h; } -static +static uniq_shortname * is_unique(mkshort_handle *h, char *name) { - queue *e, *t; - int hash; - - hash = hash_string(name); - QUEUE_FOR_EACH(&h->namelist[hash], e, t) { - uniq_shortname *z = (uniq_shortname *) e; - if (0 == case_ignore_strcmp(z->orig_shortname, name)) { - return z; - } - } - return (uniq_shortname *) NULL; + queue *e, *t; + int hash; + + hash = hash_string(name); + QUEUE_FOR_EACH(&h->namelist[hash], e, t) { + uniq_shortname *z = (uniq_shortname *) e; + if (0 == case_ignore_strcmp(z->orig_shortname, name)) { + return z; + } + } + return (uniq_shortname *) NULL; } static void add_to_hashlist(mkshort_handle *h, char *name) { - int hash = hash_string(name); - uniq_shortname *s = (uniq_shortname*) xcalloc(1, sizeof (uniq_shortname)); + int hash = hash_string(name); + uniq_shortname *s = (uniq_shortname*) xcalloc(1, sizeof(uniq_shortname)); - s->orig_shortname = xstrdup(name); - ENQUEUE_TAIL(&h->namelist[hash], &s->list); + s->orig_shortname = xstrdup(name); + ENQUEUE_TAIL(&h->namelist[hash], &s->list); } char * mkshort_add_to_list(mkshort_handle *h, char *name) { - uniq_shortname *s; + uniq_shortname *s; - while ((s = is_unique(h, name))) { - int dl; - char tbuf[10]; - size_t l = strlen(name); + while ((s = is_unique(h, name))) { + int dl; + char tbuf[10]; + size_t l = strlen(name); - s->conflictctr++; + s->conflictctr++; - dl = sprintf(tbuf, ".%d", s->conflictctr); + dl = sprintf(tbuf, ".%d", s->conflictctr); - if (l + dl < h->target_len) { - name = (char *) xrealloc(name, l + dl + 1); - strcat(name, tbuf); - } - else { - strcpy(&name[l-dl], tbuf); - } - } + if (l + dl < h->target_len) { + name = (char *) xrealloc(name, l + dl + 1); + strcat(name, tbuf); + } else { + strcpy(&name[l-dl], tbuf); + } + } - add_to_hashlist(h, name); - return name; + add_to_hashlist(h, name); + return name; } void mkshort_del_handle(short_handle *h) { - mkshort_handle *hdr = (mkshort_handle*) *h; - int i; + mkshort_handle *hdr = (mkshort_handle*) *h; + int i; - if (!h || !hdr) - return; + if (!h || !hdr) { + return; + } - for (i = 0; i < PRIME; i++) { - queue *e, *t; - QUEUE_FOR_EACH(&hdr->namelist[i], e, t) { - uniq_shortname *s = (uniq_shortname *) e; + for (i = 0; i < PRIME; i++) { + queue *e, *t; + QUEUE_FOR_EACH(&hdr->namelist[i], e, t) { + uniq_shortname *s = (uniq_shortname *) e; #if 0 - if (global_opts.verbose_status >= 2 && s->conflictctr) { - fprintf(stderr, "%d Output name conflicts: '%s'\n", - s->conflictctr, s->orig_shortname); - } + if (global_opts.verbose_status >= 2 && s->conflictctr) { + fprintf(stderr, "%d Output name conflicts: '%s'\n", + s->conflictctr, s->orig_shortname); + } #endif - dequeue(e); - xfree(s->orig_shortname); - xfree(s); - } - } - /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ - if (hdr->badchars != NULL) { - xfree(hdr->badchars); - } - setshort_goodchars(*h, NULL); - if (hdr->defname) { - xfree(hdr->defname); - } - - xfree(hdr); - *h = NULL; + dequeue(e); + xfree(s->orig_shortname); + xfree(s); + } + } + /* setshort_badchars(*h, NULL); ! currently setshort_badchars() always allocates something ! */ + if (hdr->badchars != NULL) { + xfree(hdr->badchars); + } + setshort_goodchars(*h, NULL); + if (hdr->defname) { + xfree(hdr->defname); + } + + xfree(hdr); + *h = NULL; } /* * This is the stuff that makes me ashamed to be a C programmer... */ -static +static char * delete_last_vowel(int start, char *istring, int *replaced) { - int l; - - /* - * Basically impelement strrchr. - */ - *replaced = 0; - for (l = strlen(istring); l > start; l--) { - if (strchr(vowels, istring[l-1])) { - char *ostring; - /* If vowel is the first letter of a word, keep it.*/ - if (istring[l-2] == ' ') continue; - ostring = xstrdup(istring); - strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l); - ostring[strlen(istring)-1] = 0; - *replaced = 1; - strcpy( istring, ostring ); - xfree(ostring); - break; - } - } - return istring; + int l; + + /* + * Basically impelement strrchr. + */ + *replaced = 0; + for (l = strlen(istring); l > start; l--) { + if (strchr(vowels, istring[l-1])) { + char *ostring; + /* If vowel is the first letter of a word, keep it.*/ + if (istring[l-2] == ' ') { + continue; + } + ostring = xstrdup(istring); + strncpy(&ostring[l-1], &istring[l], 1+strlen(istring)-l); + ostring[strlen(istring)-1] = 0; + *replaced = 1; + strcpy(istring, ostring); + xfree(ostring); + break; + } + } + return istring; } /* @@ -246,22 +249,22 @@ delete_last_vowel(int start, char *istring, int *replaced) void replace_constants(char *s) { - struct replacements *r; - int origslen = strlen(s); - - for (r = replacements; r->orig; r++) { - int rl = strlen(r->orig); - /* - * If word is in replacement list and preceeded by a - * space, replace it. - */ - if ((origslen - rl > 1) && - (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && - (s[origslen - rl - 1] == ' ')) { - strcpy(&s[origslen - rl], r->replacement); - return ; -} - } + struct replacements *r; + int origslen = strlen(s); + + for (r = replacements; r->orig; r++) { + int rl = strlen(r->orig); + /* + * If word is in replacement list and preceeded by a + * space, replace it. + */ + if ((origslen - rl > 1) && + (0 == case_ignore_strcmp(r->orig, &s[origslen - rl])) && + (s[origslen - rl - 1] == ' ')) { + strcpy(&s[origslen - rl], r->replacement); + return ; + } + } } @@ -272,35 +275,35 @@ replace_constants(char *s) void setshort_length(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - if (l == 0) { - hdl->target_len = DEFAULT_TARGET_LEN; - } else { - hdl->target_len = l; - } + mkshort_handle *hdl = (mkshort_handle *) h; + if (l == 0) { + hdl->target_len = DEFAULT_TARGET_LEN; + } else { + hdl->target_len = l; + } } /* * Call with L nonzero if whitespace in the generated shortname is wanted. */ - + void setshort_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->whitespaceok = l; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->whitespaceok = l; } /* - * Call with L nonzero if multiple consecutive whitespace in the + * Call with L nonzero if multiple consecutive whitespace in the * generated shortname is wanted. */ void setshort_repeating_whitespace_ok(short_handle h, int l) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->repeating_whitespaceok = l; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->repeating_whitespaceok = l; } /* @@ -310,13 +313,14 @@ setshort_repeating_whitespace_ok(short_handle h, int l) void setshort_defname(short_handle h, const char *s) { - mkshort_handle *hdl = (mkshort_handle *) h; - if (s == NULL) { - fatal("setshort_defname called without a valid name."); - } - if (hdl->defname != NULL) - xfree(hdl->defname); - hdl->defname = xstrdup(s); + mkshort_handle *hdl = (mkshort_handle *) h; + if (s == NULL) { + fatal("setshort_defname called without a valid name."); + } + if (hdl->defname != NULL) { + xfree(hdl->defname); + } + hdl->defname = xstrdup(s); } /* @@ -327,28 +331,31 @@ setshort_defname(short_handle h, const char *s) void setshort_badchars(short_handle h, const char *s) { - mkshort_handle *hdl = (mkshort_handle *) h; + mkshort_handle *hdl = (mkshort_handle *) h; - if ((hdl->badchars != NULL)) - xfree(hdl->badchars); - hdl->badchars = xstrdup (s ? s : DEFAULT_BADCHARS); + if ((hdl->badchars != NULL)) { + xfree(hdl->badchars); + } + hdl->badchars = xstrdup(s ? s : DEFAULT_BADCHARS); } /* - * Only characters that appear in *s are "whitelisted" to appear + * Only characters that appear in *s are "whitelisted" to appear * in generated names. */ void setshort_goodchars(short_handle h, const char *s) { - mkshort_handle *hdl = (mkshort_handle *) h; - - if (hdl->goodchars != NULL) - xfree(hdl->goodchars); - if (s != NULL) - hdl->goodchars = xstrdup(s); - else - hdl->goodchars = NULL; + mkshort_handle *hdl = (mkshort_handle *) h; + + if (hdl->goodchars != NULL) { + xfree(hdl->goodchars); + } + if (s != NULL) { + hdl->goodchars = xstrdup(s); + } else { + hdl->goodchars = NULL; + } } /* @@ -357,222 +364,228 @@ setshort_goodchars(short_handle h, const char *s) void setshort_mustupper(short_handle h, int i) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->mustupper = i; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->mustupper = i; } -/* +/* * Call with i zero if the generated names don't have to be unique. * (By default, they are.) */ void setshort_mustuniq(short_handle h, int i) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->must_uniq = i; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->must_uniq = i; } -/* +/* * Declare that actually characters are (or are not) encoded in UTF-8. */ void setshort_is_utf8(short_handle h, const int is_utf8) { - mkshort_handle *hdl = (mkshort_handle *) h; - hdl->is_utf8 = is_utf8; + mkshort_handle *hdl = (mkshort_handle *) h; + hdl->is_utf8 = is_utf8; } char * #ifdef DEBUG_MEM -MKSHORT(short_handle h, const char *istring, DEBUG_PARAMS ) +MKSHORT(short_handle h, const char *istring, DEBUG_PARAMS) #else mkshort(short_handle h, const char *istring) #endif { - char *ostring; - char *nstring; - char *tstring; - char *cp; - char *np; - int i, l, nlen, replaced; - mkshort_handle *hdl = (mkshort_handle *) h; - - if (hdl->is_utf8) ostring = cet_utf8_strdup(istring); /* clean UTF-8 string */ - else ostring = xxstrdup(istring, file, line); - - /* - * A rather horrible special case hack. - * If the target length is "6" and the source length is "7" and - * the first two characters are "GC", we'll assume it's one of the - * the new seven digit geocache numbers and special case whacking - * the 'G' off the front. - */ - if ((hdl->target_len == 6) && (strlen(ostring) == 7) && - (ostring[0] == 'G') && (ostring[1] == 'C')) { - memmove(&ostring[0], &ostring[1], strlen(ostring)); - } - - /* - * Whack leading "[Tt]he", - */ - if (( strlen(ostring) > hdl->target_len + 4) && - (strncmp(ostring, "The ", 4) == 0 || - strncmp(ostring, "the ", 4) == 0)) { - nstring = xxstrdup(ostring + 4, file, line); - xfree(ostring); - ostring = nstring; - } - - /* Eliminate leading whitespace in all cases */ - while (ostring[0] && isspace(ostring[0])) { - /* If orig string has N bytes, we want to copy N-1 bytes - * of the string itself plus the string terminator (which - * matters if the string consists of nothing but spaces) - */ - memmove(&ostring[0], &ostring[1], strlen(ostring)); - } - - if (!hdl->whitespaceok) { - /* - * Eliminate Whitespace - */ - tstring = xxstrdup(ostring, file, line); - l = strlen (tstring); - cp = ostring; - for (i=0;imustupper) { - for (tstring = ostring; *tstring; tstring++) { - *tstring = toupper(*tstring); - } - } - - /* Before we do any of the vowel or character removal, look for - * constants to replace. - */ - - replace_constants(ostring); - - /* - * Eliminate chars on the blacklist. - */ - tstring = xxstrdup(ostring, file, line); - l = strlen (tstring); - cp = ostring; - for (i=0;ibadchars, tstring[i])) - continue; - if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) - continue; + char *ostring; + char *nstring; + char *tstring; + char *cp; + char *np; + int i, l, nlen, replaced; + mkshort_handle *hdl = (mkshort_handle *) h; + + if (hdl->is_utf8) { + ostring = cet_utf8_strdup(istring); /* clean UTF-8 string */ + } else { + ostring = xxstrdup(istring, file, line); + } + + /* + * A rather horrible special case hack. + * If the target length is "6" and the source length is "7" and + * the first two characters are "GC", we'll assume it's one of the + * the new seven digit geocache numbers and special case whacking + * the 'G' off the front. + */ + if ((hdl->target_len == 6) && (strlen(ostring) == 7) && + (ostring[0] == 'G') && (ostring[1] == 'C')) { + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + /* + * Whack leading "[Tt]he", + */ + if ((strlen(ostring) > hdl->target_len + 4) && + (strncmp(ostring, "The ", 4) == 0 || + strncmp(ostring, "the ", 4) == 0)) { + nstring = xxstrdup(ostring + 4, file, line); + xfree(ostring); + ostring = nstring; + } + + /* Eliminate leading whitespace in all cases */ + while (ostring[0] && isspace(ostring[0])) { + /* If orig string has N bytes, we want to copy N-1 bytes + * of the string itself plus the string terminator (which + * matters if the string consists of nothing but spaces) + */ + memmove(&ostring[0], &ostring[1], strlen(ostring)); + } + + if (!hdl->whitespaceok) { + /* + * Eliminate Whitespace + */ + tstring = xxstrdup(ostring, file, line); + l = strlen(tstring); + cp = ostring; + for (i=0; imustupper) { + for (tstring = ostring; *tstring; tstring++) { + *tstring = toupper(*tstring); + } + } + + /* Before we do any of the vowel or character removal, look for + * constants to replace. + */ + + replace_constants(ostring); + + /* + * Eliminate chars on the blacklist. + */ + tstring = xxstrdup(ostring, file, line); + l = strlen(tstring); + cp = ostring; + for (i=0; ibadchars, tstring[i])) { + continue; + } + if (hdl->goodchars && (!strchr(hdl->goodchars, tstring[i]))) { + continue; + } // FIXME(robertl): we need a way to not return partial UTF-8, but this isn't it. // if (!isascii(tstring[i])) // continue; - *cp++ = tstring[i]; - } - *cp = 0; - xfree(tstring); - - /* - * Eliminate repeated whitespace. This can only shorten the string - * so we do it in place. - */ - if (!hdl->repeating_whitespaceok) { - for (i = 0; i < l-1; i++) { - if (ostring[i] == ' ' && ostring[i+1] == ' ') { - memmove(&ostring[i], &ostring[i+1], l-i); - } - } - } - - /* - * Toss vowels to approach target length, but don't toss them - * if we don't have to. We always keep the leading two letters - * to preserve leading vowels and some semblance of pronouncability. - * - * FIXME: There's a boundary case here where we're too aggressive. - * If the target length is "6" we will shorten "Trolley" to "Trlly", - * when we really don't have to. We should throw away one vowel, not - * both. - */ - - /* - * Delete vowels starting from the end. If it fits, quit stomping - * them. If we run out of string, give up. - * - * Skip this test is our target length is arbitrarily considered - * "long" as it turns out a truncated string of full words is easier - * to read than a full string of vowelless words. - * - * It also helps units with speech synthesis. - */ - if ( hdl->target_len < 15) { - replaced = 1; - } else { - replaced = 0; - } - - while (replaced && strlen(ostring) > hdl->target_len) { - ostring = delete_last_vowel(2, ostring, &replaced); - } - - /* - * Next to last thing, we look for trailing numbers and try to - * preserve those. This ensures that. - * Walk in the Woods 1. - * Walk in the Woods 2. - */ - - np = ostring + strlen(ostring); - while ((np != ostring) && *(np-1) && isdigit(*(np-1) )) { - np--; - } - if (np) { - nlen = strlen(np); - } - - /* - * Now brutally truncate the resulting string, preserve trailing - * numeric data. - * If the numeric component alone is longer than our target string - * length, use only what'll fit. - */ - if (hdl->is_utf8) { - /* ToDo: Keep trailing numeric data as described above! */ - if (cet_utf8_strlen(ostring) > hdl->target_len) { - char *tmp = cet_utf8_strndup(ostring, hdl->target_len); - xfree(ostring); - ostring = tmp; - } - } - else if ((/*i = */strlen(ostring)) > hdl->target_len) { - char *dp = &ostring[hdl->target_len] - strlen(np); - if (dp < ostring) dp = ostring; - memmove(dp, np, strlen(np)); - dp[strlen(np)] = 0; - rtrim(ostring); - } - - /* - * If, after all that, we have an empty string, punt and - * let the must_uniq code handle it. - */ - if (ostring[0] == '\0') { - xfree(ostring); - ostring = xstrdup(hdl->defname); - } - - if (hdl->must_uniq) { - return mkshort_add_to_list(hdl, ostring); - } - return ostring; + *cp++ = tstring[i]; + } + *cp = 0; + xfree(tstring); + + /* + * Eliminate repeated whitespace. This can only shorten the string + * so we do it in place. + */ + if (!hdl->repeating_whitespaceok) { + for (i = 0; i < l-1; i++) { + if (ostring[i] == ' ' && ostring[i+1] == ' ') { + memmove(&ostring[i], &ostring[i+1], l-i); + } + } + } + + /* + * Toss vowels to approach target length, but don't toss them + * if we don't have to. We always keep the leading two letters + * to preserve leading vowels and some semblance of pronouncability. + * + * FIXME: There's a boundary case here where we're too aggressive. + * If the target length is "6" we will shorten "Trolley" to "Trlly", + * when we really don't have to. We should throw away one vowel, not + * both. + */ + + /* + * Delete vowels starting from the end. If it fits, quit stomping + * them. If we run out of string, give up. + * + * Skip this test is our target length is arbitrarily considered + * "long" as it turns out a truncated string of full words is easier + * to read than a full string of vowelless words. + * + * It also helps units with speech synthesis. + */ + if (hdl->target_len < 15) { + replaced = 1; + } else { + replaced = 0; + } + + while (replaced && strlen(ostring) > hdl->target_len) { + ostring = delete_last_vowel(2, ostring, &replaced); + } + + /* + * Next to last thing, we look for trailing numbers and try to + * preserve those. This ensures that. + * Walk in the Woods 1. + * Walk in the Woods 2. + */ + + np = ostring + strlen(ostring); + while ((np != ostring) && *(np-1) && isdigit(*(np-1))) { + np--; + } + if (np) { + nlen = strlen(np); + } + + /* + * Now brutally truncate the resulting string, preserve trailing + * numeric data. + * If the numeric component alone is longer than our target string + * length, use only what'll fit. + */ + if (hdl->is_utf8) { + /* ToDo: Keep trailing numeric data as described above! */ + if (cet_utf8_strlen(ostring) > hdl->target_len) { + char *tmp = cet_utf8_strndup(ostring, hdl->target_len); + xfree(ostring); + ostring = tmp; + } + } else if ((/*i = */strlen(ostring)) > hdl->target_len) { + char *dp = &ostring[hdl->target_len] - strlen(np); + if (dp < ostring) { + dp = ostring; + } + memmove(dp, np, strlen(np)); + dp[strlen(np)] = 0; + rtrim(ostring); + } + + /* + * If, after all that, we have an empty string, punt and + * let the must_uniq code handle it. + */ + if (ostring[0] == '\0') { + xfree(ostring); + ostring = xstrdup(hdl->defname); + } + + if (hdl->must_uniq) { + return mkshort_add_to_list(hdl, ostring); + } + return ostring; } /* @@ -582,205 +595,205 @@ mkshort(short_handle h, const char *istring) char * mkshort_from_wpt(short_handle h, const waypoint *wpt) { - /* This probably came from a Groundspeak Pocket Query - * so use the 'cache name' instead of the description field - * which contains placer name, diff, terr, and generally way - * more stuff than should be in any one field... - */ - if (wpt->gc_data->diff && wpt->gc_data->terr && - wpt->notes && wpt->notes[0]) { - return mkshort(h, wpt->notes); - } - - if (wpt->description) { - return mkshort(h, wpt->description); - } - - if (wpt->notes) { - return mkshort(h, wpt->notes); - } - - /* Should probably never actually happen... */ - /* O.K.: But this can happen (waypoints transformed from trackpoints )! */ - /* Now we return every time a valid entity." */ - - return mkshort(h, wpt->shortname); + /* This probably came from a Groundspeak Pocket Query + * so use the 'cache name' instead of the description field + * which contains placer name, diff, terr, and generally way + * more stuff than should be in any one field... + */ + if (wpt->gc_data->diff && wpt->gc_data->terr && + wpt->notes && wpt->notes[0]) { + return mkshort(h, wpt->notes); + } + + if (wpt->description) { + return mkshort(h, wpt->description); + } + + if (wpt->notes) { + return mkshort(h, wpt->notes); + } + + /* Should probably never actually happen... */ + /* O.K.: But this can happen (waypoints transformed from trackpoints )! */ + /* Now we return every time a valid entity." */ + + return mkshort(h, wpt->shortname); } #if 0 char *foo[] = { -"VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ", -"PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ", -"MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca", -"SOLDIER 3640.691N 08726.660W 0000000m SOLDIER’S TRIBUTE ", -"ZOOMZOOM 3636.659N 08721.793W 0000000m ZOOM ZOOM ZOOM by Feros Family", -"SOCLOSEB 3636.494N 08722.086W 0000000m SO CLOSE BUT YET by Kyle of Fe", -"InSrchfS 3636.363N 08636.363W 0000000m In Search of Steam by BigHank ", -"RdBlngSp 3632.119N 08550.956W 0000000m Red Boiling Springs by Firedog", -"HelngWtr 3631.729N 08550.481W 0000000m Healing Waters by FiredogPotte", -"AHHtheVi 3629.020N 08533.891W 0000000m ogPotter ", -"LstCrkCc 3628.167N 08801.656W 0000000m Lost Creek Cache by Paul Kathy", -"DlvrncTr 3626.412N 08729.249W 0000000m Deliverance Train by Team Skay", -"FrQrtrRn 3438.502N 08646.926W 0000000m Four Quarter Rendezvous by Zay", -"Jstlttlc 3620.647N 08814.298W 0000000m Just a little cache by Paul Ka", -"BrryPtch 3618.786N 08616.344W 0000000m Berry Patch Cache by White Dog", -"AStrllDw 3342.752N 08630.829W 0000000m A Stroll Down Memory Lane by t", -"QunfTnns 3606.413N 08651.962W 0000000m Queen of Tennessee by A182pilo", -"GoneFish 3618.199N 08655.171W 0000000m Gone Fishin' by White Dog Pack", -"GrnwysFn 3610.942N 08642.061W 0000000m Greenways Fence by Ukulele And", -"AStnsThr 3611.240N 08638.324W 0000000m A Stone's Throw by Murrcat & S", -"Nashvlls 3617.112N 08642.359W 0000000m Nashville's Zoo by White Dog P", -"BltzMcr4 3517.127N 08622.211W 0000000m Blitz Micro Number 4 by IHTFP ", -"NkdnthWn 3437.145N 08651.693W 0000000m Naked in the Wind by Zaybex ", -"ANcPlctR 3603.389N 08654.418W 0000000m A Nice Place to Rest by JoGPS ", -"welcomtT 3638.155N 08720.130W 0000000m welcome to TN by Raf of the se", -"welcomtK 3638.956N 08721.011W 0000000m welcome to KY by raf of the se", -"BltzMcr5 3506.191N 08634.277W 0000000m Blitz Micro Number 5 by IHTFP ", -"JmsFmlyG 3615.887N 08649.846W 0000000m James Family Grocery by White ", -"seekngrf 3629.262N 08742.333W 0000000m seekeing refuge by raf of the ", -"SecrtFll 3614.927N 08534.180W 0000000m Secret Falls ", -"ApstlcTh 3613.870N 08645.108W 0000000m Apostolic Thistle Walk by Jame", -"WllIllBD 3609.258N 08637.268W 0000000m Well....I'll Be \"Dammed\" byi", -"BettysBt 3608.857N 08550.564W 0000000m Betty's Booty by White Dog Pac", -"SmthngSm 3439.748N 08643.522W 0000000m Something Smells Fishy by Zayb", -"RckyRd(C 3605.315N 08549.326W 0000000m Rocky Road (Center Hill Lake) ", -"Brdwtchr 3436.605N 08651.243W 0000000m Birdwatcher's Dream by Zaybex ", -"JcksnsHl 3605.185N 08619.439W 0000000m Jackson's Halls by White Dog P", -"FrgttnP2 3509.599N 08633.282W 0000000m Forgotten Park 2 by mdawg & mu", -"SOLDIERS 3640.691N 08726.660W 0000000m SOLDIERS TRIBUTE by Feros Fami", -"EndofRop 3433.820N 08650.460W 0000000m End of Rope by Big Rock ", -"VwthPst1 3659.263N 08627.114W 0000000m View the Past #1 by wkgraham ", -"VwthPst2 3700.706N 08627.588W 0000000m View the Past #2 by wkgraham ", -"Trash#8 3603.102N 08655.144W 0000000m Cache In Trash Out # 8 ", -"SlwwwwCc 3602.543N 08535.953W 0000000m Sloowwww Cache by Tntcacher ", -"Leavttbv 3602.514N 08638.686W 0000000m Leave it to beaver by A182pilo", -"WhrrthHr 3436.594N 08654.759W 0000000m Where are the Horses? by Zaybe", -"ButtonCc 3433.401N 08645.294W 0000000m Button Cache by Zaybex ", -"MrcsLbrr 3436.842N 08655.972W 0000000m Marco's Library by Marco ", -"Octopus 3526.743N 08534.757W 0000000m Octopus by White Dog Pack ", -"WtrFllsV 3544.140N 08527.861W 0000000m Water Falls Valley by Cave Rat", -"DeddrpPn 3448.126N 08719.696W 0000000m Dead-drop Pink by Marco ", -"JWhlrRvr 3448.157N 08719.914W 0000000m Joe Wheeler River Walk by Marc", -"CvSprngs 3432.797N 08651.084W 0000000m Cave Springs Cache by Marco.. ", -"CnyFrkOv 3550.876N 08518.446W 0000000m Fork Overlook ", -"SheepsCa 3550.527N 08519.480W 0000000m Sheep's Cave ", -"VrgnFlls 3550.308N 08519.904W 0000000m Virgin Falls Cache ", -"ShrtctVr 3550.170N 08519.590W 0000000m Shortcut Virtual ", -"KlylFlls 3549.105N 08539.814W 0000000m Klaylee Falls Cache by pattytr", -"FshngfrB 3548.923N 08538.558W 0000000m BADGER by M&Mk ", -"TpfthHll 3548.808N 08601.722W 0000000m Top of the Hill Pet Cache by M", -"TwnFllsC 3548.560N 08537.996W 0000000m Twin Falls Cache by SLCREW a", -"WtchsCst 3548.197N 08537.673W 0000000m Witch's Castle Keys by SLCREW ", -"ThatCave 3544.901N 08522.854W 0000000m That Cave by JaDan150 and AprJ", -"BssltwnW 3541.174N 08801.489W 0000000m Busseltown Wildlife Refuge by ", -"Riverfrn 3540.968N 08546.995W 0000000m Riverfront by SLCREW and M&M", -"Basement 3540.086N 08521.304W 0000000m The Basement ", -"EfflTwrC 3617.132N 08818.371W 0000000m Eiffel Tower Cache by Dick Wan", -"KeyholeC 3544.562N 08524.098W 0000000m Keyhole Cave by Cave Rat ", -"(MC^2)Mn 3444.990N 08630.218W 0000000m (MC^2) Monte Sano Cuts Cache b", -"WildctCc 3636.823N 08808.087W 0000000m Wildcat Cache by The Storm ", -"NAlbm/Tn 3444.365N 08632.688W 0000000m N. Alabama / Tennessee Valley ", -"CalebsCa 3444.215N 08633.103W 0000000m Caleb's Cave by Papaw and Cale", -"MntSnPrs 3444.201N 08632.591W 0000000m Monte Sano Preserve by Evan & ", -"FltRckFl 3444.475N 08629.958W 0000000m Flat Rock Falls Cache by Jason", -"PanormCc 3443.961N 08631.638W 0000000m The Panorama Cache by IHTFP an", -"TnnssScv 3602.861N 08652.751W 0000000m Tennessee Scavenger Hunt Cache", -"Geocache 3435.209N 08655.968W 0000000m Geocache by Papaw & Caleb ", -"Skellig 3444.100N 08656.566W 0000000m Skellig by Zaybex ", -"Deceptio 3433.450N 08655.711W 0000000m Deception by Papaw and Caleb ", -"AwlknthD 3433.310N 08655.635W 0000000m A walk in the Desert by Papa", -"MiniMsQs 3558.934N 08650.674W 0000000m Mini Me's Quest by CrotalusRex", -"BakrsBlf 3541.891N 08717.300W 0000000m Bakers Bluff by Flower Child &", -"GoFlyAKi 3435.664N 08659.267W 0000000m Go Fly A Kite by Marco.. ", -"FlntCrkA 3432.028N 08656.806W 0000000m Flint Creek Adventure by Marco", -"HonordMn 3534.680N 08612.557W 0000000m Honored Mount by Southpaw ", -"SafariZo 3440.697N 08700.774W 0000000m Safari Zone by Zaybex ", -"JckDnlsC 3517.077N 08622.260W 0000000m Jack Daniels Cache by Rmearse ", -"FrgttnPr 3509.599N 08633.282W 0000000m Forgotten Park by mdawg & muff", -"DntOvrlk 3513.326N 08616.031W 0000000m Dont Overlook Me Cache ", -"ArYStmpd 3513.039N 08615.110W 0000000m Are You Stumped Yet? cache ", -"CchtthBn 3512.532N 08614.691W 0000000m Cache at the Bend ", -"Thtsnkng 3609.009N 08530.314W 0000000m That sinking feeling by Tntcac", -"GamersCc 3449.136N 08635.836W 0000000m mer's Cache by avoral ", -"CchMIfYC 3452.455N 08620.648W 0000000m Cache Me If You Can! by Glen H", -"SavageVs 3526.915N 08535.136W 0000000m Savage Vista by White Dog Pack", -"PrtrnG15 3555.479N 08653.274W 0000000m Praetorian Guards Hail Caesar #15!", -"WtrlnAmp 3443.722N 08632.535W 0000000m Waterline Amphitheater by Fath", -"BysLttlC 3447.569N 08638.448W 0000000m Boys' Little Cache by Zaybex ", -"DrgnsBrt 3443.779N 08635.188W 0000000m Dragon's Breath by Zaybex ", -"CryBbyHl 3430.733N 08657.362W 0000000m Cry Baby Hollow Cache by La Pa", -"Parmer 3606.218N 08651.590W 0000000m Parmer by A182pilot & Family ", -"JnnfrndJ 3438.141N 08632.991W 0000000m Jennifer and Jonathans Cliff C", -"ALDRIDGE 3435.305N 08632.868W 0000000m ALDRIDGE CREEK LOTTA LOOT!! by", -"RcktCtyS 3440.032N 08631.352W 0000000m Rocket City Stash by David Upt", -"TrgcAccd 3608.561N 08648.381W 0000000m Tragic Accident by Campaholics", -"FALLENTR 3439.210N 08631.104W 0000000m FALLEN TREE 4 MILE POST by zac", -"TrshOt15 3558.964N 08646.064W 0000000m Cache In Trash Out # 15 by Jo", -"TrshOt13 3602.214N 08650.428W 0000000m Cache In Trash Out #13 by JoGP", -"PrcysDrp 3604.312N 08653.465W 0000000m Percys Dripping Springs by KLi", -"TrshOt14 3605.292N 08648.560W 0000000m Cache In Trash Out # 14 by JoG", -"PrtrnGr5 3557.621N 08640.278W 0000000m Praetorian Guards Hail Caesar #5!", -"PrtrnGr4 3557.370N 08640.201W 0000000m Praetorian Guards Hail Caesar #4!", -"PrtrnGr3 3557.250N 08640.047W 0000000m Praetorian Guards Hail Caesar #3!", -"GrnMntnC 3439.120N 08631.100W 0000000m Green Mountain Cache by Steve ", -"TrshOt12 3605.330N 08635.817W 0000000m Cache In Trash Out #12 by JoGP", -"BlncngAc 3608.579N 08648.120W 0000000m Balancing Act by Campaholics ", -"DittoCac 3434.652N 08633.310W 0000000m Ditto Cache by mookey ", -"EraserCc 3431.888N 08633.024W 0000000m Eraser Cache by Zaybex ", -"FrMlPstE 3439.440N 08630.180W 0000000m Four Mile Post Extension Cache", -"MllrdFxC 3439.578N 08706.552W 0000000m Mallard-Fox Creek Cache by bam", -"FireCach 3443.908N 08630.318W 0000000m he by Glen Pam Chase M ", -"FlntRvrC 3443.170N 08625.990W 0000000m Flint River Canoe Cache by Ran", -"ArabinCc 3419.104N 08628.765W 0000000m The Arabian Cache by WesNSpace", -"CvrdBrdg 3412.406N 08659.392W 0000000m Covered Bridge Cache by pmarkh", -"MilesTCc 3424.470N 08611.720W 0000000m Miles Too Cache by Rmearse ", -"MbryOvrl 3423.803N 08611.922W 0000000m Mabrey Overlook Me by DDVaughn", -"LwEnfrcm 3423.218N 08612.258W 0000000m Law Enforcement Cache by DDVau", -"GrndDddy 3423.128N 08612.025W 0000000m Grand Daddys Home by Rmearse ", -"BamaCach 3421.459N 08611.686W 0000000m The Bama Cache by DDVaughn & T", -"Canyons 3440.085N 08600.910W 0000000m The Canyons by Aubrey and Josh", -"ADamGodV 3511.677N 08616.587W 0000000m A Dam Good View by mdawg & muf", -"UNDERTHE 3446.918N 08739.790W 0000000m UNDER THE ROCK by RUNNINGWILD ", -"SQUIRREL 3448.712N 08741.681W 0000000m SQUIRREL'S NEST by RUNNINGWILD", -"WlknthPr 3448.273N 08741.844W 0000000m Walk in the Park by Runningwil", -"NetsClue 3448.494N 08741.977W 0000000m Net's Clues by Runningwild Adv", -"NatrlBrd 3405.583N 08736.909W 0000000m Natural Bridge by Southeast Xt", -"TrnglPrk 3341.448N 08640.980W 0000000m Triangle Park Cache by Charles", -"LttlRvrI 3421.855N 08539.597W 0000000m Little River Initiative by spa", -"GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po", -"GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ", -"FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ", -"CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol" + "VwthPst# 3700.706N 08627.588W 0000000m View the Past #2 ", + "PilotRoc 3655.270N 08717.173W 0000000m Pilot Rock by CacheAdvance ", + "MrCycsNg 3652.407N 08728.890W 0000000m Mr. Cayces Neighborhood by Ca", + "SOLDIER 3640.691N 08726.660W 0000000m SOLDIER’S TRIBUTE ", + "ZOOMZOOM 3636.659N 08721.793W 0000000m ZOOM ZOOM ZOOM by Feros Family", + "SOCLOSEB 3636.494N 08722.086W 0000000m SO CLOSE BUT YET by Kyle of Fe", + "InSrchfS 3636.363N 08636.363W 0000000m In Search of Steam by BigHank ", + "RdBlngSp 3632.119N 08550.956W 0000000m Red Boiling Springs by Firedog", + "HelngWtr 3631.729N 08550.481W 0000000m Healing Waters by FiredogPotte", + "AHHtheVi 3629.020N 08533.891W 0000000m ogPotter ", + "LstCrkCc 3628.167N 08801.656W 0000000m Lost Creek Cache by Paul Kathy", + "DlvrncTr 3626.412N 08729.249W 0000000m Deliverance Train by Team Skay", + "FrQrtrRn 3438.502N 08646.926W 0000000m Four Quarter Rendezvous by Zay", + "Jstlttlc 3620.647N 08814.298W 0000000m Just a little cache by Paul Ka", + "BrryPtch 3618.786N 08616.344W 0000000m Berry Patch Cache by White Dog", + "AStrllDw 3342.752N 08630.829W 0000000m A Stroll Down Memory Lane by t", + "QunfTnns 3606.413N 08651.962W 0000000m Queen of Tennessee by A182pilo", + "GoneFish 3618.199N 08655.171W 0000000m Gone Fishin' by White Dog Pack", + "GrnwysFn 3610.942N 08642.061W 0000000m Greenways Fence by Ukulele And", + "AStnsThr 3611.240N 08638.324W 0000000m A Stone's Throw by Murrcat & S", + "Nashvlls 3617.112N 08642.359W 0000000m Nashville's Zoo by White Dog P", + "BltzMcr4 3517.127N 08622.211W 0000000m Blitz Micro Number 4 by IHTFP ", + "NkdnthWn 3437.145N 08651.693W 0000000m Naked in the Wind by Zaybex ", + "ANcPlctR 3603.389N 08654.418W 0000000m A Nice Place to Rest by JoGPS ", + "welcomtT 3638.155N 08720.130W 0000000m welcome to TN by Raf of the se", + "welcomtK 3638.956N 08721.011W 0000000m welcome to KY by raf of the se", + "BltzMcr5 3506.191N 08634.277W 0000000m Blitz Micro Number 5 by IHTFP ", + "JmsFmlyG 3615.887N 08649.846W 0000000m James Family Grocery by White ", + "seekngrf 3629.262N 08742.333W 0000000m seekeing refuge by raf of the ", + "SecrtFll 3614.927N 08534.180W 0000000m Secret Falls ", + "ApstlcTh 3613.870N 08645.108W 0000000m Apostolic Thistle Walk by Jame", + "WllIllBD 3609.258N 08637.268W 0000000m Well....I'll Be \"Dammed\" byi", + "BettysBt 3608.857N 08550.564W 0000000m Betty's Booty by White Dog Pac", + "SmthngSm 3439.748N 08643.522W 0000000m Something Smells Fishy by Zayb", + "RckyRd(C 3605.315N 08549.326W 0000000m Rocky Road (Center Hill Lake) ", + "Brdwtchr 3436.605N 08651.243W 0000000m Birdwatcher's Dream by Zaybex ", + "JcksnsHl 3605.185N 08619.439W 0000000m Jackson's Halls by White Dog P", + "FrgttnP2 3509.599N 08633.282W 0000000m Forgotten Park 2 by mdawg & mu", + "SOLDIERS 3640.691N 08726.660W 0000000m SOLDIERS TRIBUTE by Feros Fami", + "EndofRop 3433.820N 08650.460W 0000000m End of Rope by Big Rock ", + "VwthPst1 3659.263N 08627.114W 0000000m View the Past #1 by wkgraham ", + "VwthPst2 3700.706N 08627.588W 0000000m View the Past #2 by wkgraham ", + "Trash#8 3603.102N 08655.144W 0000000m Cache In Trash Out # 8 ", + "SlwwwwCc 3602.543N 08535.953W 0000000m Sloowwww Cache by Tntcacher ", + "Leavttbv 3602.514N 08638.686W 0000000m Leave it to beaver by A182pilo", + "WhrrthHr 3436.594N 08654.759W 0000000m Where are the Horses? by Zaybe", + "ButtonCc 3433.401N 08645.294W 0000000m Button Cache by Zaybex ", + "MrcsLbrr 3436.842N 08655.972W 0000000m Marco's Library by Marco ", + "Octopus 3526.743N 08534.757W 0000000m Octopus by White Dog Pack ", + "WtrFllsV 3544.140N 08527.861W 0000000m Water Falls Valley by Cave Rat", + "DeddrpPn 3448.126N 08719.696W 0000000m Dead-drop Pink by Marco ", + "JWhlrRvr 3448.157N 08719.914W 0000000m Joe Wheeler River Walk by Marc", + "CvSprngs 3432.797N 08651.084W 0000000m Cave Springs Cache by Marco.. ", + "CnyFrkOv 3550.876N 08518.446W 0000000m Fork Overlook ", + "SheepsCa 3550.527N 08519.480W 0000000m Sheep's Cave ", + "VrgnFlls 3550.308N 08519.904W 0000000m Virgin Falls Cache ", + "ShrtctVr 3550.170N 08519.590W 0000000m Shortcut Virtual ", + "KlylFlls 3549.105N 08539.814W 0000000m Klaylee Falls Cache by pattytr", + "FshngfrB 3548.923N 08538.558W 0000000m BADGER by M&Mk ", + "TpfthHll 3548.808N 08601.722W 0000000m Top of the Hill Pet Cache by M", + "TwnFllsC 3548.560N 08537.996W 0000000m Twin Falls Cache by SLCREW a", + "WtchsCst 3548.197N 08537.673W 0000000m Witch's Castle Keys by SLCREW ", + "ThatCave 3544.901N 08522.854W 0000000m That Cave by JaDan150 and AprJ", + "BssltwnW 3541.174N 08801.489W 0000000m Busseltown Wildlife Refuge by ", + "Riverfrn 3540.968N 08546.995W 0000000m Riverfront by SLCREW and M&M", + "Basement 3540.086N 08521.304W 0000000m The Basement ", + "EfflTwrC 3617.132N 08818.371W 0000000m Eiffel Tower Cache by Dick Wan", + "KeyholeC 3544.562N 08524.098W 0000000m Keyhole Cave by Cave Rat ", + "(MC^2)Mn 3444.990N 08630.218W 0000000m (MC^2) Monte Sano Cuts Cache b", + "WildctCc 3636.823N 08808.087W 0000000m Wildcat Cache by The Storm ", + "NAlbm/Tn 3444.365N 08632.688W 0000000m N. Alabama / Tennessee Valley ", + "CalebsCa 3444.215N 08633.103W 0000000m Caleb's Cave by Papaw and Cale", + "MntSnPrs 3444.201N 08632.591W 0000000m Monte Sano Preserve by Evan & ", + "FltRckFl 3444.475N 08629.958W 0000000m Flat Rock Falls Cache by Jason", + "PanormCc 3443.961N 08631.638W 0000000m The Panorama Cache by IHTFP an", + "TnnssScv 3602.861N 08652.751W 0000000m Tennessee Scavenger Hunt Cache", + "Geocache 3435.209N 08655.968W 0000000m Geocache by Papaw & Caleb ", + "Skellig 3444.100N 08656.566W 0000000m Skellig by Zaybex ", + "Deceptio 3433.450N 08655.711W 0000000m Deception by Papaw and Caleb ", + "AwlknthD 3433.310N 08655.635W 0000000m A walk in the Desert by Papa", + "MiniMsQs 3558.934N 08650.674W 0000000m Mini Me's Quest by CrotalusRex", + "BakrsBlf 3541.891N 08717.300W 0000000m Bakers Bluff by Flower Child &", + "GoFlyAKi 3435.664N 08659.267W 0000000m Go Fly A Kite by Marco.. ", + "FlntCrkA 3432.028N 08656.806W 0000000m Flint Creek Adventure by Marco", + "HonordMn 3534.680N 08612.557W 0000000m Honored Mount by Southpaw ", + "SafariZo 3440.697N 08700.774W 0000000m Safari Zone by Zaybex ", + "JckDnlsC 3517.077N 08622.260W 0000000m Jack Daniels Cache by Rmearse ", + "FrgttnPr 3509.599N 08633.282W 0000000m Forgotten Park by mdawg & muff", + "DntOvrlk 3513.326N 08616.031W 0000000m Dont Overlook Me Cache ", + "ArYStmpd 3513.039N 08615.110W 0000000m Are You Stumped Yet? cache ", + "CchtthBn 3512.532N 08614.691W 0000000m Cache at the Bend ", + "Thtsnkng 3609.009N 08530.314W 0000000m That sinking feeling by Tntcac", + "GamersCc 3449.136N 08635.836W 0000000m mer's Cache by avoral ", + "CchMIfYC 3452.455N 08620.648W 0000000m Cache Me If You Can! by Glen H", + "SavageVs 3526.915N 08535.136W 0000000m Savage Vista by White Dog Pack", + "PrtrnG15 3555.479N 08653.274W 0000000m Praetorian Guards Hail Caesar #15!", + "WtrlnAmp 3443.722N 08632.535W 0000000m Waterline Amphitheater by Fath", + "BysLttlC 3447.569N 08638.448W 0000000m Boys' Little Cache by Zaybex ", + "DrgnsBrt 3443.779N 08635.188W 0000000m Dragon's Breath by Zaybex ", + "CryBbyHl 3430.733N 08657.362W 0000000m Cry Baby Hollow Cache by La Pa", + "Parmer 3606.218N 08651.590W 0000000m Parmer by A182pilot & Family ", + "JnnfrndJ 3438.141N 08632.991W 0000000m Jennifer and Jonathans Cliff C", + "ALDRIDGE 3435.305N 08632.868W 0000000m ALDRIDGE CREEK LOTTA LOOT!! by", + "RcktCtyS 3440.032N 08631.352W 0000000m Rocket City Stash by David Upt", + "TrgcAccd 3608.561N 08648.381W 0000000m Tragic Accident by Campaholics", + "FALLENTR 3439.210N 08631.104W 0000000m FALLEN TREE 4 MILE POST by zac", + "TrshOt15 3558.964N 08646.064W 0000000m Cache In Trash Out # 15 by Jo", + "TrshOt13 3602.214N 08650.428W 0000000m Cache In Trash Out #13 by JoGP", + "PrcysDrp 3604.312N 08653.465W 0000000m Percys Dripping Springs by KLi", + "TrshOt14 3605.292N 08648.560W 0000000m Cache In Trash Out # 14 by JoG", + "PrtrnGr5 3557.621N 08640.278W 0000000m Praetorian Guards Hail Caesar #5!", + "PrtrnGr4 3557.370N 08640.201W 0000000m Praetorian Guards Hail Caesar #4!", + "PrtrnGr3 3557.250N 08640.047W 0000000m Praetorian Guards Hail Caesar #3!", + "GrnMntnC 3439.120N 08631.100W 0000000m Green Mountain Cache by Steve ", + "TrshOt12 3605.330N 08635.817W 0000000m Cache In Trash Out #12 by JoGP", + "BlncngAc 3608.579N 08648.120W 0000000m Balancing Act by Campaholics ", + "DittoCac 3434.652N 08633.310W 0000000m Ditto Cache by mookey ", + "EraserCc 3431.888N 08633.024W 0000000m Eraser Cache by Zaybex ", + "FrMlPstE 3439.440N 08630.180W 0000000m Four Mile Post Extension Cache", + "MllrdFxC 3439.578N 08706.552W 0000000m Mallard-Fox Creek Cache by bam", + "FireCach 3443.908N 08630.318W 0000000m he by Glen Pam Chase M ", + "FlntRvrC 3443.170N 08625.990W 0000000m Flint River Canoe Cache by Ran", + "ArabinCc 3419.104N 08628.765W 0000000m The Arabian Cache by WesNSpace", + "CvrdBrdg 3412.406N 08659.392W 0000000m Covered Bridge Cache by pmarkh", + "MilesTCc 3424.470N 08611.720W 0000000m Miles Too Cache by Rmearse ", + "MbryOvrl 3423.803N 08611.922W 0000000m Mabrey Overlook Me by DDVaughn", + "LwEnfrcm 3423.218N 08612.258W 0000000m Law Enforcement Cache by DDVau", + "GrndDddy 3423.128N 08612.025W 0000000m Grand Daddys Home by Rmearse ", + "BamaCach 3421.459N 08611.686W 0000000m The Bama Cache by DDVaughn & T", + "Canyons 3440.085N 08600.910W 0000000m The Canyons by Aubrey and Josh", + "ADamGodV 3511.677N 08616.587W 0000000m A Dam Good View by mdawg & muf", + "UNDERTHE 3446.918N 08739.790W 0000000m UNDER THE ROCK by RUNNINGWILD ", + "SQUIRREL 3448.712N 08741.681W 0000000m SQUIRREL'S NEST by RUNNINGWILD", + "WlknthPr 3448.273N 08741.844W 0000000m Walk in the Park by Runningwil", + "NetsClue 3448.494N 08741.977W 0000000m Net's Clues by Runningwild Adv", + "NatrlBrd 3405.583N 08736.909W 0000000m Natural Bridge by Southeast Xt", + "TrnglPrk 3341.448N 08640.980W 0000000m Triangle Park Cache by Charles", + "LttlRvrI 3421.855N 08539.597W 0000000m Little River Initiative by spa", + "GimmShlt 3430.087N 08536.834W 0000000m Gimme Shelter by Big Rock & Po", + "GnomeTrs 3433.081N 08535.849W 0000000m Gnome Treasure by Big Rock ", + "FlyingTr 3608.594N 08648.179W 0000000m Flying Torso by Campaholics ", + "CultivtC 3608.582N 08648.064W 0000000m Cultivate a Cure by Campahol" } ; main() { - char **foop = foo; - int r; - - printf("%s\n", mkshort("The Troll")); - printf("%s\n", mkshort("EFI")); - printf("%s\n", mkshort("the Troll")); - printf("%s\n", mkshort("the Trolley")); - printf("%s\n", mkshort("The Troll Lives Under The Bridge")); - printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!")); - printf("%s\n", mkshort("The Trolley Goes Round")); - printf("%s\n", mkshort("Cache In / Trash Out #1")); - printf("%s\n", mkshort("Cache In / Trash Out #2")); - printf("%s\n", mkshort("Cache In / Trash Out #137")); - - while (0 && *foop) { - printf("%s %s\n", mkshort(*foop+39), *foop+39); - foop++; - } - -printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r)); -printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r)); -printf("%s\n", delete_last_vowel(0, "xxx", &r)); -printf("%s\n", delete_last_vowel(0, "ixxx", &r)); -printf("%s\n", delete_last_vowel(0, "aexxx", &r)); - + char **foop = foo; + int r; + + printf("%s\n", mkshort("The Troll")); + printf("%s\n", mkshort("EFI")); + printf("%s\n", mkshort("the Troll")); + printf("%s\n", mkshort("the Trolley")); + printf("%s\n", mkshort("The Troll Lives Under The Bridge")); + printf("%s\n", mkshort("The \"Troll\" Lives Under $$ The Bridge!")); + printf("%s\n", mkshort("The Trolley Goes Round")); + printf("%s\n", mkshort("Cache In / Trash Out #1")); + printf("%s\n", mkshort("Cache In / Trash Out #2")); + printf("%s\n", mkshort("Cache In / Trash Out #137")); + + while (0 && *foop) { + printf("%s %s\n", mkshort(*foop+39), *foop+39); + foop++; + } + + printf("%s\n", delete_last_vowel(0, "the quick brown foo", &r)); + printf("%s\n", delete_last_vowel(0, "the quick brown fox", &r)); + printf("%s\n", delete_last_vowel(0, "xxx", &r)); + printf("%s\n", delete_last_vowel(0, "ixxx", &r)); + printf("%s\n", delete_last_vowel(0, "aexxx", &r)); + } #endif diff --git a/gpsbabel/mmo.c b/gpsbabel/mmo.c index a36859997..32c02f177 100644 --- a/gpsbabel/mmo.c +++ b/gpsbabel/mmo.c @@ -19,10 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + /* History: - + 2008/10/18: Initial release 2008/10/19: Don't write empty names Add options 'locked' and 'visible' @@ -56,29 +56,35 @@ static char *opt_locked, *opt_visible, *opt_version; static arglist_t mmo_args[] = { - { "locked", &opt_locked, "Write items 'locked' [default no]", "0", - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "visible", &opt_visible, "Write items 'visible' [default yes]", "1", - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "ver", &opt_version, "Write files with internal version [n]", NULL, - ARGTYPE_INT, "17", "18" }, - ARG_TERMINATOR + { + "locked", &opt_locked, "Write items 'locked' [default no]", "0", + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "visible", &opt_visible, "Write items 'visible' [default yes]", "1", + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "ver", &opt_version, "Write files with internal version [n]", NULL, + ARGTYPE_INT, "17", "18" + }, + ARG_TERMINATOR }; typedef struct mmo_data_s { - int objid; /* internal object id */ - char *name; - const char *category; /* currently not handled */ - gpsdata_type type; /* type of "data" */ - time_t ctime; - time_t mtime; - int left; /* number of un-readed route points */ - void *data; /* can be a waypoint, a route or a track */ - int refct; - struct mmo_data_s **members; - unsigned char visible:1; - unsigned char locked:1; - unsigned char loaded:1; + int objid; /* internal object id */ + char *name; + const char *category; /* currently not handled */ + gpsdata_type type; /* type of "data" */ + time_t ctime; + time_t mtime; + int left; /* number of un-readed route points */ + void *data; /* can be a waypoint, a route or a track */ + int refct; + struct mmo_data_s **members; + unsigned char visible:1; + unsigned char locked:1; + unsigned char loaded:1; } mmo_data_t; static gbfile *fin, *fout; @@ -100,39 +106,39 @@ static avltree_t *category_names, *objects, *mmobjects, *category_ids; static avltree_t *icons; typedef struct mmo_icon_mapping_s { - const int value; - const char *icon; + const int value; + const char *icon; } mmo_icon_mapping_t; /* standard icons; no bitmaps in file */ static const mmo_icon_mapping_t mmo_icon_value_table[] = { - { 0x00, "Dot" }, - { 0x01, "House" }, - { 0x02, "Fuel" }, - { 0x03, "Car" }, - { 0x04, "Fish" }, - { 0x05, "Boat" }, - { 0x06, "Anchor" }, - { 0x07, "Wreck" }, - { 0x08, "Exit" }, - { 0x09, "Skull" }, - { 0x0A, "Flag" }, - { 0x0B, "Camp" }, - { 0x0C, "Man Overboard" }, - { 0x0D, "Deer" }, - { 0x0E, "First Aid" }, - { 0x0F, "Trackback" }, - { 0x10, "Tiny dot" }, - { 0x11, "Triangle" }, - { 0x12, "Square" }, - { 0x13, "Circle" }, - { 0x14, "Green bouy" }, - { 0x15, "Red bouy" }, - { 0x16, "Yellow bouy" }, - { 0x17, "Geocache" }, - - { -1, NULL } + { 0x00, "Dot" }, + { 0x01, "House" }, + { 0x02, "Fuel" }, + { 0x03, "Car" }, + { 0x04, "Fish" }, + { 0x05, "Boat" }, + { 0x06, "Anchor" }, + { 0x07, "Wreck" }, + { 0x08, "Exit" }, + { 0x09, "Skull" }, + { 0x0A, "Flag" }, + { 0x0B, "Camp" }, + { 0x0C, "Man Overboard" }, + { 0x0D, "Deer" }, + { 0x0E, "First Aid" }, + { 0x0F, "Trackback" }, + { 0x10, "Tiny dot" }, + { 0x11, "Triangle" }, + { 0x12, "Square" }, + { 0x13, "Circle" }, + { 0x14, "Green bouy" }, + { 0x15, "Red bouy" }, + { 0x16, "Yellow bouy" }, + { 0x17, "Geocache" }, + + { -1, NULL } }; static const gbuint32 obj_type_ico = 0x00; @@ -147,12 +153,12 @@ static const gbuint32 obj_type_wpt = 0x3C; static void dbgprintf(const char *sobj, const char *fmt, ...) { - va_list args; - va_start(args, fmt); + va_list args; + va_start(args, fmt); - printf(MYNAME "-%s: ", sobj); - vprintf(fmt, args); - va_end(args); + printf(MYNAME "-%s: ", sobj); + vprintf(fmt, args); + va_end(args); } # define DBG(args) dbgprintf args @@ -163,37 +169,45 @@ dbgprintf(const char *sobj, const char *fmt, ...) static char * mmo_readstr(void) { - char *res; - int len; - - len = (unsigned)gbfgetc(fin); - if (len == 0xFF) { - len = gbfgetint16(fin); - if (len < 0) fatal(MYNAME ": Invalid string length (%d)!\n", len); - } - res = xmalloc(len + 1); - res[len] = '\0'; - if (len) { - gbfread(res, len, 1, fin); - if (len != strlen(res)) fatal(MYNAME ": Error in file structure!\n"); - } - - return res; + char *res; + int len; + + len = (unsigned)gbfgetc(fin); + if (len == 0xFF) { + len = gbfgetint16(fin); + if (len < 0) { + fatal(MYNAME ": Invalid string length (%d)!\n", len); + } + } + res = xmalloc(len + 1); + res[len] = '\0'; + if (len) { + gbfread(res, len, 1, fin); + if (len != strlen(res)) { + fatal(MYNAME ": Error in file structure!\n"); + } + } + + return res; } static int mmo_fillbuf2(void *buf, const gbsize_t bufsz, const gbsize_t count, const int need_all) { - gbsize_t res; - - if (count > (int)bufsz) fatal(MYNAME ": Internal error (bufsz too small)!\n"); - - memset(buf, 0xFF, count); - res = gbfread(buf, 1, count, fin); - if (need_all && (res < count)) fatal(MYNAME ": Unexpected end of file!\n"); - - return res; + gbsize_t res; + + if (count > (int)bufsz) { + fatal(MYNAME ": Internal error (bufsz too small)!\n"); + } + + memset(buf, 0xFF, count); + res = gbfread(buf, 1, count, fin); + if (need_all && (res < count)) { + fatal(MYNAME ": Unexpected end of file!\n"); + } + + return res; } #define mmo_fillbuf(a,b,c) mmo_fillbuf2((a),sizeof((a)),(b),(c)) @@ -201,15 +215,20 @@ static void mmo_printbuf(const char *buf, int count, const char *comment) { #ifdef MMO_DBG - int i; - printf("%s", comment); - for (i = 0; i < count; i++) printf("%02X ", buf[i] & 0xFF); - printf("- "); - for (i = 0; i < count; i++) - if (isprint(buf[i])) printf("%c", buf[i] & 0xFF); - else printf("."); - printf("\n"); - fflush(stdout); + int i; + printf("%s", comment); + for (i = 0; i < count; i++) { + printf("%02X ", buf[i] & 0xFF); + } + printf("- "); + for (i = 0; i < count; i++) + if (isprint(buf[i])) { + printf("%c", buf[i] & 0xFF); + } else { + printf("."); + } + printf("\n"); + fflush(stdout); #endif } @@ -218,98 +237,106 @@ mmo_printbuf(const char *buf, int count, const char *comment) static mmo_data_t * mmo_register_object(const int objid, const void *ptr, const gpsdata_type type) { - char key[16]; - mmo_data_t *data; - - data = xcalloc(1, sizeof(*data)); - data->data = (void *)ptr; - data->visible = 1; - data->locked = 0; - data->type = type; - data->objid = objid; - - snprintf(key, sizeof(key), "%d", objid); - avltree_insert(objects, key, data); - - return data; + char key[16]; + mmo_data_t *data; + + data = xcalloc(1, sizeof(*data)); + data->data = (void *)ptr; + data->visible = 1; + data->locked = 0; + data->type = type; + data->objid = objid; + + snprintf(key, sizeof(key), "%d", objid); + avltree_insert(objects, key, data); + + return data; } static int mmo_get_objid(const void *ptr) { - const char *key; - mmo_data_t *data; - - if ((key = avltree_first(objects, (void *)&data))) do { - if (data->data == ptr) { - return atoi(key); - } - } while ((key = avltree_next(objects, key, (void *)&data))); - - return 0; + const char *key; + mmo_data_t *data; + + if ((key = avltree_first(objects, (void *)&data))) do { + if (data->data == ptr) { + return atoi(key); + } + } while ((key = avltree_next(objects, key, (void *)&data))); + + return 0; } static mmo_data_t * mmo_get_object(const gbuint16 objid) { - char key[16]; - mmo_data_t *data; - - snprintf(key, sizeof(key), "%d", objid | 0x8000); - if (! avltree_find(objects, key, (void *)&data)) { + char key[16]; + mmo_data_t *data; + + snprintf(key, sizeof(key), "%d", objid | 0x8000); + if (! avltree_find(objects, key, (void *)&data)) { #ifdef MMO_DBG - gbfseek(fin, -2, SEEK_CUR); - int ni, n; - for (ni = 0; (n = gbfgetc(fin)) != EOF; ni++) { - DBG(("mmo_get_object", "%04X %02X %c (%d)\n", - ni, n, n >= 32 && n <= 126 ? (char)n : '.', n)); - } + gbfseek(fin, -2, SEEK_CUR); + int ni, n; + for (ni = 0; (n = gbfgetc(fin)) != EOF; ni++) { + DBG(("mmo_get_object", "%04X %02X %c (%d)\n", + ni, n, n >= 32 && n <= 126 ? (char)n : '.', n)); + } #endif - fatal(MYNAME ": Unregistered object id 0x%04X!\n", objid | 0x8000); - } - - return data; + fatal(MYNAME ": Unregistered object id 0x%04X!\n", objid | 0x8000); + } + + return data; } static waypoint * mmo_get_waypt(mmo_data_t *data) { - data->refct++; - if (data->refct == 1) return (waypoint *)data->data; - else return waypt_dupe((waypoint *)data->data); + data->refct++; + if (data->refct == 1) { + return (waypoint *)data->data; + } else { + return waypt_dupe((waypoint *)data->data); + } } static void mmo_release_avltree(avltree_t *tree, const int is_object) { - const char *key; - char *name; - - if ((key = avltree_first(tree, (void *)&name))) { - do { - if (name == NULL) continue; - if (is_object) { - mmo_data_t *data = (mmo_data_t *)name; - if (data->name) xfree(data->name); - if ((data->type == wptdata) && (data->refct == 0)) - waypt_free((waypoint *)data->data); - } - xfree(name); - } while ((key = avltree_next(tree, key, (void *)&name))); - } - avltree_done(tree); + const char *key; + char *name; + + if ((key = avltree_first(tree, (void *)&name))) { + do { + if (name == NULL) { + continue; + } + if (is_object) { + mmo_data_t *data = (mmo_data_t *)name; + if (data->name) { + xfree(data->name); + } + if ((data->type == wptdata) && (data->refct == 0)) { + waypt_free((waypoint *)data->data); + } + } + xfree(name); + } while ((key = avltree_next(tree, key, (void *)&name))); + } + avltree_done(tree); } static void mmo_register_icon(const int id, const char *name) { - char key[16]; - - snprintf(key, sizeof(key), "%d", id); - avltree_insert(icons, key, xstrdup(name)); + char key[16]; + + snprintf(key, sizeof(key), "%d", id); + avltree_insert(icons, key, xstrdup(name)); } @@ -320,43 +347,45 @@ static void mmo_end_of_route(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjRoute"; + const char *sobj = "CObjRoute"; #endif - route_head *rte = data->data; - char buf[7]; - - if (mmo_version >= 0x12) { - mmo_fillbuf(buf, 7, 1); - DBG((sobj, "route data (since 0x12): ")); - mmo_printbuf(buf, 7, ""); - - rte->line_color.bbggrr = le_read32(&buf[0]); - rte->line_color.opacity = 255 - (buf[6] * 51); - DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr)); - DBG((sobj, "transparency = %d (-> %d)\n", buf[6], rte->line_color.opacity)); - DBG((sobj, "for \"%s\" \n", data->name)); - } - - if (rte->rte_waypt_ct == 0) { /* don't keep empty routes */ - route_del_head(rte); - data->data = NULL; - } + route_head *rte = data->data; + char buf[7]; + + if (mmo_version >= 0x12) { + mmo_fillbuf(buf, 7, 1); + DBG((sobj, "route data (since 0x12): ")); + mmo_printbuf(buf, 7, ""); + + rte->line_color.bbggrr = le_read32(&buf[0]); + rte->line_color.opacity = 255 - (buf[6] * 51); + DBG((sobj, "color = 0x%06X\n", rte->line_color.bbggrr)); + DBG((sobj, "transparency = %d (-> %d)\n", buf[6], rte->line_color.opacity)); + DBG((sobj, "for \"%s\" \n", data->name)); + } + + if (rte->rte_waypt_ct == 0) { /* don't keep empty routes */ + route_del_head(rte); + data->data = NULL; + } } static void mmo_read_category(mmo_data_t *data) { - int marker = gbfgetuint16(fin); - - if (marker & 0x8000) { - mmo_data_t *tmp; - - DBG(("mmo_read_category", "reading category object\n")); - gbfseek(fin, -2, SEEK_CUR); - tmp = mmo_read_object(); - if (data) data->category = tmp->name; - } + int marker = gbfgetuint16(fin); + + if (marker & 0x8000) { + mmo_data_t *tmp; + + DBG(("mmo_read_category", "reading category object\n")); + gbfseek(fin, -2, SEEK_CUR); + tmp = mmo_read_object(); + if (data) { + data->category = tmp->name; + } + } } @@ -364,44 +393,44 @@ static void mmo_read_CObjIcons(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjIcons"; + const char *sobj = "CObjIcons"; #endif - int icon_id; - gbuint16 u16; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - if (mmo_version >= 0x18) { - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X\n", u16)); - - while ((icon_id = gbfgetuint32(fin))) { - char *name; - (void) gbfgetuint32(fin); - (void) gbfgetuint32(fin); - name = mmo_readstr(); - DBG((sobj, "bitmap(0x%08X) = \"%s\"\n", icon_id, name)); - mmo_register_icon(icon_id, name); - xfree(name); - // The next four bytes hold the length of the image, - // read them and then skip the image data. - gbfseek(fin, gbfgetuint32(fin), SEEK_CUR); - } + int icon_id; + gbuint16 u16; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + if (mmo_version >= 0x18) { + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X\n", u16)); + + while ((icon_id = gbfgetuint32(fin))) { + char *name; + (void) gbfgetuint32(fin); + (void) gbfgetuint32(fin); + name = mmo_readstr(); + DBG((sobj, "bitmap(0x%08X) = \"%s\"\n", icon_id, name)); + mmo_register_icon(icon_id, name); + xfree(name); + // The next four bytes hold the length of the image, + // read them and then skip the image data. + gbfseek(fin, gbfgetuint32(fin), SEEK_CUR); + } } @@ -409,121 +438,140 @@ static void mmo_read_CObjWaypoint(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjWaypoint"; + const char *sobj = "CObjWaypoint"; #endif - waypoint *wpt; - time_t time; - int rtelinks; - mmo_data_t **rtelink = NULL; - char *str; - char buf[16]; - int i, ux; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - data->data = wpt = waypt_new(); - wpt->shortname = xstrdup(data->name); - - time = data->mtime; - if (! time) time = data->ctime; - if (time > 0) wpt->creation_time = time; - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - - DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); - - rtelinks = gbfgetuint16(fin); - if (rtelinks > 0) { - - rtelink = xcalloc(sizeof(*rtelink), rtelinks); - DBG((sobj, "rtelinks = %d\n", rtelinks)); - - for (i = 0; i < rtelinks; i++) { - mmo_data_t *tmp; - - DBG((sobj, "read rtelink number %d\n", i + 1)); - rtelink[i] = tmp = mmo_read_object(); - } - - } - - str = mmo_readstr(); /* descr + url */ - if (strncmp(str, "_FILE_ ", 7) == 0) { - char *cx, *cend; - - cx = lrtrim(str + 7); - cend = strchr(cx, '\n'); - if (cend == NULL) cend = cx + strlen(cx); - - cx = lrtrim(xstrndup(cx, cend - cx)); - if (*cx) wpt->url = cx; - else xfree(cx); - - if (*cend++) wpt->notes = xstrdup(cend); - - if (wpt->url) DBG((sobj, "url = \"%s\"\n", wpt->url)); - } - else - if (*str) wpt->notes = xstrdup(str); - xfree(str); - - if (wpt->notes) DBG((sobj, "notes = \"%s\"\n", wpt->notes)); - - mmo_fillbuf(buf, 12, 1); - i = le_read32(&buf[8]); /* icon */ - if (i != -1) { - char key[16]; - char *name; - - snprintf(key, sizeof(key), "%d", i); - if (avltree_find(icons, key, (void *)&name)) { - wpt->icon_descr = xstrdup(name); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr)); - } + waypoint *wpt; + time_t time; + int rtelinks; + mmo_data_t **rtelink = NULL; + char *str; + char buf[16]; + int i, ux; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + data->data = wpt = waypt_new(); + wpt->shortname = xstrdup(data->name); + + time = data->mtime; + if (! time) { + time = data->ctime; + } + if (time > 0) { + wpt->creation_time = time; + } + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + + DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); + + rtelinks = gbfgetuint16(fin); + if (rtelinks > 0) { + + rtelink = xcalloc(sizeof(*rtelink), rtelinks); + DBG((sobj, "rtelinks = %d\n", rtelinks)); + + for (i = 0; i < rtelinks; i++) { + mmo_data_t *tmp; + + DBG((sobj, "read rtelink number %d\n", i + 1)); + rtelink[i] = tmp = mmo_read_object(); + } + + } + + str = mmo_readstr(); /* descr + url */ + if (strncmp(str, "_FILE_ ", 7) == 0) { + char *cx, *cend; + + cx = lrtrim(str + 7); + cend = strchr(cx, '\n'); + if (cend == NULL) { + cend = cx + strlen(cx); + } + + cx = lrtrim(xstrndup(cx, cend - cx)); + if (*cx) { + wpt->url = cx; + } else { + xfree(cx); + } + + if (*cend++) { + wpt->notes = xstrdup(cend); + } + + if (wpt->url) { + DBG((sobj, "url = \"%s\"\n", wpt->url)); + } + } else if (*str) { + wpt->notes = xstrdup(str); + } + xfree(str); + + if (wpt->notes) { + DBG((sobj, "notes = \"%s\"\n", wpt->notes)); + } + + mmo_fillbuf(buf, 12, 1); + i = le_read32(&buf[8]); /* icon */ + if (i != -1) { + char key[16]; + char *name; + + snprintf(key, sizeof(key), "%d", i); + if (avltree_find(icons, key, (void *)&name)) { + wpt->icon_descr = xstrdup(name); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + DBG((sobj, "icon = \"%s\"\n", wpt->icon_descr)); + } #ifdef MMO_DBG - else { - DBG((sobj, "icon not found for 0x%08X\n", i)); - } + else { + DBG((sobj, "icon not found for 0x%08X\n", i)); + } #endif - } - - wpt->proximity = le_read_float(&buf[4]); - if (wpt->proximity) { - wpt->wpt_flags.proximity = 1; - DBG((sobj, "proximity = %f\n", wpt->proximity)); - } - - str = mmo_readstr(); /* name on gps ??? option ??? */ - if (*str) { - wpt->description = wpt->shortname; - wpt->shortname = str; - DBG((sobj, "name on gps = %s\n", str)); - } - else xfree(str); - - ux = gbfgetuint32(fin); - DBG((sobj, "proximity type = %d\n", ux)); - - data->loaded = 1; - - if (rtelink) xfree(rtelink); - else waypt_add(mmo_get_waypt(data)); + } + + wpt->proximity = le_read_float(&buf[4]); + if (wpt->proximity) { + wpt->wpt_flags.proximity = 1; + DBG((sobj, "proximity = %f\n", wpt->proximity)); + } + + str = mmo_readstr(); /* name on gps ??? option ??? */ + if (*str) { + wpt->description = wpt->shortname; + wpt->shortname = str; + DBG((sobj, "name on gps = %s\n", str)); + } else { + xfree(str); + } + + ux = gbfgetuint32(fin); + DBG((sobj, "proximity type = %d\n", ux)); + + data->loaded = 1; + + if (rtelink) { + xfree(rtelink); + } else { + waypt_add(mmo_get_waypt(data)); + } } @@ -531,71 +579,76 @@ static void mmo_read_CObjRoute(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjRoute"; + const char *sobj = "CObjRoute"; #endif - int rtept; - route_head *rte; - char buf[16]; - int ux; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - data->data = rte = route_head_alloc(); - rte->rte_name = xstrdup(data->name); - route_add_head(rte); - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - ux = gbfgetc(fin); /* line label */ - DBG((sobj, "line label = %d\n", ux)); - - data->left = rtept = gbfgetint16(fin); - DBG((sobj, "route has %d point(s)\n", rtept)); - - if (data->left <= 0) { - if (mmo_version >= 0x12) mmo_fillbuf(buf, 7, 1); - route_del_head(rte); - data->data = NULL; - - return; - } - - while (data->left > 0) { - mmo_data_t *tmp; - - DBG((sobj, "read next waypoint\n")); - tmp = mmo_read_object(); - if (tmp && tmp->data && (tmp->type = wptdata)) { - waypoint *wpt; - - /* FIXME: At this point this waypoint maybe not fully loaded (initialized) !!! - We need a final procedure to handle this !!! */ - if (! tmp->loaded) { - wpt = waypt_new(); - wpt->latitude = 0; - wpt->longitude = 0; - xasprintf(&wpt->shortname, "\01%p", tmp); - } - else wpt = mmo_get_waypt(tmp); - - route_add_wpt(rte, wpt); - data->left--; - } - } - - if (mmo_version > 0x11) mmo_end_of_route(data); + int rtept; + route_head *rte; + char buf[16]; + int ux; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + data->data = rte = route_head_alloc(); + rte->rte_name = xstrdup(data->name); + route_add_head(rte); + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + ux = gbfgetc(fin); /* line label */ + DBG((sobj, "line label = %d\n", ux)); + + data->left = rtept = gbfgetint16(fin); + DBG((sobj, "route has %d point(s)\n", rtept)); + + if (data->left <= 0) { + if (mmo_version >= 0x12) { + mmo_fillbuf(buf, 7, 1); + } + route_del_head(rte); + data->data = NULL; + + return; + } + + while (data->left > 0) { + mmo_data_t *tmp; + + DBG((sobj, "read next waypoint\n")); + tmp = mmo_read_object(); + if (tmp && tmp->data && (tmp->type = wptdata)) { + waypoint *wpt; + + /* FIXME: At this point this waypoint maybe not fully loaded (initialized) !!! + We need a final procedure to handle this !!! */ + if (! tmp->loaded) { + wpt = waypt_new(); + wpt->latitude = 0; + wpt->longitude = 0; + xasprintf(&wpt->shortname, "\01%p", tmp); + } else { + wpt = mmo_get_waypt(tmp); + } + + route_add_wpt(rte, wpt); + data->left--; + } + } + + if (mmo_version > 0x11) { + mmo_end_of_route(data); + } } @@ -603,112 +656,112 @@ static void mmo_read_CObjTrack(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjTrack"; + const char *sobj = "CObjTrack"; #endif - int tp, ctp; - route_head *trk; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - trk = route_head_alloc(); - trk->rte_name = xstrdup(data->name); - track_add_head(trk); - - if (mmo_version >= 0x18) { - gbuint16 u16; - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); - } - - tp = gbfgetint16(fin); - DBG((sobj, "track has %d point(s)\n", tp)); - - for (ctp = 0; ctp < tp; ctp++) { - waypoint *wpt; - char unk; - - wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); - unk = gbfgetc(fin); - DBG((sobj, "Unknown = 0x%02X (%d)\n", unk, unk)); - - wpt->creation_time = gbfgetint32(fin); - wpt->altitude = gbfgetflt(fin); - - if (unk != 0) { - gbuint16 ux; - ux = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); - if (unk > 1) { - gbuint16 ux; - ux = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); - } - } - track_add_wpt(trk, wpt); - } - - if (mmo_version > 0) { - gbuint32 u32; - - u32 = gbfgetuint32(fin); /* Min. update interval */ - DBG((sobj, "min. update interval = %d\n", u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "min. update distance = %d\n", u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "track partition interval = %d\n", u32 / 60)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); - u32 = gbfgetuint32(fin); /* unknown */ - DBG((sobj, "tick interval = %d\n", u32 / 60)); - trk->line_color.bbggrr = gbfgetuint32(fin); /* rgb color */ - trk->line_color.opacity = 255; - DBG((sobj, "color = 0x%06X\n", trk->line_color.bbggrr)); - } - - if (mmo_version >= 0x12) { - char u8; - - u8 = gbfgetc(fin); - DBG((sobj, "line width = %d - (since 0x12)\n", u8)); - u8 = gbfgetc(fin); - DBG((sobj, "line style = %d - (since 0x12)\n", u8)); - u8 = gbfgetc(fin); - DBG((sobj, "transparency = %d - (since 0x12)\n", u8)); - trk->line_color.opacity = 255 - (u8 * 51); - - if (mmo_version >= 0x16) { - char u8; - gbuint16 u16; - - u8 = gbfgetc(fin); - DBG((sobj, "unknown value = 0x%02X (since 0x16)\n", u8)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); - u16 = gbfgetuint16(fin); - DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); - } - } - - if (trk->rte_waypt_ct == 0) { - track_del_head(trk); - data->data = NULL; - } + int tp, ctp; + route_head *trk; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + trk = route_head_alloc(); + trk->rte_name = xstrdup(data->name); + track_add_head(trk); + + if (mmo_version >= 0x18) { + gbuint16 u16; + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x18)\n", u16)); + } + + tp = gbfgetint16(fin); + DBG((sobj, "track has %d point(s)\n", tp)); + + for (ctp = 0; ctp < tp; ctp++) { + waypoint *wpt; + char unk; + + wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", wpt->latitude, wpt->longitude)); + unk = gbfgetc(fin); + DBG((sobj, "Unknown = 0x%02X (%d)\n", unk, unk)); + + wpt->creation_time = gbfgetint32(fin); + wpt->altitude = gbfgetflt(fin); + + if (unk != 0) { + gbuint16 ux; + ux = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); + if (unk > 1) { + gbuint16 ux; + ux = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (%d)\n", ux, ux)); + } + } + track_add_wpt(trk, wpt); + } + + if (mmo_version > 0) { + gbuint32 u32; + + u32 = gbfgetuint32(fin); /* Min. update interval */ + DBG((sobj, "min. update interval = %d\n", u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "min. update distance = %d\n", u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "track partition interval = %d\n", u32 / 60)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "unknown value = 0x%08X (%d)\n", u32, u32)); + u32 = gbfgetuint32(fin); /* unknown */ + DBG((sobj, "tick interval = %d\n", u32 / 60)); + trk->line_color.bbggrr = gbfgetuint32(fin); /* rgb color */ + trk->line_color.opacity = 255; + DBG((sobj, "color = 0x%06X\n", trk->line_color.bbggrr)); + } + + if (mmo_version >= 0x12) { + char u8; + + u8 = gbfgetc(fin); + DBG((sobj, "line width = %d - (since 0x12)\n", u8)); + u8 = gbfgetc(fin); + DBG((sobj, "line style = %d - (since 0x12)\n", u8)); + u8 = gbfgetc(fin); + DBG((sobj, "transparency = %d - (since 0x12)\n", u8)); + trk->line_color.opacity = 255 - (u8 * 51); + + if (mmo_version >= 0x16) { + char u8; + gbuint16 u16; + + u8 = gbfgetc(fin); + DBG((sobj, "unknown value = 0x%02X (since 0x16)\n", u8)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); + u16 = gbfgetuint16(fin); + DBG((sobj, "unknown value = 0x%04X (since 0x16)\n", u16)); + } + } + + if (trk->rte_waypt_ct == 0) { + track_del_head(trk); + data->data = NULL; + } } @@ -716,31 +769,31 @@ static void mmo_read_CObjText(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjText"; + const char *sobj = "CObjText"; #endif - char buf[28]; - double lat, lon; - char *text, *font; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); + char buf[28]; + double lat, lon; + char *text, *font; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); - lat = gbfgetdbl(fin); - lon = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", lat, lon)); + lat = gbfgetdbl(fin); + lon = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", lat, lon)); - text = mmo_readstr(); - DBG((sobj, "text = \"%s\"\n", text)); - xfree(text); + text = mmo_readstr(); + DBG((sobj, "text = \"%s\"\n", text)); + xfree(text); - mmo_fillbuf(buf, 28, 1); + mmo_fillbuf(buf, 28, 1); - font = mmo_readstr(); - DBG((sobj, "font = \"%s\"\n", font)); - xfree(font); + font = mmo_readstr(); + DBG((sobj, "font = \"%s\"\n", font)); + xfree(font); - mmo_fillbuf(buf, 25, 1); + mmo_fillbuf(buf, 25, 1); } @@ -748,160 +801,187 @@ static void mmo_read_CObjCurrentPosition(mmo_data_t *data) { #ifdef MMO_DBG - const char *sobj = "CObjCurrentPosition"; + const char *sobj = "CObjCurrentPosition"; #endif - char buf[24]; - double lat, lon; - - DBG((sobj, ":-----------------------------------------------------\n")); - DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", - data->name, data->visible ? "yes" : "NO", data->objid)); - - lat = gbfgetdbl(fin); - lon = gbfgetdbl(fin); - DBG((sobj, "coordinates = %f / %f\n", lat, lon)); - - mmo_fillbuf(buf, 24, 1); - - if (mmo_version >= 0x14) { - char *name; - - name = mmo_readstr(); - DBG((sobj, "name = \"%s\"\n", name)); - xfree(name); - mmo_fillbuf(buf, 13, 1); - } + char buf[24]; + double lat, lon; + + DBG((sobj, ":-----------------------------------------------------\n")); + DBG((sobj, "name = \"%s\" [ visible=%s, id=0x%04X ]\n", + data->name, data->visible ? "yes" : "NO", data->objid)); + + lat = gbfgetdbl(fin); + lon = gbfgetdbl(fin); + DBG((sobj, "coordinates = %f / %f\n", lat, lon)); + + mmo_fillbuf(buf, 24, 1); + + if (mmo_version >= 0x14) { + char *name; + + name = mmo_readstr(); + DBG((sobj, "name = \"%s\"\n", name)); + xfree(name); + mmo_fillbuf(buf, 13, 1); + } } static mmo_data_t * mmo_read_object(void) { - int objid; - mmo_data_t *data = NULL; - - // There are three cases: - // a new object of a type that has not occurred previously in this file; - // a new object; or - // a back reference to an object that appears earlier in the file. - - objid = gbfgetuint16(fin); - if (objid == 0xFFFF) { - gbuint16 version; - char *sobj; - int len; - DBG(("mmo_read_object", "Registering new object type\n")); - - objid = mmo_object_id++; - - version = gbfgetuint16(fin); - is_fatal(version != mmo_version, MYNAME ": Invalid version identifier!\n"); - - len = gbfgetint16(fin); - - sobj = xmalloc(len + 1); - sobj[len] = '\0'; - gbfread(sobj, len, 1, fin); - DBG(("mmo_read_object", "%s\n", sobj)); - - if (strcmp(sobj, "CObjIcons") == 0) ico_object_id = objid; - else if (strcmp(sobj, "CCategory") == 0) cat_object_id = objid; - else if (strcmp(sobj, "CObjWaypoint") == 0) wpt_object_id = objid; - else if (strcmp(sobj, "CObjRoute") == 0) rte_object_id = objid; - else if (strcmp(sobj, "CObjTrack") == 0) trk_object_id = objid; - else if (strcmp(sobj, "CObjCurrentPosition") == 0) pos_object_id = objid; - else if (strcmp(sobj, "CObjText") == 0) txt_object_id = objid; - else - fatal(MYNAME ": Unknown Object \"%s\"!\n", sobj); - xfree(sobj); - } - - DBG(("mmo_read_object", "objid = 0x%04X\n", objid)); - - if (objid & 0x8000) { - data = mmo_register_object(mmo_object_id++, NULL, 0); - data->name = mmo_readstr(); - - if (objid != cat_object_id) { - gbuint32 obj_type; - data->ctime = gbfgetuint32(fin); - data->mtime = gbfgetuint32(fin); - data->locked = gbfgetc(fin); - data->visible = gbfgetc(fin); - - obj_type = gbfgetuint32(fin); + int objid; + mmo_data_t *data = NULL; + + // There are three cases: + // a new object of a type that has not occurred previously in this file; + // a new object; or + // a back reference to an object that appears earlier in the file. + + objid = gbfgetuint16(fin); + if (objid == 0xFFFF) { + gbuint16 version; + char *sobj; + int len; + DBG(("mmo_read_object", "Registering new object type\n")); + + objid = mmo_object_id++; + + version = gbfgetuint16(fin); + is_fatal(version != mmo_version, MYNAME ": Invalid version identifier!\n"); + + len = gbfgetint16(fin); + + sobj = xmalloc(len + 1); + sobj[len] = '\0'; + gbfread(sobj, len, 1, fin); + DBG(("mmo_read_object", "%s\n", sobj)); + + if (strcmp(sobj, "CObjIcons") == 0) { + ico_object_id = objid; + } else if (strcmp(sobj, "CCategory") == 0) { + cat_object_id = objid; + } else if (strcmp(sobj, "CObjWaypoint") == 0) { + wpt_object_id = objid; + } else if (strcmp(sobj, "CObjRoute") == 0) { + rte_object_id = objid; + } else if (strcmp(sobj, "CObjTrack") == 0) { + trk_object_id = objid; + } else if (strcmp(sobj, "CObjCurrentPosition") == 0) { + pos_object_id = objid; + } else if (strcmp(sobj, "CObjText") == 0) { + txt_object_id = objid; + } else { + fatal(MYNAME ": Unknown Object \"%s\"!\n", sobj); + } + xfree(sobj); + } + + DBG(("mmo_read_object", "objid = 0x%04X\n", objid)); + + if (objid & 0x8000) { + data = mmo_register_object(mmo_object_id++, NULL, 0); + data->name = mmo_readstr(); + + if (objid != cat_object_id) { + gbuint32 obj_type; + data->ctime = gbfgetuint32(fin); + data->mtime = gbfgetuint32(fin); + data->locked = gbfgetc(fin); + data->visible = gbfgetc(fin); + + obj_type = gbfgetuint32(fin); #ifdef MMO_DBG - gbuint32 expected_type = 0xFFFFFFFF; - if (objid == ico_object_id) expected_type = obj_type_ico; - else if (objid == trk_object_id) expected_type = obj_type_trk; - else if (objid == wpt_object_id) expected_type = obj_type_wpt; - else if (objid == rte_object_id) expected_type = obj_type_rte; - else if (objid == txt_object_id) expected_type = obj_type_txt; - if (mmo_version >= 0x18) expected_type <<= 24; - DBG(("mmo_read_object", "object type = 0x%08X\n", obj_type)); - if (obj_type != expected_type) - DBG(("mmo_read_object", " expected 0x%08X\n", expected_type)); + gbuint32 expected_type = 0xFFFFFFFF; + if (objid == ico_object_id) { + expected_type = obj_type_ico; + } else if (objid == trk_object_id) { + expected_type = obj_type_trk; + } else if (objid == wpt_object_id) { + expected_type = obj_type_wpt; + } else if (objid == rte_object_id) { + expected_type = obj_type_rte; + } else if (objid == txt_object_id) { + expected_type = obj_type_txt; + } + if (mmo_version >= 0x18) { + expected_type <<= 24; + } + DBG(("mmo_read_object", "object type = 0x%08X\n", obj_type)); + if (obj_type != expected_type) { + DBG(("mmo_read_object", " expected 0x%08X\n", expected_type)); + } #endif - if (objid != ico_object_id) mmo_read_category(data); - DBG(("mmo_read_object", "Category : %s\n", - data->category ? data->category : "[No category]")); - } - - if (objid == cat_object_id) ; /* do nothing */ - else if (objid == ico_object_id) mmo_read_CObjIcons(data); - else if (objid == trk_object_id) { - data->type = trkdata; - mmo_read_CObjTrack(data); - } - else if (objid == wpt_object_id) { - data->type = wptdata; - mmo_read_CObjWaypoint(data); - } - else if (objid == rte_object_id) { - data->type = rtedata; - mmo_read_CObjRoute(data); - } - else if (objid == pos_object_id) mmo_read_CObjCurrentPosition(data); - else if (objid == txt_object_id) mmo_read_CObjText(data); - else - fatal(MYNAME ": Unregistered Object-ID 0x%04X\n", objid); - } - else data = mmo_get_object(objid); - - return data; + if (objid != ico_object_id) { + mmo_read_category(data); + } + DBG(("mmo_read_object", "Category : %s\n", + data->category ? data->category : "[No category]")); + } + + if (objid == cat_object_id) ; /* do nothing */ + else if (objid == ico_object_id) { + mmo_read_CObjIcons(data); + } else if (objid == trk_object_id) { + data->type = trkdata; + mmo_read_CObjTrack(data); + } else if (objid == wpt_object_id) { + data->type = wptdata; + mmo_read_CObjWaypoint(data); + } else if (objid == rte_object_id) { + data->type = rtedata; + mmo_read_CObjRoute(data); + } else if (objid == pos_object_id) { + mmo_read_CObjCurrentPosition(data); + } else if (objid == txt_object_id) { + mmo_read_CObjText(data); + } else { + fatal(MYNAME ": Unregistered Object-ID 0x%04X\n", objid); + } + } else { + data = mmo_get_object(objid); + } + + return data; } static void mmo_finalize_rtept_cb(const waypoint *wptref) { - waypoint *wpt = (waypoint *)wptref; - - if ((wpt->shortname[0] == 1) && (wpt->latitude == 0) && (wpt->longitude == 0)) { - mmo_data_t *data; - waypoint *wpt2; - - sscanf(wpt->shortname + 1, "%p", &data); - wpt2 = (waypoint *)data->data; - - wpt->latitude = wpt2->latitude; - wpt->longitude = wpt2->longitude; - - xfree(wpt->shortname); - wpt->shortname = xstrdup(wpt2->shortname); - - if (wpt2->description) wpt->description = xstrdup(wpt2->description); - if (wpt2->notes) wpt->notes = xstrdup(wpt2->notes); - if (wpt2->url) wpt->notes = xstrdup(wpt2->url); - - wpt->proximity = wpt2->proximity; - wpt->wpt_flags.proximity = wpt2->wpt_flags.proximity; - - if (wpt2->icon_descr) { - wpt->icon_descr = xstrdup(wpt2->icon_descr); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - } + waypoint *wpt = (waypoint *)wptref; + + if ((wpt->shortname[0] == 1) && (wpt->latitude == 0) && (wpt->longitude == 0)) { + mmo_data_t *data; + waypoint *wpt2; + + sscanf(wpt->shortname + 1, "%p", &data); + wpt2 = (waypoint *)data->data; + + wpt->latitude = wpt2->latitude; + wpt->longitude = wpt2->longitude; + + xfree(wpt->shortname); + wpt->shortname = xstrdup(wpt2->shortname); + + if (wpt2->description) { + wpt->description = xstrdup(wpt2->description); + } + if (wpt2->notes) { + wpt->notes = xstrdup(wpt2->notes); + } + if (wpt2->url) { + wpt->notes = xstrdup(wpt2->url); + } + + wpt->proximity = wpt2->proximity; + wpt->wpt_flags.proximity = wpt2->wpt_flags.proximity; + + if (wpt2->icon_descr) { + wpt->icon_descr = xstrdup(wpt2->icon_descr); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + } } /******************************************************************************* @@ -911,36 +991,36 @@ mmo_finalize_rtept_cb(const waypoint *wptref) static void mmo_rd_init(const char *fname) { - int i; - - fin = gbfopen_le(fname, "rb", MYNAME); - - category_ids = avltree_init(0, MYNAME); - objects = avltree_init(0, MYNAME); - icons = avltree_init(0, MYNAME); - - ico_object_id = pos_object_id = txt_object_id = cat_object_id = 0; - wpt_object_id = rte_object_id = trk_object_id = 0; - - mmo_object_id = 0x8001; - - i = 0; - while (mmo_icon_value_table[i].icon) { - mmo_register_icon(mmo_icon_value_table[i].value, mmo_icon_value_table[i].icon); - i++; - } + int i; + + fin = gbfopen_le(fname, "rb", MYNAME); + + category_ids = avltree_init(0, MYNAME); + objects = avltree_init(0, MYNAME); + icons = avltree_init(0, MYNAME); + + ico_object_id = pos_object_id = txt_object_id = cat_object_id = 0; + wpt_object_id = rte_object_id = trk_object_id = 0; + + mmo_object_id = 0x8001; + + i = 0; + while (mmo_icon_value_table[i].icon) { + mmo_register_icon(mmo_icon_value_table[i].value, mmo_icon_value_table[i].icon); + i++; + } } -static void +static void mmo_rd_deinit(void) { - route_disp_session(curr_session(), NULL, NULL, mmo_finalize_rtept_cb); + route_disp_session(curr_session(), NULL, NULL, mmo_finalize_rtept_cb); - mmo_release_avltree(icons, 0); - mmo_release_avltree(category_ids, 0); - mmo_release_avltree(objects, 1); - gbfclose(fin); + mmo_release_avltree(icons, 0); + mmo_release_avltree(category_ids, 0); + mmo_release_avltree(objects, 1); + gbfclose(fin); } @@ -948,46 +1028,48 @@ static void mmo_read(void) { #ifdef MMO_DBG - const char *sobj = "main"; + const char *sobj = "main"; #endif - gbfile *fx; - int i; + gbfile *fx; + int i; + + /* copy file to memory stream (needed for seek-ops and piped commands) */ - /* copy file to memory stream (needed for seek-ops and piped commands) */ + DBG(("main", "loading file \"%s\".\n", fin->name)); - DBG(("main", "loading file \"%s\".\n", fin->name)); - - fx = gbfopen(NULL, "wb", MYNAME); - gbfcopyfrom(fx, fin, 0x7FFFFFFF); - gbfrewind(fx); - gbfclose(fin); - fin = fx; - - mmo_obj_ct = gbfgetuint16(fin); - DBG((sobj, "number of objects = %d\n", mmo_obj_ct)); - - i = gbfgetuint16(fin); - if (i != 0xFFFF) fatal(MYNAME ": Marker not equal to 0xFFFF!\n"); + fx = gbfopen(NULL, "wb", MYNAME); + gbfcopyfrom(fx, fin, 0x7FFFFFFF); + gbfrewind(fx); + gbfclose(fin); + fin = fx; - mmo_version = gbfgetuint16(fin); - DBG((sobj, "version = 0x%02X\n", mmo_version)); + mmo_obj_ct = gbfgetuint16(fin); + DBG((sobj, "number of objects = %d\n", mmo_obj_ct)); - mmo_filemark = 0xFFFF0000UL | be_read16(&mmo_version); - DBG((sobj, "filemark = 0x%08X\n", mmo_filemark)); + i = gbfgetuint16(fin); + if (i != 0xFFFF) { + fatal(MYNAME ": Marker not equal to 0xFFFF!\n"); + } - gbfseek(fin, -4, SEEK_CUR); + mmo_version = gbfgetuint16(fin); + DBG((sobj, "version = 0x%02X\n", mmo_version)); - while (! gbfeof(fin)) { /* main read loop */ + mmo_filemark = 0xFFFF0000UL | be_read16(&mmo_version); + DBG((sobj, "filemark = 0x%08X\n", mmo_filemark)); - (void) mmo_read_object(); + gbfseek(fin, -4, SEEK_CUR); - } + while (! gbfeof(fin)) { /* main read loop */ + + (void) mmo_read_object(); + + } #ifdef MMO_DBG - printf("\n" MYNAME ":---------------------------------------\n"); - printf(MYNAME ": EOF reached, nice!!!\n"); - printf(MYNAME ": =======================================\n\n"); -#endif + printf("\n" MYNAME ":---------------------------------------\n"); + printf(MYNAME ": EOF reached, nice!!!\n"); + printf(MYNAME ": =======================================\n\n"); +#endif } /**************************************************************************/ @@ -995,309 +1077,332 @@ mmo_read(void) static void mmo_register_category_names(const char *name) { - char key[16]; + char key[16]; - snprintf(key, sizeof(key), "%d", mmo_object_id); - avltree_insert(category_names, name, xstrdup(key)); + snprintf(key, sizeof(key), "%d", mmo_object_id); + avltree_insert(category_names, name, xstrdup(key)); } static void mmo_writestr(const char *str) { - int len = strlen(str); - - if (len > 254) { - len = len & 0x7FFF; - gbfputc(0xFF, fout); - gbfputint16(len, fout); - } - else gbfputc(len, fout); - if (len) gbfwrite(str, len, 1, fout); + int len = strlen(str); + + if (len > 254) { + len = len & 0x7FFF; + gbfputc(0xFF, fout); + gbfputint16(len, fout); + } else { + gbfputc(len, fout); + } + if (len) { + gbfwrite(str, len, 1, fout); + } } static void mmo_enum_waypt_cb(const waypoint *wpt) { - mmo_obj_ct++; + mmo_obj_ct++; } static void mmo_enum_route_cb(const route_head *rte) { - if (rte->rte_waypt_ct > 0) mmo_obj_ct++; + if (rte->rte_waypt_ct > 0) { + mmo_obj_ct++; + } } static int mmo_write_obj_mark(const char *sobj, const char *name) { - char *key; - gbuint16 nr; - char buf[16]; - int res; - - if (avltree_find(mmobjects, sobj, (void *)&key)) { - nr = (unsigned)atoi(key); - gbfputuint16(nr, fout); - } - else { - mmo_object_id++; - snprintf(buf, sizeof(buf), "%u", mmo_object_id); - - DBG(("write", "object \"%s\", registered type \"%s\" (id = 0x%04X)\n", - name, sobj, mmo_object_id)); - - avltree_insert(mmobjects, sobj, xstrdup(buf)); - - gbfputuint32(mmo_filemark, fout); - gbfputuint16(strlen(sobj), fout); - gbfwrite(sobj, strlen(sobj), 1, fout); - } - - mmo_object_id++; - res = mmo_object_id; - mmo_writestr(name); - - return res; + char *key; + gbuint16 nr; + char buf[16]; + int res; + + if (avltree_find(mmobjects, sobj, (void *)&key)) { + nr = (unsigned)atoi(key); + gbfputuint16(nr, fout); + } else { + mmo_object_id++; + snprintf(buf, sizeof(buf), "%u", mmo_object_id); + + DBG(("write", "object \"%s\", registered type \"%s\" (id = 0x%04X)\n", + name, sobj, mmo_object_id)); + + avltree_insert(mmobjects, sobj, xstrdup(buf)); + + gbfputuint32(mmo_filemark, fout); + gbfputuint16(strlen(sobj), fout); + gbfwrite(sobj, strlen(sobj), 1, fout); + } + + mmo_object_id++; + res = mmo_object_id; + mmo_writestr(name); + + return res; } static void mmo_write_category(const char *sobj, const char *name) { - char *key; - gbuint16 nr; - - if (avltree_find(category_names, name, (void *)&key)) { - nr = (unsigned)atoi(key); - gbfputuint16(nr & 0x7FFF, fout); - } - else { - mmo_write_obj_mark(sobj, name); - mmo_register_category_names(name); - } + char *key; + gbuint16 nr; + + if (avltree_find(category_names, name, (void *)&key)) { + nr = (unsigned)atoi(key); + gbfputuint16(nr & 0x7FFF, fout); + } else { + mmo_write_obj_mark(sobj, name); + mmo_register_category_names(name); + } } static int -mmo_write_obj_head(const char *sobj, const char *name, const time_t ctime, - const gbuint32 obj_type) +mmo_write_obj_head(const char *sobj, const char *name, const time_t ctime, + const gbuint32 obj_type) { - int res; + int res; - res = mmo_write_obj_mark(sobj, name); - - gbfputuint32(ctime, fout); - gbfputuint32(ctime, fout); + res = mmo_write_obj_mark(sobj, name); - gbfputc(*opt_locked, fout); - gbfputc(*opt_visible, fout); + gbfputuint32(ctime, fout); + gbfputuint32(ctime, fout); - gbfputuint32(obj_type, fout); - - return res; + gbfputc(*opt_locked, fout); + gbfputc(*opt_visible, fout); + + gbfputuint32(obj_type, fout); + + return res; } static void mmo_write_wpt_cb(const waypoint *wpt) { - char *str, *cx; - int objid; - time_t time; - int icon = 0; - mmo_data_t *data; - - time = wpt->creation_time; - if (time < 0) time = 0; - - if (mmo_datatype == trkdata) { - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - gbfputc(0, fout); - gbfputuint32(time, fout); - if (wpt->altitude != unknown_alt) - gbfputflt(wpt->altitude, fout); - else - gbfputflt(0, fout); - - return; - } - - DBG(("write", "waypoint \"%s\"\n", wpt->shortname ? wpt->shortname : "Mark")); - - objid = mmo_write_obj_head("CObjWaypoint", - (wpt->shortname && *wpt->shortname) ? wpt->shortname : "Mark", time, obj_type_wpt); - data = mmo_register_object(objid, wpt, wptdata); - data->refct = 1; - mmo_write_category("CCategory", (mmo_datatype == rtedata) ? "Waypoints" : "Marks"); - - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - - if (mmo_datatype == rtedata) { - int i = mmo_get_objid(mmo_rte); - gbfputuint16(1, fout); /* two extra bytes */ - gbfputuint16(i & 0x7FFF, fout); - } - else - gbfputuint16(0, fout); /* extra bytes */ - - if (wpt->url && *wpt->url) { - str = xstrdup("_FILE_ "); - str = xstrappend(str, wpt->url); - str = xstrappend(str, "\n"); - } - else str = xstrdup(""); - - cx = wpt->notes; - if (cx == NULL) cx = wpt->description; - if (cx != NULL) { - char *kml = NULL; - - if (strcmp(wpt->session->name, "kml") == 0) { - utf_string tmp; - - tmp.utfstring = cx; - tmp.is_html = 1; - cx = kml = strip_html(&tmp); - } - str = xstrappend(str, cx); - if (kml) xfree(kml); - } - mmo_writestr(str); - xfree(str); - - gbfputuint32(0x01, fout); - if WAYPT_HAS(wpt, proximity) gbfputflt((int) wpt->proximity, fout); - else gbfputflt(0, fout); - - if (wpt->icon_descr) { - int i = 0; - - while (mmo_icon_value_table[i].icon) { - if (case_ignore_strcmp(wpt->icon_descr, mmo_icon_value_table[i].icon) == 0) { - icon = mmo_icon_value_table[i].value; - break; - } - i++; - } - } - gbfputuint32(icon, fout); - - mmo_writestr(""); /* name on gps */ - gbfputuint32(0x00, fout); + char *str, *cx; + int objid; + time_t time; + int icon = 0; + mmo_data_t *data; + + time = wpt->creation_time; + if (time < 0) { + time = 0; + } + + if (mmo_datatype == trkdata) { + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + gbfputc(0, fout); + gbfputuint32(time, fout); + if (wpt->altitude != unknown_alt) { + gbfputflt(wpt->altitude, fout); + } else { + gbfputflt(0, fout); + } + + return; + } + + DBG(("write", "waypoint \"%s\"\n", wpt->shortname ? wpt->shortname : "Mark")); + + objid = mmo_write_obj_head("CObjWaypoint", + (wpt->shortname && *wpt->shortname) ? wpt->shortname : "Mark", time, obj_type_wpt); + data = mmo_register_object(objid, wpt, wptdata); + data->refct = 1; + mmo_write_category("CCategory", (mmo_datatype == rtedata) ? "Waypoints" : "Marks"); + + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + + if (mmo_datatype == rtedata) { + int i = mmo_get_objid(mmo_rte); + gbfputuint16(1, fout); /* two extra bytes */ + gbfputuint16(i & 0x7FFF, fout); + } else { + gbfputuint16(0, fout); /* extra bytes */ + } + + if (wpt->url && *wpt->url) { + str = xstrdup("_FILE_ "); + str = xstrappend(str, wpt->url); + str = xstrappend(str, "\n"); + } else { + str = xstrdup(""); + } + + cx = wpt->notes; + if (cx == NULL) { + cx = wpt->description; + } + if (cx != NULL) { + char *kml = NULL; + + if (strcmp(wpt->session->name, "kml") == 0) { + utf_string tmp; + + tmp.utfstring = cx; + tmp.is_html = 1; + cx = kml = strip_html(&tmp); + } + str = xstrappend(str, cx); + if (kml) { + xfree(kml); + } + } + mmo_writestr(str); + xfree(str); + + gbfputuint32(0x01, fout); + if WAYPT_HAS(wpt, proximity) { + gbfputflt((int) wpt->proximity, fout); + } else { + gbfputflt(0, fout); + } + + if (wpt->icon_descr) { + int i = 0; + + while (mmo_icon_value_table[i].icon) { + if (case_ignore_strcmp(wpt->icon_descr, mmo_icon_value_table[i].icon) == 0) { + icon = mmo_icon_value_table[i].value; + break; + } + i++; + } + } + gbfputuint32(icon, fout); + + mmo_writestr(""); /* name on gps */ + gbfputuint32(0x00, fout); } static void mmo_write_rte_head_cb(const route_head *rte) { - int objid; - queue *elem, *tmp; - time_t time = 0x7FFFFFFF; - - if (rte->rte_waypt_ct <= 0) return; - - mmo_rte = (route_head *)rte; - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - - if ((wpt->creation_time > 0) && (wpt->creation_time < time)) - time = wpt->creation_time; - } - if (time == 0x7FFFFFFF) time = gpsbabel_time; - - objid = mmo_write_obj_head("CObjRoute", - (rte->rte_name && *rte->rte_name) ? rte->rte_name : "Route", time, obj_type_rte); - mmo_register_object(objid, rte, rtedata); - mmo_write_category("CCategory", "Route"); - gbfputc(0, fout); /* unknown */ - gbfputuint16(rte->rte_waypt_ct, fout); + int objid; + queue *elem, *tmp; + time_t time = 0x7FFFFFFF; + + if (rte->rte_waypt_ct <= 0) { + return; + } + + mmo_rte = (route_head *)rte; + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + + if ((wpt->creation_time > 0) && (wpt->creation_time < time)) { + time = wpt->creation_time; + } + } + if (time == 0x7FFFFFFF) { + time = gpsbabel_time; + } + + objid = mmo_write_obj_head("CObjRoute", + (rte->rte_name && *rte->rte_name) ? rte->rte_name : "Route", time, obj_type_rte); + mmo_register_object(objid, rte, rtedata); + mmo_write_category("CCategory", "Route"); + gbfputc(0, fout); /* unknown */ + gbfputuint16(rte->rte_waypt_ct, fout); } static void mmo_write_rte_tail_cb(const route_head *rte) { - queue *elem, *tmp; - - if (rte->rte_waypt_ct <= 0) return; - - DBG(("write", "route with %d point(s).\n", rte->rte_waypt_ct)); - - if (mmo_version >= 0x12) { - if (rte->line_color.bbggrr < 0) { - gbfputuint32(0xFF, fout); /* color; default red */ - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc(0x00, fout); /* Transparency "Opaque" */ - } - else { - gbfputuint32(rte->line_color.bbggrr, fout); /* color */ - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc((255 - rte->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ - } - } - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - waypoint *wpt = (waypoint *)elem; - int objid = mmo_get_objid(wpt); - gbfputuint16(objid & 0x7FFF, fout); - } + queue *elem, *tmp; + + if (rte->rte_waypt_ct <= 0) { + return; + } + + DBG(("write", "route with %d point(s).\n", rte->rte_waypt_ct)); + + if (mmo_version >= 0x12) { + if (rte->line_color.bbggrr < 0) { + gbfputuint32(0xFF, fout); /* color; default red */ + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc(0x00, fout); /* Transparency "Opaque" */ + } else { + gbfputuint32(rte->line_color.bbggrr, fout); /* color */ + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc((255 - rte->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ + } + } + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + int objid = mmo_get_objid(wpt); + gbfputuint16(objid & 0x7FFF, fout); + } } static void mmo_write_trk_head_cb(const route_head *trk) { - int objid; - - if (trk->rte_waypt_ct <= 0) return; - - objid = mmo_write_obj_head("CObjTrack", - (trk->rte_name && *trk->rte_name) ? trk->rte_name : "Track", gpsbabel_time, obj_type_trk); - mmo_write_category("CCategory", "Track"); - gbfputuint16(trk->rte_waypt_ct, fout); - - mmo_register_object(objid, trk, trkdata); + int objid; + + if (trk->rte_waypt_ct <= 0) { + return; + } + + objid = mmo_write_obj_head("CObjTrack", + (trk->rte_name && *trk->rte_name) ? trk->rte_name : "Track", gpsbabel_time, obj_type_trk); + mmo_write_category("CCategory", "Track"); + gbfputuint16(trk->rte_waypt_ct, fout); + + mmo_register_object(objid, trk, trkdata); } static void mmo_write_trk_tail_cb(const route_head *trk) { - if (trk->rte_waypt_ct <= 0) return; - - gbfputuint32(0x0A, fout); /* Min. update interval */ - gbfputflt(0, fout); - gbfputflt(0, fout); - gbfputuint32(0x0F, fout); /* Min. update distance */ - gbfputuint32(0xE10, fout); /* Track partition interval */ - gbfputuint32(0x00, fout); /* ??? */ - gbfputuint32(0x12C, fout); - - if (trk->line_color.bbggrr < 0) { - gbfputuint32(0xFF0000, fout); /* color; default blue */ - if (mmo_version >= 0x12) { - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc(0x00, fout); /* Transparency "Opaque" */ - } - } - else { - gbfputuint32(trk->line_color.bbggrr, fout); /* color */ - if (mmo_version >= 0x12) { - gbfputc(0x01, fout); /* Line width "normal" */ - gbfputc(0x00, fout); /* Line style "solid"*/ - gbfputc((255 - trk->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ - } - } + if (trk->rte_waypt_ct <= 0) { + return; + } + + gbfputuint32(0x0A, fout); /* Min. update interval */ + gbfputflt(0, fout); + gbfputflt(0, fout); + gbfputuint32(0x0F, fout); /* Min. update distance */ + gbfputuint32(0xE10, fout); /* Track partition interval */ + gbfputuint32(0x00, fout); /* ??? */ + gbfputuint32(0x12C, fout); + + if (trk->line_color.bbggrr < 0) { + gbfputuint32(0xFF0000, fout); /* color; default blue */ + if (mmo_version >= 0x12) { + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc(0x00, fout); /* Transparency "Opaque" */ + } + } else { + gbfputuint32(trk->line_color.bbggrr, fout); /* color */ + if (mmo_version >= 0x12) { + gbfputc(0x01, fout); /* Line width "normal" */ + gbfputc(0x00, fout); /* Line style "solid"*/ + gbfputc((255 - trk->line_color.opacity) / 51, fout); /* Transparency "Opaque" */ + } + } } /**************************************************************************/ @@ -1305,76 +1410,80 @@ mmo_write_trk_tail_cb(const route_head *trk) static void mmo_wr_init(const char *fname) { - fout = gbfopen_le(fname, "wb", MYNAME); - - objects = avltree_init(0, MYNAME); - mmobjects = avltree_init(0, MYNAME); - category_names = avltree_init(0, MYNAME); - - mmo_object_id = 0x8000; - mmo_obj_ct = 1; /* ObjIcons always present */ - mmo_version = 0x12; /* by default we write as version 0x12 */ - if (opt_version) { - while (isspace(*opt_version)) opt_version++; - errno = 0; - mmo_version = strtol(opt_version, NULL, 0); - if (errno || ((mmo_version != 0x11) && (mmo_version != 0x12))) { - fatal(MYNAME ": Unsupported version identifier (%s)!\n", opt_version); - } - } - DBG(("write", "version = 0x%02X\n", mmo_version)); - mmo_filemark = 0xFFFFUL | (mmo_version << 16); + fout = gbfopen_le(fname, "wb", MYNAME); + + objects = avltree_init(0, MYNAME); + mmobjects = avltree_init(0, MYNAME); + category_names = avltree_init(0, MYNAME); + + mmo_object_id = 0x8000; + mmo_obj_ct = 1; /* ObjIcons always present */ + mmo_version = 0x12; /* by default we write as version 0x12 */ + if (opt_version) { + while (isspace(*opt_version)) { + opt_version++; + } + errno = 0; + mmo_version = strtol(opt_version, NULL, 0); + if (errno || ((mmo_version != 0x11) && (mmo_version != 0x12))) { + fatal(MYNAME ": Unsupported version identifier (%s)!\n", opt_version); + } + } + DBG(("write", "version = 0x%02X\n", mmo_version)); + mmo_filemark = 0xFFFFUL | (mmo_version << 16); } static void mmo_wr_deinit(void) { - mmo_release_avltree(mmobjects, 0); - mmo_release_avltree(category_names, 0); - mmo_release_avltree(objects, 1); + mmo_release_avltree(mmobjects, 0); + mmo_release_avltree(category_names, 0); + mmo_release_avltree(objects, 1); - gbfclose(fout); + gbfclose(fout); } static void mmo_write(void) { - int i; - - /* find out number of objects we have to write */ - waypt_disp_all(mmo_enum_waypt_cb); - route_disp_all(mmo_enum_route_cb, NULL, mmo_enum_waypt_cb); - track_disp_all(mmo_enum_route_cb, NULL, NULL); - - gbfputuint16(mmo_obj_ct, fout); - - mmo_write_obj_head("CObjIcons", "Unnamed object", gpsbabel_time, obj_type_ico); - for (i = 0; i < 5; i++) gbfputuint16(0, fout); - - mmo_datatype = wptdata; - waypt_disp_all(mmo_write_wpt_cb); - mmo_datatype = rtedata; - route_disp_all(mmo_write_rte_head_cb, mmo_write_rte_tail_cb, mmo_write_wpt_cb); - mmo_datatype = trkdata; - track_disp_all(mmo_write_trk_head_cb, mmo_write_trk_tail_cb, mmo_write_wpt_cb); + int i; + + /* find out number of objects we have to write */ + waypt_disp_all(mmo_enum_waypt_cb); + route_disp_all(mmo_enum_route_cb, NULL, mmo_enum_waypt_cb); + track_disp_all(mmo_enum_route_cb, NULL, NULL); + + gbfputuint16(mmo_obj_ct, fout); + + mmo_write_obj_head("CObjIcons", "Unnamed object", gpsbabel_time, obj_type_ico); + for (i = 0; i < 5; i++) { + gbfputuint16(0, fout); + } + + mmo_datatype = wptdata; + waypt_disp_all(mmo_write_wpt_cb); + mmo_datatype = rtedata; + route_disp_all(mmo_write_rte_head_cb, mmo_write_rte_tail_cb, mmo_write_wpt_cb); + mmo_datatype = trkdata; + track_disp_all(mmo_write_trk_head_cb, mmo_write_trk_tail_cb, mmo_write_wpt_cb); } /**************************************************************************/ ff_vecs_t mmo_vecs = { - ff_type_file, - FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ - mmo_rd_init, - mmo_wr_init, - mmo_rd_deinit, - mmo_wr_deinit, - mmo_read, - mmo_write, - NULL, - mmo_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ + mmo_rd_init, + mmo_wr_init, + mmo_rd_deinit, + mmo_wr_deinit, + mmo_read, + mmo_write, + NULL, + mmo_args, + CET_CHARSET_MS_ANSI, 0 }; diff --git a/gpsbabel/msroute.c b/gpsbabel/msroute.c index 83732fefd..da44eb51c 100644 --- a/gpsbabel/msroute.c +++ b/gpsbabel/msroute.c @@ -1,7 +1,7 @@ -/* +/* Support for Microsoft AutoRoute 2002 ".axe" files, - + Copyright (C) 2005,2007,2008 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -30,32 +30,30 @@ static gbfile *fin; -static arglist_t msroute_args[] = -{ - ARG_TERMINATOR +static arglist_t msroute_args[] = { + ARG_TERMINATOR }; /* MS-AutoRoute structures */ -typedef struct msroute_head_s -{ - gbuint32 U1; /* 58/02/00/00 */ - char masm[4]; /* "MASM " */ - gbuint32 U2; - gbuint32 U3; - gbint32 waypts; - gbuint32 U5; - gbuint32 U6; - gbuint32 U7; - gbuint32 U8; - gbuint32 U9; - gbuint32 U10; - gbuint32 U11; - gbuint32 U12; - gbuint32 U13; - gbuint32 U14; - gbuint32 U15; - gbuint32 U16; +typedef struct msroute_head_s { + gbuint32 U1; /* 58/02/00/00 */ + char masm[4]; /* "MASM " */ + gbuint32 U2; + gbuint32 U3; + gbint32 waypts; + gbuint32 U5; + gbuint32 U6; + gbuint32 U7; + gbuint32 U8; + gbuint32 U9; + gbuint32 U10; + gbuint32 U11; + gbuint32 U12; + gbuint32 U13; + gbuint32 U14; + gbuint32 U15; + gbuint32 U16; // short U17; // char U18; } msroute_head_t; @@ -69,66 +67,63 @@ typedef struct msroute_head_s #define BLOCKS(a, b) (((a) + (b) - 1) / (b)) -static const unsigned char ole_magic[8] = -{ - 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 +static const unsigned char ole_magic[8] = { + 0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1 }; -/* +/* The ole implementation looks like a FAT filesystem. Thatswhy i use in code fat1 as item for the "big blocks" or bbd and fat2 for "small blocks" (sbd). - + Remarks: * in the moment ole_size1 and sector_sz represents the same value * in OLE_DEBUG mode: successfully tested with 64MB++ standard MS doc's (PowerPoint, Word) */ -typedef struct ole_head_s -{ - char magic[8]; - char clsid[16]; - gbuint16 rev; /* offset 0x18 */ - gbuint16 ver; /* offset 0x1a */ - gbint16 byte_order; /* offset 0x1c */ - gbuint16 fat1_size_shift; /* offset 0x1e */ - gbuint16 fat2_size_shift; /* offset 0x20 */ - gbuint16 U7; /* offset 0x22 */ - gbuint32 U8; /* offset 0x24 */ - gbuint32 U9; /* offset 0x28 */ - gbint32 fat1_blocks; /* offset 0x2c */ - gbint32 prop_start; /* offset 0x30 */ - gbuint32 U12; /* offset 0x34 */ - gbuint32 fat1_min_size; /* offset 0x38 */ - gbint32 fat2_start; /* offset 0x3c */ - gbint32 fat2_blocks; /* offset 0x40 */ - gbint32 fat1_extra_start; /* offset 0x44 */ - gbint32 fat1_extra_ct; /* offset 0x48 */ - gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ +typedef struct ole_head_s { + char magic[8]; + char clsid[16]; + gbuint16 rev; /* offset 0x18 */ + gbuint16 ver; /* offset 0x1a */ + gbint16 byte_order; /* offset 0x1c */ + gbuint16 fat1_size_shift; /* offset 0x1e */ + gbuint16 fat2_size_shift; /* offset 0x20 */ + gbuint16 U7; /* offset 0x22 */ + gbuint32 U8; /* offset 0x24 */ + gbuint32 U9; /* offset 0x28 */ + gbint32 fat1_blocks; /* offset 0x2c */ + gbint32 prop_start; /* offset 0x30 */ + gbuint32 U12; /* offset 0x34 */ + gbuint32 fat1_min_size; /* offset 0x38 */ + gbint32 fat2_start; /* offset 0x3c */ + gbint32 fat2_blocks; /* offset 0x40 */ + gbint32 fat1_extra_start; /* offset 0x44 */ + gbint32 fat1_extra_ct; /* offset 0x48 */ + gbint32 fat1[OLE_HEAD_FAT1_CT]; /* offset 0x4c */ } ole_head_t; -typedef struct ole_prop_s -{ - gbuint16 name[32]; - gbuint16 name_sz; /* offset 0x40 */ - char ole_typ; /* offset 0x42 */ - char U1; /* offset 0x43 */ - gbuint32 previous; /* offset 0x44 */ - gbuint32 next; /* offset 0x48 */ - gbuint32 dir; /* offset 0x4c */ - gbuint32 U5; /* offset 0x50 */ - gbuint32 U6; /* offset 0x54 */ - gbuint32 U7; /* offset 0x58 */ - gbuint32 U8; /* offset 0x5c */ - gbuint32 U9; /* offset 0x60 */ - gbuint32 U10; /* offset 0x64 */ - gbuint32 U11; /* offset 0x68 */ - gbuint32 U12; /* offset 0x6c */ - gbuint32 U13; /* offset 0x70 */ - gbint32 first_sector; /* offset 0x74 */ - gbint32 data_sz; /* offset 0x78 */ - gbuint32 U16; /* offset 0x7c */ +typedef struct ole_prop_s { + gbuint16 name[32]; + gbuint16 name_sz; /* offset 0x40 */ + char ole_typ; /* offset 0x42 */ + char U1; /* offset 0x43 */ + gbuint32 previous; /* offset 0x44 */ + gbuint32 next; /* offset 0x48 */ + gbuint32 dir; /* offset 0x4c */ + gbuint32 U5; /* offset 0x50 */ + gbuint32 U6; /* offset 0x54 */ + gbuint32 U7; /* offset 0x58 */ + gbuint32 U8; /* offset 0x5c */ + gbuint32 U9; /* offset 0x60 */ + gbuint32 U10; /* offset 0x64 */ + gbuint32 U11; /* offset 0x68 */ + gbuint32 U12; /* offset 0x6c */ + gbuint32 U13; /* offset 0x70 */ + gbint32 first_sector; /* offset 0x74 */ + gbint32 data_sz; /* offset 0x78 */ + gbuint32 U16; /* offset 0x7c */ } ole_prop_t; #define DIR_ITEM_SIZE sizeof(ole_prop_t) @@ -160,9 +155,10 @@ static int ole_root_sec_ct; static void le_read32_buff(int *buff, const int count) { - int i; - for (i = 0; i < count; i++) - buff[i] = le_read32(&buff[i]); + int i; + for (i = 0; i < count; i++) { + buff[i] = le_read32(&buff[i]); + } } /* simple OLE file reader */ @@ -170,134 +166,133 @@ le_read32_buff(int *buff, const int count) static void ole_read_sector(const int sector, void *target, const char full) { - int res; - - res = gbfseek(fin, (sector + 1) * sector_sz, SEEK_SET); - is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); - res = gbfread(target, 1, sector_sz, fin); - is_fatal( - ((res < 0) || (full && (res < sector_sz))), - MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin->name); + int res; + + res = gbfseek(fin, (sector + 1) * sector_sz, SEEK_SET); + is_fatal((res != 0), MYNAME ": Could not seek file to sector %d!", sector + 1); + res = gbfread(target, 1, sector_sz, fin); + is_fatal( + ((res < 0) || (full && (res < sector_sz))), + MYNAME ": Read error (%d, sector %d) on file \"%s\"!", res, sector, fin->name); } static ole_prop_t * ole_find_property(const char *property) { - int i; - - for (i = 0; i < ole_dir_ct; i++) - { - int len, test; - char *str; - ole_prop_t *item; - - item = &ole_dir[i]; - if ((item->ole_typ != 1) && (item->ole_typ != 2) && (item->ole_typ != 5)) continue; - if ((item->data_sz <= 0) || (item->name_sz <= 0)) continue; - - len = min(OLE_MAX_NAME_LENGTH, item->name_sz / 2); - str = cet_str_uni_to_utf8((short *)&item->name, len); - test = case_ignore_strcmp(str, property); - xfree(str); - - if (test == 0) return item; - } - is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); - return 0; + int i; + + for (i = 0; i < ole_dir_ct; i++) { + int len, test; + char *str; + ole_prop_t *item; + + item = &ole_dir[i]; + if ((item->ole_typ != 1) && (item->ole_typ != 2) && (item->ole_typ != 5)) { + continue; + } + if ((item->data_sz <= 0) || (item->name_sz <= 0)) { + continue; + } + + len = min(OLE_MAX_NAME_LENGTH, item->name_sz / 2); + str = cet_str_uni_to_utf8((short *)&item->name, len); + test = case_ignore_strcmp(str, property); + xfree(str); + + if (test == 0) { + return item; + } + } + is_fatal((1), MYNAME ": \"%s\" not in property catalog!", property); + return 0; } static char * ole_read_stream(const ole_prop_t *property) { - const char *action = "ole_read_stream"; - int len, sector, big, blocksize, offs, left; - int i; - int *fat; - char *buff; - - len = property->data_sz; - - if (len >= ole_size1_min) - { - big = 1; - blocksize = ole_size1; - fat = ole_fat1; - } - else - { - big = 0; - blocksize = ole_size2; - fat = ole_fat2; - } - - offs = 0; - left = len; - sector = property->first_sector; - - i = ((len + blocksize - 1) / blocksize) * blocksize; - buff = xmalloc(i); /* blocksize aligned */ - - if (big != 0) - { - while (left > 0) - { - int bytes = (left <= blocksize) ? left : blocksize; - ole_read_sector(sector, buff + offs, (bytes >= sector_sz)); - left -= bytes; - offs += bytes; - if (left > 0) - { - sector = fat[sector]; - is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); - } - } - } - else - { - int chain = sector; - int blocks = (len + blocksize - 1) / blocksize; - int blocks_per_sector = sector_sz / blocksize; - - offs = 0; - - while (blocks-- > 0) - { - char *temp; - int block_offs; - - is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); - - sector = chain / blocks_per_sector; - is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); - - temp = ole_root_sec[sector]; - is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); - - block_offs = (chain % blocks_per_sector) * blocksize; - - memcpy(buff + offs, temp + block_offs, blocksize); - - offs += blocksize; - chain = fat[chain]; - } - } - return buff; + const char *action = "ole_read_stream"; + int len, sector, big, blocksize, offs, left; + int i; + int *fat; + char *buff; + + len = property->data_sz; + + if (len >= ole_size1_min) { + big = 1; + blocksize = ole_size1; + fat = ole_fat1; + } else { + big = 0; + blocksize = ole_size2; + fat = ole_fat2; + } + + offs = 0; + left = len; + sector = property->first_sector; + + i = ((len + blocksize - 1) / blocksize) * blocksize; + buff = xmalloc(i); /* blocksize aligned */ + + if (big != 0) { + while (left > 0) { + int bytes = (left <= blocksize) ? left : blocksize; + ole_read_sector(sector, buff + offs, (bytes >= sector_sz)); + left -= bytes; + offs += bytes; + if (left > 0) { + sector = fat[sector]; + is_fatal((sector < 0), MYNAME ": Broken stream (%s)!", action); + } + } + } else { + int chain = sector; + int blocks = (len + blocksize - 1) / blocksize; + int blocks_per_sector = sector_sz / blocksize; + + offs = 0; + + while (blocks-- > 0) { + char *temp; + int block_offs; + + is_fatal((chain < 0), MYNAME ": Broken stream (%s)!", action); + + sector = chain / blocks_per_sector; + is_fatal((sector >= ole_root_sec_ct), MYNAME ": Broken stream (%s)!", action); + + temp = ole_root_sec[sector]; + is_fatal((temp == NULL), MYNAME ": Broken stream (%s)!", action); + + block_offs = (chain % blocks_per_sector) * blocksize; + + memcpy(buff + offs, temp + block_offs, blocksize); + + offs += blocksize; + chain = fat[chain]; + } + } + return buff; } static char * ole_read_property_stream(const char *property_name, int *data_sz) { - ole_prop_t *property; - char *result; - - if ((property = ole_find_property(property_name)) == NULL) return NULL; - - result = ole_read_stream(property); - if ((result != NULL) && (data_sz != NULL)) - *data_sz = property->data_sz; - - return result; + ole_prop_t *property; + char *result; + + if ((property = ole_find_property(property_name)) == NULL) { + return NULL; + } + + result = ole_read_stream(property); + if ((result != NULL) && (data_sz != NULL)) { + *data_sz = property->data_sz; + } + + return result; } #ifdef OLE_DEBUG @@ -305,260 +300,260 @@ ole_read_property_stream(const char *property_name, int *data_sz) static void ole_test_properties() { - int i; - - for (i = 0; i < ole_dir_ct; i++) - { - char *temp; - char name[OLE_MAX_NAME_LENGTH + 1]; - ole_prop_t *p = &ole_dir[i]; - - if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) continue; - if ((p->data_sz <= 0) || (p->name_sz <= 0)) continue; - - temp = cet_str_uni_to_utf8(&p->name, min(p->name_sz / 2, OLE_MAX_NAME_LENGTH)); - strncpy(name, temp, sizeof(name)); - xfree(temp); - - printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->data_sz); - - if ((case_ignore_strcmp(name, "Root Entry") == 0) || - (p->data_sz < ole_size1_min)) - { - printf(" skipped...\n"); - continue; - } - else - { - int sector = p->first_sector; - int data_sz = p->data_sz; - int block_size = ole_size1; /* sector_sz */ - - printf("\n"); - - while ((data_sz > 0) && (sector >= 0)) - { - int bytes = (data_sz > block_size) ? block_size : data_sz; - int prev = sector; - - data_sz -= bytes; - sector = ole_fat1[sector]; - if (sector == -3) - { - printf(MYNAME ": special block at %d\n", prev); - if ((prev + 2) < ole_fat1_ct) - sector = ole_fat1[prev + 1]; - printf(MYNAME "-new sector: %d\n", sector); - } - } - is_fatal((data_sz != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", - sector, data_sz, BLOCKS(data_sz, block_size)); - } - } + int i; + + for (i = 0; i < ole_dir_ct; i++) { + char *temp; + char name[OLE_MAX_NAME_LENGTH + 1]; + ole_prop_t *p = &ole_dir[i]; + + if ((p->ole_typ != 1) && (p->ole_typ != 2) && (p->ole_typ != 5)) { + continue; + } + if ((p->data_sz <= 0) || (p->name_sz <= 0)) { + continue; + } + + temp = cet_str_uni_to_utf8(&p->name, min(p->name_sz / 2, OLE_MAX_NAME_LENGTH)); + strncpy(name, temp, sizeof(name)); + xfree(temp); + + printf(MYNAME ": ole_test_properties for \"%s\" (%d bytes):", name, p->data_sz); + + if ((case_ignore_strcmp(name, "Root Entry") == 0) || + (p->data_sz < ole_size1_min)) { + printf(" skipped...\n"); + continue; + } else { + int sector = p->first_sector; + int data_sz = p->data_sz; + int block_size = ole_size1; /* sector_sz */ + + printf("\n"); + + while ((data_sz > 0) && (sector >= 0)) { + int bytes = (data_sz > block_size) ? block_size : data_sz; + int prev = sector; + + data_sz -= bytes; + sector = ole_fat1[sector]; + if (sector == -3) { + printf(MYNAME ": special block at %d\n", prev); + if ((prev + 2) < ole_fat1_ct) { + sector = ole_fat1[prev + 1]; + } + printf(MYNAME "-new sector: %d\n", sector); + } + } + is_fatal((data_sz != 0), MYNAME ": Error in fat1 chain, sector = %d, %d bytes (=%d blocks) left!", + sector, data_sz, BLOCKS(data_sz, block_size)); + } + } } #endif static void ole_init(void) { - ole_head_t head; - int i, i_offs, sector, count, left; - int fat1_extra[128]; - - ole_fat1 = NULL; - ole_fat2 = NULL; - - sector_sz = 512; /* fixed for the moment */ - - is_fatal((sizeof(head) != sector_sz), - MYNAME ": (!) internal error - invalid header size (%lu)!", - (unsigned long) sizeof(head)); - - memset(&head, 0, sizeof(head)); - gbfread(&head, sizeof(head), 1, fin); - - is_fatal((strncmp(head.magic, (char *) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); - - head.rev = le_read16(&head.rev); - head.ver = le_read16(&head.ver); - head.byte_order = le_read16(&head.byte_order); - head.fat1_size_shift = le_read16(&head.fat1_size_shift); - head.fat2_size_shift = le_read16(&head.fat2_size_shift); - head.fat1_blocks = le_read32(&head.fat1_blocks); - head.prop_start = le_read32(&head.prop_start); - head.fat1_min_size = le_read32(&head.fat1_min_size); - head.fat2_start = le_read32(&head.fat2_start); - head.fat2_blocks = le_read32(&head.fat2_blocks); - head.fat1_extra_start = le_read32(&head.fat1_extra_start); - head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); - le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); - - ole_size1 = (1 << head.fat1_size_shift); - ole_size2 = (1 << head.fat2_size_shift); - ole_size1_min = head.fat1_min_size; + ole_head_t head; + int i, i_offs, sector, count, left; + int fat1_extra[128]; + + ole_fat1 = NULL; + ole_fat2 = NULL; + + sector_sz = 512; /* fixed for the moment */ + + is_fatal((sizeof(head) != sector_sz), + MYNAME ": (!) internal error - invalid header size (%lu)!", + (unsigned long) sizeof(head)); + + memset(&head, 0, sizeof(head)); + gbfread(&head, sizeof(head), 1, fin); + + is_fatal((strncmp(head.magic, (char *) ole_magic, sizeof(ole_magic)) != 0), MYNAME ": No MS document."); + + head.rev = le_read16(&head.rev); + head.ver = le_read16(&head.ver); + head.byte_order = le_read16(&head.byte_order); + head.fat1_size_shift = le_read16(&head.fat1_size_shift); + head.fat2_size_shift = le_read16(&head.fat2_size_shift); + head.fat1_blocks = le_read32(&head.fat1_blocks); + head.prop_start = le_read32(&head.prop_start); + head.fat1_min_size = le_read32(&head.fat1_min_size); + head.fat2_start = le_read32(&head.fat2_start); + head.fat2_blocks = le_read32(&head.fat2_blocks); + head.fat1_extra_start = le_read32(&head.fat1_extra_start); + head.fat1_extra_ct = le_read32(&head.fat1_extra_ct); + le_read32_buff(&head.fat1[0], OLE_HEAD_FAT1_CT); + + ole_size1 = (1 << head.fat1_size_shift); + ole_size2 = (1 << head.fat2_size_shift); + ole_size1_min = head.fat1_min_size; #ifdef OLE_DEBUG - printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); - printf(MYNAME "-head: byte-order = %d\n", head.byte_order); - printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); - printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); - printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); - printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); - printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); - printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); - printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); - printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); - printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); - printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); + printf(MYNAME "-head: (version.revision) = %d.%d\n", head.ver, head.rev); + printf(MYNAME "-head: byte-order = %d\n", head.byte_order); + printf(MYNAME "-head: big fat start sector = %d (0x%x)\n", head.fat1[0], (head.fat1[0] + 1) * 512); + printf(MYNAME "-head: big fat blocks = %d\n", head.fat1_blocks); + printf(MYNAME "-head: big fat block size = %d\n", (1 << head.fat1_size_shift)); + printf(MYNAME "-head: small fat start sector = %d\n", head.fat2_start); + printf(MYNAME "-head: small fat blocks = %d\n", head.fat2_blocks); + printf(MYNAME "-head: small fat block size = %d\n", (1 << head.fat2_size_shift)); + printf(MYNAME "-head: big fat minimum length = %d\n", head.fat1_min_size); + printf(MYNAME "-head: property catalog start sector = %d\n", head.prop_start); + printf(MYNAME "-head: additional big fat blocks = %d\n", head.fat1_extra_ct); + printf(MYNAME "-head: additional big fat start sector = %d (0x%x)\n", head.fat1_extra_start, (head.fat1_extra_start + 1) * 512); #endif - is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); + is_fatal((head.byte_order != -2), MYNAME ": Unsupported byte-order %d", head.byte_order); #if 0 - sector_sz = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ - /* with "sector_sz" other than 512 */ + sector_sz = ole_size1; /* i'll implement this, if i get an MS-doc (ole) */ + /* with "sector_sz" other than 512 */ #else - is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); + is_fatal((ole_size1 != 512), MYNAME ": Unsupported sector size %d", ole_size1); #endif - ole_fat1 = xmalloc(head.fat1_blocks * sector_sz); - ole_fat1_ct = (head.fat1_blocks * sector_sz) / sizeof(gbint32); - + ole_fat1 = xmalloc(head.fat1_blocks * sector_sz); + ole_fat1_ct = (head.fat1_blocks * sector_sz) / sizeof(gbint32); + #ifdef OLE_DEBUG - printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", - ole_fat1_ct, head.fat1_blocks * sector_sz, head.fat1_blocks * sector_sz * sector_sz / sizeof(gbint32)); + printf(MYNAME "-big fat: %d maximum sectors, size in memory %d, max. datasize %d bytes\n", + ole_fat1_ct, head.fat1_blocks * sector_sz, head.fat1_blocks * sector_sz * sector_sz / sizeof(gbint32)); #endif - i_offs = 0; /* load "big fat" into memory */ - left = head.fat1_blocks; - count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; - - for (i = 0; i < count; i++) - { - sector = head.fat1[i]; - ole_read_sector(sector, &ole_fat1[i_offs], 1); - i_offs += ole_size1 / 4; - } - - left -= count; - - if (left > 0) - { - sector = head.fat1_extra_start; - - while ((left > 0) && (sector >= 0)) - { - ole_read_sector(sector, &fat1_extra, 1); - le_read32_buff(&fat1_extra[0], 128); - - count = (left < 127) ? left : 127; - for (i = 0; i < count; i++) - { - ole_read_sector(fat1_extra[i], &ole_fat1[i_offs], 1); - i_offs += ole_size1 / 4; - } - left -= count; - if (left > 0) - sector = fat1_extra[127]; - } - is_fatal((left > 0), MYNAME ": Broken stream!"); - } - if (ole_fat1_ct > 0) - le_read32_buff(&ole_fat1[0], ole_fat1_ct); - - - /* load fat2 "small fat" into memory */ - - sector = head.fat2_start; - if (sector >= 0) - { - count = 0; - do - { - if (ole_fat2 == NULL) - ole_fat2 = (int *)xmalloc((count + 1) * sector_sz); - else - ole_fat2 = (int *)xrealloc(ole_fat2, (count + 1) * sector_sz); - - ole_read_sector(sector, (char *)ole_fat2 + (count * sector_sz), 1); - sector = ole_fat1[sector]; - - count++; - } - while (sector >= 0); - - ole_fat2_ct = (count * sector_sz) / sizeof(gbint32); - if (ole_fat2_ct > 0) - le_read32_buff(&ole_fat2[0], ole_fat2_ct); - } - - /* load directory (property catalog) */ - - sector = head.prop_start; - is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); - - count = 0; - while (sector >= 0) - { - if (ole_dir == NULL) - ole_dir = (void *)xmalloc((count + 1) * sector_sz); - else - ole_dir = (void *)xrealloc(ole_dir, (count + 1) * sector_sz); - - ole_read_sector(sector, (char *)ole_dir + (count * sector_sz), 1); - sector = ole_fat1[sector]; - - count++; - } - ole_dir_ct = (count * sector_sz) / sizeof(ole_prop_t); - - /* fix endianess of property catalog */ - - for (i = 0; i < ole_dir_ct; i++) - { - ole_prop_t *item = &ole_dir[i]; - - item->first_sector = le_read32(&item->first_sector); - item->data_sz = le_read32(&item->data_sz); - } - - ole_root = ole_find_property("Root Entry"); - - /* read fat2 data sectors given by "Root Entry" */ - - ole_root_sec_ct = (ole_root->data_sz + (sector_sz - 1)) / sector_sz; - ole_root_sec = xcalloc(ole_root_sec_ct + 1, sizeof(char *)); - - i = 0; - sector = ole_root->first_sector; - while (sector >= 0) - { - char *temp; - - temp = ole_root_sec[i++] = xmalloc(sector_sz); - - ole_read_sector(sector, temp, 1); - sector = ole_fat1[sector]; - } + i_offs = 0; /* load "big fat" into memory */ + left = head.fat1_blocks; + count = (left > OLE_HEAD_FAT1_CT) ? OLE_HEAD_FAT1_CT : left; + + for (i = 0; i < count; i++) { + sector = head.fat1[i]; + ole_read_sector(sector, &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + + left -= count; + + if (left > 0) { + sector = head.fat1_extra_start; + + while ((left > 0) && (sector >= 0)) { + ole_read_sector(sector, &fat1_extra, 1); + le_read32_buff(&fat1_extra[0], 128); + + count = (left < 127) ? left : 127; + for (i = 0; i < count; i++) { + ole_read_sector(fat1_extra[i], &ole_fat1[i_offs], 1); + i_offs += ole_size1 / 4; + } + left -= count; + if (left > 0) { + sector = fat1_extra[127]; + } + } + is_fatal((left > 0), MYNAME ": Broken stream!"); + } + if (ole_fat1_ct > 0) { + le_read32_buff(&ole_fat1[0], ole_fat1_ct); + } + + + /* load fat2 "small fat" into memory */ + + sector = head.fat2_start; + if (sector >= 0) { + count = 0; + do { + if (ole_fat2 == NULL) { + ole_fat2 = (int *)xmalloc((count + 1) * sector_sz); + } else { + ole_fat2 = (int *)xrealloc(ole_fat2, (count + 1) * sector_sz); + } + + ole_read_sector(sector, (char *)ole_fat2 + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } while (sector >= 0); + + ole_fat2_ct = (count * sector_sz) / sizeof(gbint32); + if (ole_fat2_ct > 0) { + le_read32_buff(&ole_fat2[0], ole_fat2_ct); + } + } + + /* load directory (property catalog) */ + + sector = head.prop_start; + is_fatal((sector < 0), MYNAME ": Invalid file (no property catalog)!"); + + count = 0; + while (sector >= 0) { + if (ole_dir == NULL) { + ole_dir = (void *)xmalloc((count + 1) * sector_sz); + } else { + ole_dir = (void *)xrealloc(ole_dir, (count + 1) * sector_sz); + } + + ole_read_sector(sector, (char *)ole_dir + (count * sector_sz), 1); + sector = ole_fat1[sector]; + + count++; + } + ole_dir_ct = (count * sector_sz) / sizeof(ole_prop_t); + + /* fix endianess of property catalog */ + + for (i = 0; i < ole_dir_ct; i++) { + ole_prop_t *item = &ole_dir[i]; + + item->first_sector = le_read32(&item->first_sector); + item->data_sz = le_read32(&item->data_sz); + } + + ole_root = ole_find_property("Root Entry"); + + /* read fat2 data sectors given by "Root Entry" */ + + ole_root_sec_ct = (ole_root->data_sz + (sector_sz - 1)) / sector_sz; + ole_root_sec = xcalloc(ole_root_sec_ct + 1, sizeof(char *)); + + i = 0; + sector = ole_root->first_sector; + while (sector >= 0) { + char *temp; + + temp = ole_root_sec[i++] = xmalloc(sector_sz); + + ole_read_sector(sector, temp, 1); + sector = ole_fat1[sector]; + } #ifdef OLE_DEBUG - ole_test_properties(); + ole_test_properties(); #endif } static void ole_deinit(void) { - if (ole_root_sec != NULL) - { - int i; - for (i = 0; i < ole_root_sec_ct; i++) - { - char *c; - if ((c = ole_root_sec[i])) xfree(c); - } - xfree(ole_root_sec); - } - if (ole_fat1 != NULL) xfree(ole_fat1); - if (ole_fat2 != NULL) xfree(ole_fat2); - if (ole_dir != NULL) xfree(ole_dir); + if (ole_root_sec != NULL) { + int i; + for (i = 0; i < ole_root_sec_ct; i++) { + char *c; + if ((c = ole_root_sec[i])) { + xfree(c); + } + } + xfree(ole_root_sec); + } + if (ole_fat1 != NULL) { + xfree(ole_fat1); + } + if (ole_fat2 != NULL) { + xfree(ole_fat2); + } + if (ole_dir != NULL) { + xfree(ole_dir); + } } /* global MS AutoRoute functions */ @@ -566,118 +561,119 @@ ole_deinit(void) static void msroute_read_journey(void) { - int bufsz = 0; - char *buff; - - buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); - - if ((buff != NULL) && (bufsz > 0)) - { - msroute_head_t *head = (msroute_head_t *)buff; - unsigned char *cin, *cend; - int count = 0; - route_head *route; - waypoint *wpt; - char version; - - is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); - - version = buff[0x14]; - is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); - - cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t); - cend = (unsigned char *)buff + bufsz; - - route = route_head_alloc(); - route_add_head(route); - - head->waypts = le_read32(&head->waypts); - - while (count < head->waypts) - { - int len; - - /* after version 6 we've seen data with different header length */ - /* now we try to find the next pair of names in buff */ - - while (1) { - len = *cin; - if ((cin + 120) > cend) { - cin = NULL; - break; - } - if ((cin + len < cend) && /* within buff ? */ - (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ - (cin[len + 4] == len) && /* wide string of same length ? */ - (le_read16(cin + len + 1) == 0xfeff)) { - break; - } - cin++; - } - if (cin == NULL) break; - - wpt = waypt_new(); - - len = *cin++; /* length of shortname */ - cin += len; - cin += 3; /* 0xfffeff */ - - len = *cin++; - wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len); - cin += (len * 2); /* seek over wide string */ - cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ - - /* offs 12 !!!! Latitude int32 LE */ - /* offs 16 !!!! Longitude int32 LE */ - wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); - wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); - - cin += (23 * sizeof(gbint32)); - cin += 3; - + int bufsz = 0; + char *buff; + + buff = ole_read_property_stream(MSROUTE_OBJ_NAME, &bufsz); + + if ((buff != NULL) && (bufsz > 0)) { + msroute_head_t *head = (msroute_head_t *)buff; + unsigned char *cin, *cend; + int count = 0; + route_head *route; + waypoint *wpt; + char version; + + is_fatal((strncmp(head->masm, "MASM", 4) != 0), MYNAME ": Invalid or unknown data!"); + + version = buff[0x14]; + is_fatal((version < 1) || (version > 7), MYNAME ": Unsupported version %d!", version); + + cin = (unsigned char *)buff + 71; // (at least?) sizeof(msroute_head_t); + cend = (unsigned char *)buff + bufsz; + + route = route_head_alloc(); + route_add_head(route); + + head->waypts = le_read32(&head->waypts); + + while (count < head->waypts) { + int len; + + /* after version 6 we've seen data with different header length */ + /* now we try to find the next pair of names in buff */ + + while (1) { + len = *cin; + if ((cin + 120) > cend) { + cin = NULL; + break; + } + if ((cin + len < cend) && /* within buff ? */ + (cin[len + 3] == 0xff) && /* 0xff before next length byte ? */ + (cin[len + 4] == len) && /* wide string of same length ? */ + (le_read16(cin + len + 1) == 0xfeff)) { + break; + } + cin++; + } + if (cin == NULL) { + break; + } + + wpt = waypt_new(); + + len = *cin++; /* length of shortname */ + cin += len; + cin += 3; /* 0xfffeff */ + + len = *cin++; + wpt->shortname = cet_str_uni_to_utf8((const short *)cin, len); + cin += (len * 2); /* seek over wide string */ + cin += (5 * sizeof(gbint32)); /* five unknown DWORDs */ + + /* offs 12 !!!! Latitude int32 LE */ + /* offs 16 !!!! Longitude int32 LE */ + wpt->latitude = GPS_Math_Semi_To_Deg(le_read32(cin+12)); + wpt->longitude = GPS_Math_Semi_To_Deg(le_read32(cin+16)); + + cin += (23 * sizeof(gbint32)); + cin += 3; + #ifdef OLE_DEBUG - waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ -#endif - route_add_wpt(route, wpt); - count++; - } - } - - if (buff != NULL) - xfree(buff); + waypt_add(waypt_dupe(wpt)); /* put to wpt-list to see results if no output is specified */ +#endif + route_add_wpt(route, wpt); + count++; + } + } + + if (buff != NULL) { + xfree(buff); + } } /* registered callbacks */ static void msroute_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); - - ole_init(); + fin = gbfopen(fname, "rb", MYNAME); + + ole_init(); } static void msroute_rd_deinit(void) { - ole_deinit(); + ole_deinit(); - gbfclose(fin); + gbfclose(fin); } static void msroute_read(void) { - msroute_read_journey(); + msroute_read_journey(); } ff_vecs_t msroute_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read }, - msroute_rd_init, - NULL, - msroute_rd_deinit, - NULL, - msroute_read, - NULL, - NULL, - msroute_args, - CET_CHARSET_UTF8, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + msroute_rd_init, + NULL, + msroute_rd_deinit, + NULL, + msroute_read, + NULL, + NULL, + msroute_args, + CET_CHARSET_UTF8, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/mtk_logger.c b/gpsbabel/mtk_logger.c index c48438337..6d3a9ceba 100644 --- a/gpsbabel/mtk_logger.c +++ b/gpsbabel/mtk_logger.c @@ -1,8 +1,8 @@ /* - Download track data from GPS loggers based in MTK chipset. + Download track data from GPS loggers based in MTK chipset. Copyright (C) 2007 Per Borgentun, e4borgen(at)yahoo.com - With lot of inspiration from wbt-200.c + With lot of inspiration from wbt-200.c Copyright (C) 2006 Andy Armstrong This program is free software; you can redistribute it and/or modify @@ -20,36 +20,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* +/* -------------------------------------------------------------- - This module will download track data from a MTK chipset based GPS logger. - It will also convert the raw data.bin file to MTK compatible CSV and + This module will download track data from a MTK chipset based GPS logger. + It will also convert the raw data.bin file to MTK compatible CSV and gpsbabel output of your choice. It has been tested with Transystem i-Blue 747 but other devices should work as well (Qstarz BT-Q1000, iTrek Z1, ...) - For more info and tweaks on MTK based loggers + For more info and tweaks on MTK based loggers For info about the used log format: - Module updated 2008-2009. Now also handles Holux M-241 and + Module updated 2008-2009. Now also handles Holux M-241 and Holux GR-245 aka. GPSport-245 devices. These devices have small differences in the log format and use a lower baudrate to transfer the data. - Example usage:: - # Read from USB port, output trackpoints & waypoints in GPX format + Example usage:: + # Read from USB port, output trackpoints & waypoints in GPX format ./gpsbabel -D 2 -t -w -i mtk -f /dev/ttyUSB0 -o gpx -F out.gpx - - # Parse an existing .bin file (data_2007_09_04.bin), output trackpoints as + + # Parse an existing .bin file (data_2007_09_04.bin), output trackpoints as # both CSV file and GPX, discard points without fix ./gpsbabel -D 2 -t -i mtk-bin,csv=data__2007_09_04.csv -f data_2007_09_04.bin -x discard,fixnone -o gpx -F out.gpx - Tip: Check out the -x height,wgs84tomsl filter to correct the altitude. + Tip: Check out the -x height,wgs84tomsl filter to correct the altitude. Todo: - o .... - + o .... + */ #include "defs.h" @@ -61,52 +61,54 @@ #define MYNAME "mtk_logger" /* MTK packet id's -- currently unused... */ -enum MTK_NMEA_PACKET { - PMTK_TEST = 0, - PMTK_ACK = 1, - PMTK_SYS_MSG = 10, - PMTK_CMD_HOT_START = 101, - PMTK_CMD_WARM_START = 102, - PMTK_CMD_COLD_START = 103, - PMTK_CMD_FULL_COLD_START = 104, - PMTK_CMD_LOG = 182, /* Data log commands */ - PMTK_SET_NMEA_BAUDRATE = 251, - PMTK_API_SET_DGPS_MODE = 301, - PMTK_API_SET_SBAS_ENABLED = 313, - PMTK_API_SET_NMEA_OUTPUT = 314, - PMTK_API_SET_PWR_SAV_MODE = 320, - PMTK_API_SET_DATUM = 330, - PMTK_API_SET_DATUM_ADVANCE = 331, - PMTK_API_SET_USER_OPTION = 390, - PMTK_API_Q_FIX_CTL = 400, - PMTK_API_Q_DGPS_MODE = 401, - PMTK_API_Q_SBAS_ENABLED = 413, - PMTK_API_Q_NMEA_OUTPUT = 414, - PMTK_API_Q_PWR_SAV_MODE = 420, - PMTK_API_Q_DATUM = 430, - PMTK_API_Q_DATUM_ADVANCE = 431, - PMTK_API_GET_USER_OPTION = 490, - PMTK_DT_FIX_CTL = 500, - PMTK_DT_DGPS_MODE = 501, - PMTK_DT_SBAS_ENABLED = 513, - PMTK_DT_NMEA_OUTPUT = 514, - PMTK_DT_PWR_SAV_MODE = 520, - PMTK_DT_DATUM = 530, - PMTK_DT_FLASH_USER_OPTION = 590, - PMTK_Q_VERSION = 604, - PMTK_Q_RELEASE = 605, - PMTK_DT_VERSION = 704, - PMTK_DT_RELEASE = 705 -}; - -static const unsigned char LOG_RST[16] = { - 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* start marker */ - 0x00, 0x00, 0x00, 0x00, 0x00, /* data */ - 0xbb, 0xbb, 0xbb, 0xbb }; /* end marker */ +enum MTK_NMEA_PACKET { + PMTK_TEST = 0, + PMTK_ACK = 1, + PMTK_SYS_MSG = 10, + PMTK_CMD_HOT_START = 101, + PMTK_CMD_WARM_START = 102, + PMTK_CMD_COLD_START = 103, + PMTK_CMD_FULL_COLD_START = 104, + PMTK_CMD_LOG = 182, /* Data log commands */ + PMTK_SET_NMEA_BAUDRATE = 251, + PMTK_API_SET_DGPS_MODE = 301, + PMTK_API_SET_SBAS_ENABLED = 313, + PMTK_API_SET_NMEA_OUTPUT = 314, + PMTK_API_SET_PWR_SAV_MODE = 320, + PMTK_API_SET_DATUM = 330, + PMTK_API_SET_DATUM_ADVANCE = 331, + PMTK_API_SET_USER_OPTION = 390, + PMTK_API_Q_FIX_CTL = 400, + PMTK_API_Q_DGPS_MODE = 401, + PMTK_API_Q_SBAS_ENABLED = 413, + PMTK_API_Q_NMEA_OUTPUT = 414, + PMTK_API_Q_PWR_SAV_MODE = 420, + PMTK_API_Q_DATUM = 430, + PMTK_API_Q_DATUM_ADVANCE = 431, + PMTK_API_GET_USER_OPTION = 490, + PMTK_DT_FIX_CTL = 500, + PMTK_DT_DGPS_MODE = 501, + PMTK_DT_SBAS_ENABLED = 513, + PMTK_DT_NMEA_OUTPUT = 514, + PMTK_DT_PWR_SAV_MODE = 520, + PMTK_DT_DATUM = 530, + PMTK_DT_FLASH_USER_OPTION = 590, + PMTK_Q_VERSION = 604, + PMTK_Q_RELEASE = 605, + PMTK_DT_VERSION = 704, + PMTK_DT_RELEASE = 705 +}; + +static const unsigned char LOG_RST[16] = { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, /* start marker */ + 0x00, 0x00, 0x00, 0x00, 0x00, /* data */ + 0xbb, 0xbb, 0xbb, 0xbb +}; /* end marker */ static const char *MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ - "Invalid packet", "Unsupported packet type", - "Valid packet but action failed", "Valid packet, action success" }; + "Invalid packet", "Unsupported packet type", + "Valid packet but action failed", "Valid packet, action success" +}; #define MTK_EVT_BITMASK (1<<0x02) #define MTK_EVT_PERIOD (1<<0x03) @@ -119,93 +121,93 @@ static const char *MTK_ACK[] = { /* Flags returned from PMTK001 ack packet */ /* Data id, type, sizes used by MTK chipset - don't touch.... */ enum { - UTC = 0, - VALID, - LATITUDE, - LONGITUDE, - HEIGHT, - SPEED, - HEADING, - DSTA, - DAGE, - PDOP, - HDOP, - VDOP, - NSAT, - SID, - ELEVATION, - AZIMUTH, - SNR, - RCR, - MILLISECOND, - DISTANCE, + UTC = 0, + VALID, + LATITUDE, + LONGITUDE, + HEIGHT, + SPEED, + HEADING, + DSTA, + DAGE, + PDOP, + HDOP, + VDOP, + NSAT, + SID, + ELEVATION, + AZIMUTH, + SNR, + RCR, + MILLISECOND, + DISTANCE, } DATA_TYPES; struct log_type { - int id; - int size; - const char *name; + int id; + int size; + const char *name; } log_type[32] = { - { 0, 4, "UTC" }, - { 1, 2, "VALID" }, - { 2, 8, "LATITUDE,N/S"}, - { 3, 8, "LONGITUDE,E/W"}, - { 4, 4, "HEIGHT" }, - { 5, 4, "SPEED" }, - { 6, 4, "HEADING" }, - { 7, 2, "DSTA" }, - { 8, 4, "DAGE" }, - { 9, 2, "PDOP" }, - { 10, 2, "HDOP"}, - { 11, 2, "VDOP"}, - { 12, 2, "NSAT (USED/VIEW)"}, - { 13, 4, "SID",}, - { 14, 2, "ELEVATION" }, - { 15, 2, "AZIMUTH" }, - { 16, 2, "SNR"}, - { 17, 2, "RCR"}, - { 18, 2, "MILLISECOND"}, - { 19, 8, "DISTANCE" }, - { 20, 0, NULL}, + { 0, 4, "UTC" }, + { 1, 2, "VALID" }, + { 2, 8, "LATITUDE,N/S"}, + { 3, 8, "LONGITUDE,E/W"}, + { 4, 4, "HEIGHT" }, + { 5, 4, "SPEED" }, + { 6, 4, "HEADING" }, + { 7, 2, "DSTA" }, + { 8, 4, "DAGE" }, + { 9, 2, "PDOP" }, + { 10, 2, "HDOP"}, + { 11, 2, "VDOP"}, + { 12, 2, "NSAT (USED/VIEW)"}, + { 13, 4, "SID",}, + { 14, 2, "ELEVATION" }, + { 15, 2, "AZIMUTH" }, + { 16, 2, "SNR"}, + { 17, 2, "RCR"}, + { 18, 2, "MILLISECOND"}, + { 19, 8, "DISTANCE" }, + { 20, 0, NULL}, }; struct sat_info { - char id, used; - short elevation, azimut, snr; + char id, used; + short elevation, azimut, snr; } sat_info; struct data_item { - time_t timestamp; - short valid; - double lat; - double lon; - float height; - float speed; - float heading; - short dsta; // differential station id - float dage; // differential data age - float pdop, hdop, vdop; - char sat_used, sat_view, sat_count; - short rcr; - unsigned short timestamp_ms; - double distance; - struct sat_info sat_data[32]; + time_t timestamp; + short valid; + double lat; + double lon; + float height; + float speed; + float heading; + short dsta; // differential station id + float dage; // differential data age + float pdop, hdop, vdop; + char sat_used, sat_view, sat_count; + short rcr; + unsigned short timestamp_ms; + double distance; + struct sat_info sat_data[32]; } data_item; struct mtk_loginfo { - unsigned int bitmask; - int logLen; - int period, distance, speed; /* in 10:ths of sec, m, km/h */ - int track_event; + unsigned int bitmask; + int logLen; + int period, distance, speed; /* in 10:ths of sec, m, km/h */ + int track_event; } mtk_loginfo; /* *************************************** */ -/* MTK chip based devices with different baudrate, tweaks, ... */ +/* MTK chip based devices with different baudrate, tweaks, ... */ enum MTK_DEVICE_TYPE { - MTK_LOGGER, - HOLUX_M241, - HOLUX_GR245 + MTK_LOGGER, + HOLUX_M241, + HOLUX_GR245 }; #define TIMEOUT 1500 @@ -248,236 +250,262 @@ static int mtk_parse_info(const unsigned char *data, int dataLen); // Arguments for log fetch 'mtk' command.. static arglist_t mtk_sargs[] = { - { "erase", &OPT_erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "erase_only", &OPT_erase_only, "Only erase device data, do not download anything", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "log_enable", &OPT_log_enable, "Enable logging after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "csv", &csv_file, "MTK compatible CSV output file", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &OPT_erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "erase_only", &OPT_erase_only, "Only erase device data, do not download anything", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "log_enable", &OPT_log_enable, "Enable logging after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void dbg(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vfprintf(stderr,msg, ap); - fflush(stderr); - } - va_end(ap); +static void dbg(int l, const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vfprintf(stderr,msg, ap); + fflush(stderr); + } + va_end(ap); } -static int do_send_cmd(const char *cmd, int cmdLen) { - int rc; - - dbg(6, "Send %s ", cmd); - rc = gbser_print(fd, cmd); - if ( rc != gbser_OK ) - fatal(MYNAME ": Write error (%d)\n", rc); +static int do_send_cmd(const char *cmd, int cmdLen) +{ + int rc; + + dbg(6, "Send %s ", cmd); + rc = gbser_print(fd, cmd); + if (rc != gbser_OK) { + fatal(MYNAME ": Write error (%d)\n", rc); + } - return cmdLen; + return cmdLen; } -static int do_cmd(const char *cmd, const char *expect, char **rslt, time_t timeout_sec) { - char line[256]; - int len, done, loops, cmd_erase; - int expect_len; - time_t tout; - - if ( expect ) - expect_len = strlen(expect); - else - expect_len = 0; - - time(&tout); - if ( timeout_sec > 0 ) - tout += timeout_sec; - else - tout += 1; - - cmd_erase = 0; - if ( strncmp(cmd, CMD_LOG_ERASE, 12) == 0 ){ - cmd_erase = 1; - if (global_opts.verbose_status || global_opts.debug_level > 0) { - fprintf(stderr, "Erasing "); - } - } - // dbg(6, "## Send '%s' -- Expect '%s' in %d sec\n", cmd, expect, timeout_sec); - - do_send_cmd(cmd, strlen(cmd)); // success or fatal()... - - done = 0; - loops = 0; - memset(line, '\0', sizeof(line)); - do { +static int do_cmd(const char *cmd, const char *expect, char **rslt, time_t timeout_sec) +{ + char line[256]; + int len, done, loops, cmd_erase; + int expect_len; + time_t tout; + + if (expect) { + expect_len = strlen(expect); + } else { + expect_len = 0; + } + + time(&tout); + if (timeout_sec > 0) { + tout += timeout_sec; + } else { + tout += 1; + } + + cmd_erase = 0; + if (strncmp(cmd, CMD_LOG_ERASE, 12) == 0) { + cmd_erase = 1; + if (global_opts.verbose_status || global_opts.debug_level > 0) { + fprintf(stderr, "Erasing "); + } + } + // dbg(6, "## Send '%s' -- Expect '%s' in %d sec\n", cmd, expect, timeout_sec); + + do_send_cmd(cmd, strlen(cmd)); // success or fatal()... + + done = 0; + loops = 0; + memset(line, '\0', sizeof(line)); + do { int rc; rc = gbser_read_line(fd, line, sizeof(line)-1, TIMEOUT, 0x0A, 0x0D); - if ( rc != gbser_OK) { - if ( rc == gbser_TIMEOUT && time(NULL) > tout ){ - dbg(2, "NMEA command '%s' timeout !\n", cmd); - return -1; - // fatal(MYNAME "do_cmd(): Read error (%d)\n", rc); - } - len = -1; + if (rc != gbser_OK) { + if (rc == gbser_TIMEOUT && time(NULL) > tout) { + dbg(2, "NMEA command '%s' timeout !\n", cmd); + return -1; + // fatal(MYNAME "do_cmd(): Read error (%d)\n", rc); + } + len = -1; } else { - len = strlen(line); + len = strlen(line); } loops++; dbg(8, "Read %d bytes: '%s'\n", len, line); - if ( cmd_erase && (global_opts.verbose_status || (global_opts.debug_level > 0 && global_opts.debug_level <= 3)) ){ - // erase cmd progress wheel -- only for debug level 1-3 - fprintf(stderr,"\b%c", LIVE_CHAR[loops%4]); fflush(stderr); + if (cmd_erase && (global_opts.verbose_status || (global_opts.debug_level > 0 && global_opts.debug_level <= 3))) { + // erase cmd progress wheel -- only for debug level 1-3 + fprintf(stderr,"\b%c", LIVE_CHAR[loops%4]); + fflush(stderr); } - if ( len > 5 && line[0] == '$' ){ - if ( expect_len > 0 && strncmp(&line[1], expect, expect_len) == 0 ){ - if ( cmd_erase && (global_opts.verbose_status || global_opts.debug_level > 0) ) fprintf(stderr,"\n"); - dbg(6, "NMEA command success !\n"); - if ( (len - 4) > expect_len ){ // alloc and copy data segment... - if ( line[len-3] == '*' ) - line[len-3] = '\0'; - // printf("Data segment: #%s#\n", &line[expect_len+1]); - if ( rslt ){ - *rslt = xmalloc(len-3-expect_len+1); - strcpy(*rslt, &line[expect_len+1]); - } + if (len > 5 && line[0] == '$') { + if (expect_len > 0 && strncmp(&line[1], expect, expect_len) == 0) { + if (cmd_erase && (global_opts.verbose_status || global_opts.debug_level > 0)) { + fprintf(stderr,"\n"); + } + dbg(6, "NMEA command success !\n"); + if ((len - 4) > expect_len) { // alloc and copy data segment... + if (line[len-3] == '*') { + line[len-3] = '\0'; + } + // printf("Data segment: #%s#\n", &line[expect_len+1]); + if (rslt) { + *rslt = xmalloc(len-3-expect_len+1); + strcpy(*rslt, &line[expect_len+1]); + } + } + done = 1; + } else if (strncmp(line, "$PMTK", 5) == 0) { + /* A quick parser for ACK packets */ + if (!cmd_erase && strncmp(line, "$PMTK001,", 9) == 0 && line[9] != '\0') { + char *pType, *pRslt; + int pAck; + pType = &line[9]; + pRslt = strchr(&line[9], ',') + 1; + if (memcmp(&cmd[5], pType, 3) == 0 && pRslt != NULL && *pRslt != '\0') { + pAck = *pRslt - '0'; + if (pAck != 3 && pAck >= 0 && pAck < 4) { // Erase will return '2' + dbg(1, "NMEA command '%s' failed - %s\n", cmd, MTK_ACK[pAck]); + return -1; } - done = 1; - } else if ( strncmp(line, "$PMTK", 5) == 0 ){ - /* A quick parser for ACK packets */ - if ( !cmd_erase && strncmp(line, "$PMTK001,", 9) == 0 && line[9] != '\0' ){ - char *pType, *pRslt; - int pAck; - pType = &line[9]; - pRslt = strchr(&line[9], ',') + 1; - if ( memcmp(&cmd[5], pType, 3) == 0 && pRslt != NULL && *pRslt != '\0' ){ - pAck = *pRslt - '0'; - if ( pAck != 3 && pAck >= 0 && pAck < 4 ){ // Erase will return '2' - dbg(1, "NMEA command '%s' failed - %s\n", cmd, MTK_ACK[pAck]); - return -1; - } - } - - } - dbg(6, "RECV: '%s'\n", line); } - - } - if ( !done && time(NULL) > tout ){ - dbg(1, "NMEA command '%s' timeout !\n", cmd); - return -1; + + } + dbg(6, "RECV: '%s'\n", line); } - } while ( len != 0 && loops > 0 && !done ); - return done?0:1; + + } + if (!done && time(NULL) > tout) { + dbg(1, "NMEA command '%s' timeout !\n", cmd); + return -1; + } + } while (len != 0 && loops > 0 && !done); + return done?0:1; } /******************************************************************************* * %%% global callbacks called by gpsbabel main process %%% * *******************************************************************************/ -static void mtk_rd_init_m241 (const char *fname) { - mtk_device = HOLUX_M241; - mtk_rd_init(fname); +static void mtk_rd_init_m241(const char *fname) +{ + mtk_device = HOLUX_M241; + mtk_rd_init(fname); } -static void mtk_rd_init(const char *fname){ - int rc; - char *model; - - port = xstrdup(fname); - - errno = 0; - dbg(1, "Opening port %s...\n", fname); - if ( (fd = gbser_init(port)) == NULL ) { - fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", port, strerror(errno)); - } - - // verify that we have a MTK based logger... - dbg(1, "Verifying MTK based device...\n"); - - switch ( mtk_device ){ - case HOLUX_M241: - case HOLUX_GR245: - log_type[LATITUDE].size = log_type[LONGITUDE].size = 4; - log_type[HEIGHT].size = 3; - rc = gbser_set_port(fd, MTK_BAUDRATE_M241, 8, 0, 1); - break; - case MTK_LOGGER: - default: - rc = gbser_set_port(fd, MTK_BAUDRATE, 8, 0, 1); - break; - } - if (rc) { - dbg(1, "Set baud rate to %d failed (%d)\n", MTK_BAUDRATE, rc); - fatal(MYNAME ": Failed to set baudrate !\n"); - } +static void mtk_rd_init(const char *fname) +{ + int rc; + char *model; - rc = do_cmd("$PMTK605*31\r\n", "PMTK705,", &model, 10); - if ( rc != 0 ) - fatal(MYNAME ": This is not a MTK based GPS ! (or is device turned off ?)\n"); - - // say hello to GR245 to make it display "USB PROCESSING" - if (strstr(model, "GR-245")) { - holux245_init(); // remember we have a GR245 for mtk_rd_deinit() - rc |= do_cmd("$PHLX810*35\r\n", "PHLX852,", NULL, 10); - rc |= do_cmd("$PHLX826*30\r\n", "PHLX859*38", NULL, 10); - if (rc != 0) - dbg(2, "Greeting not successfull.\n"); + port = xstrdup(fname); + + errno = 0; + dbg(1, "Opening port %s...\n", fname); + if ((fd = gbser_init(port)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\" (%s)\n", port, strerror(errno)); + } + + // verify that we have a MTK based logger... + dbg(1, "Verifying MTK based device...\n"); + + switch (mtk_device) { + case HOLUX_M241: + case HOLUX_GR245: + log_type[LATITUDE].size = log_type[LONGITUDE].size = 4; + log_type[HEIGHT].size = 3; + rc = gbser_set_port(fd, MTK_BAUDRATE_M241, 8, 0, 1); + break; + case MTK_LOGGER: + default: + rc = gbser_set_port(fd, MTK_BAUDRATE, 8, 0, 1); + break; + } + if (rc) { + dbg(1, "Set baud rate to %d failed (%d)\n", MTK_BAUDRATE, rc); + fatal(MYNAME ": Failed to set baudrate !\n"); + } + + rc = do_cmd("$PMTK605*31\r\n", "PMTK705,", &model, 10); + if (rc != 0) { + fatal(MYNAME ": This is not a MTK based GPS ! (or is device turned off ?)\n"); + } + + // say hello to GR245 to make it display "USB PROCESSING" + if (strstr(model, "GR-245")) { + holux245_init(); // remember we have a GR245 for mtk_rd_deinit() + rc |= do_cmd("$PHLX810*35\r\n", "PHLX852,", NULL, 10); + rc |= do_cmd("$PHLX826*30\r\n", "PHLX859*38", NULL, 10); + if (rc != 0) { + dbg(2, "Greeting not successfull.\n"); } - xfree(model); - } - -static void mtk_rd_deinit(void){ - if (mtk_device == HOLUX_GR245) { - int rc = do_cmd("$PHLX827*31\r\n", "PHLX860*32", NULL, 10); - if (rc != 0) - dbg(2, "Goodbye not successfull.\n"); + } + xfree(model); +} + +static void mtk_rd_deinit(void) +{ + if (mtk_device == HOLUX_GR245) { + int rc = do_cmd("$PHLX827*31\r\n", "PHLX860*32", NULL, 10); + if (rc != 0) { + dbg(2, "Goodbye not successfull.\n"); } + } - dbg(3, "Closing port...\n"); - gbser_deinit(fd); - fd = NULL; - xfree(port); + dbg(3, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); } -static int mtk_erase(void){ - int log_status, log_mask, err; - char *lstatus = NULL; - +static int mtk_erase(void) +{ + int log_status, log_mask, err; + char *lstatus = NULL; + log_status = 0; // check log status - is logging disabled ? do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &lstatus, 2); - if ( lstatus ){ - log_status = atoi(lstatus); - dbg(3, "LOG Status '%s'\n", lstatus); - xfree(lstatus); - lstatus = NULL; - } + if (lstatus) { + log_status = atoi(lstatus); + dbg(3, "LOG Status '%s'\n", lstatus); + xfree(lstatus); + lstatus = NULL; + } do_cmd(CMD_LOG_FORMAT, "PMTK182,3,2,", &lstatus, 2); - if ( lstatus ){ - log_mask = strtoul(lstatus, NULL, 16); - dbg(3, "LOG Mask '%s' - 0x%.8x \n", lstatus, log_mask); - xfree(lstatus); - lstatus = NULL; - } - - dbg(1, "Start flash erase..\n"); - do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 1); - gb_sleep(10*1000); - - // Erase log.... - do_cmd(CMD_LOG_ERASE, "PMTK001,182,6", NULL, 30); - gb_sleep(100*1000); - - if ( (log_status & 2) ){ // auto-log were enabled before..re-enable log. - err = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); - dbg(3, "re-enable log %s\n", err==0?"Success":"Fail"); - } - return 0; + if (lstatus) { + log_mask = strtoul(lstatus, NULL, 16); + dbg(3, "LOG Mask '%s' - 0x%.8x \n", lstatus, log_mask); + xfree(lstatus); + lstatus = NULL; + } + + dbg(1, "Start flash erase..\n"); + do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 1); + gb_sleep(10*1000); + + // Erase log.... + do_cmd(CMD_LOG_ERASE, "PMTK001,182,6", NULL, 30); + gb_sleep(100*1000); + + if ((log_status & 2)) { // auto-log were enabled before..re-enable log. + err = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); + dbg(3, "re-enable log %s\n", err==0?"Success":"Fail"); + } + return 0; } -static void mtk_read(void){ +static void mtk_read(void) +{ char cmd[256]; char *line = NULL; unsigned char crc, *data = NULL; @@ -488,73 +516,74 @@ static void mtk_read(void){ char *fusage = NULL; - if ( *OPT_erase_only != '0' ) { - mtk_erase(); - return; - } + if (*OPT_erase_only != '0') { + mtk_erase(); + return; + } log_enabled = 0; init_scan = 0; dout = fopen(TEMP_DATA_BIN, "r+b"); - if ( dout == NULL ){ - dout = fopen(TEMP_DATA_BIN, "wb"); - if ( dout == NULL ){ - fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); - return; - } + if (dout == NULL) { + dout = fopen(TEMP_DATA_BIN, "wb"); + if (dout == NULL) { + fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); + return; + } } fseek(dout, 0L,SEEK_END); dsize = ftell(dout); - if ( dsize > 1024 ){ - dbg(1, "Temp %s file exists. with size %d\n", TEMP_DATA_BIN, dsize); - dpos = 0; - init_scan = 1; + if (dsize > 1024) { + dbg(1, "Temp %s file exists. with size %d\n", TEMP_DATA_BIN, dsize); + dpos = 0; + init_scan = 1; } dbg(1, "Download %s -> %s\n", port, TEMP_DATA_BIN); // check log status - is logging disabled ? do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &fusage, 2); - if ( fusage ){ - log_enabled = (atoi(fusage) & 2)?1:0; - dbg(3, "LOG Status '%s' -- log %s \n", fusage, log_enabled?"enabled":"disabled"); - xfree(fusage); - fusage = NULL; - } - - gb_sleep(10*1000); - if ( 1 || log_enabled ){ - i = do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 2); - dbg(3, " ---- LOG DISABLE ---- %s\n", i==0?"Success":"Fail"); - } - gb_sleep(100*1000); - + if (fusage) { + log_enabled = (atoi(fusage) & 2)?1:0; + dbg(3, "LOG Status '%s' -- log %s \n", fusage, log_enabled?"enabled":"disabled"); + xfree(fusage); + fusage = NULL; + } + + gb_sleep(10*1000); + if (1 || log_enabled) { + i = do_cmd(CMD_LOG_DISABLE, "PMTK001,182,5,3", NULL, 2); + dbg(3, " ---- LOG DISABLE ---- %s\n", i==0?"Success":"Fail"); + } + gb_sleep(100*1000); + addr_max = 0; // get flash usage, current log address..cmd only works if log disabled. - do_cmd("$PMTK182,2,8*33\r\n", "PMTK182,3,8,", &fusage, 2); - if ( fusage ){ - addr_max = strtoul(fusage, NULL, 16); - if ( addr_max > 0 ) - addr_max = addr_max - addr_max%65536 + 65535; - xfree(fusage); - } - - if ( addr_max == 0 ) { // get flash usage failed... - addr_max = 0x200000; // 16Mbit/2Mbyte/32x64kByte block. -- fixme Q1000-ng has 32Mbit + do_cmd("$PMTK182,2,8*33\r\n", "PMTK182,3,8,", &fusage, 2); + if (fusage) { + addr_max = strtoul(fusage, NULL, 16); + if (addr_max > 0) { + addr_max = addr_max - addr_max%65536 + 65535; + } + xfree(fusage); + } + + if (addr_max == 0) { // get flash usage failed... + addr_max = 0x200000; // 16Mbit/2Mbyte/32x64kByte block. -- fixme Q1000-ng has 32Mbit init_scan = 1; } dbg(1, "Download %dkB from device\n", (addr_max+1) >> 10); - if ( dsize > addr_max ){ - dbg(1, "Temp %s file (%ld) is larger than data size %d. Data erased since last download !\n", TEMP_DATA_BIN, dsize, addr_max); - fclose(dout); - dsize = 0; - init_scan = 0; - rename(TEMP_DATA_BIN, TEMP_DATA_BIN_OLD); - dout = fopen(TEMP_DATA_BIN, "wb"); - if ( dout == NULL ){ - fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); - return; - } + if (dsize > addr_max) { + dbg(1, "Temp %s file (%ld) is larger than data size %d. Data erased since last download !\n", TEMP_DATA_BIN, dsize, addr_max); + fclose(dout); + dsize = 0; + init_scan = 0; + rename(TEMP_DATA_BIN, TEMP_DATA_BIN_OLD); + dout = fopen(TEMP_DATA_BIN, "wb"); + if (dout == NULL) { + fatal(MYNAME ": Can't create temporary file %s", TEMP_DATA_BIN); + return; + } } bsize = 0x0400; @@ -562,901 +591,992 @@ static void mtk_read(void){ line_size = 2*bsize + 32; // logdata as nmea/hex. data_size = bsize + 32; - if ( (line = xmalloc(line_size)) == NULL){ - fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size); + if ((line = xmalloc(line_size)) == NULL) { + fatal(MYNAME ": Can't allocate %u bytes for NMEA buffer\n", line_size); } - if ( (data = xmalloc(data_size)) == NULL ){ - fatal(MYNAME ": Can't allocate %u bytes for data buffer\n", data_size); + if ((data = xmalloc(data_size)) == NULL) { + fatal(MYNAME ": Can't allocate %u bytes for data buffer\n", data_size); } memset(line, '\0', line_size); memset(data, '\0', data_size); retry_cnt = 0; - - while ( init_scan || addr < addr_max ) { - // generate - read address NMEA command, add crc. - crc = 0; - cmdLen = snprintf(cmd, sizeof(cmd), "$PMTK182,7,%.8x,%.8x", addr, bsize); - for (i=1;i 0 ) { - line[len] = '\0'; - if ( strncmp(line, "$PMTK182,8", 10) == 0 ){// $PMTK182,8,00005000,FFFFFFF - retry_cnt = 0; - data_addr = strtoul(&line[11], NULL, 16); - fseek(dout, data_addr, SEEK_SET); - i = 20; - j = 0; - ff_len = 0; // number of 0xff bytes. - null_len = 0; // number of 0x00 bytes. - while ( i < (len-3) ){ - data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 + - (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA)); - if ( data[j] == 0xff ) - ff_len++; - if ( data[j] == 0x00 ) - null_len++; - i += 2; - j++; - } - if ( init_scan ){ - if ( dsize > 0 && addr < dsize ){ - fseek(dout, addr, SEEK_SET); - if ( fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0 ){ - dpos = addr; - dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr); - } else { - dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr); - } - } - if ( ff_len == j ){ // data in sector - we've found max sector.. - addr_max = addr; - dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10); - } - len = 0; - } else { - if ( null_len == j ){ // 0x00 block - bad block.... - fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line); - } - if ( fwrite(data, 1, j, dout) != j ) - fatal(MYNAME ": Failed to write temp. binary file\n"); - if ( ff_len == j ){ // 0xff block - read complete... - len = ff_len; - addr_max = addr; - break; - } else { - len = 0; - } - } - } else if ( strncmp(line, "$PMTK001,182,7,", 15) == 0 ){ // Command ACK - if ( line[15] != '3' ) { - // fixme - we should timeout here when no log data has been received... - dbg(2, "\nLog req. failed (%c)\n", line[15]); - gb_sleep(10*1000); - retry_cnt++; - goto mtk_retry; - } + while (init_scan || addr < addr_max) { + // generate - read address NMEA command, add crc. + crc = 0; + cmdLen = snprintf(cmd, sizeof(cmd), "$PMTK182,7,%.8x,%.8x", addr, bsize); + for (i=1; i 0) { + line[len] = '\0'; + if (strncmp(line, "$PMTK182,8", 10) == 0) { // $PMTK182,8,00005000,FFFFFFF + retry_cnt = 0; + data_addr = strtoul(&line[11], NULL, 16); + fseek(dout, data_addr, SEEK_SET); + i = 20; + j = 0; + ff_len = 0; // number of 0xff bytes. + null_len = 0; // number of 0x00 bytes. + while (i < (len-3)) { + data[j] = (isdigit(line[i])?(line[i]-'0'):(line[i]-'A'+0xA))*0x10 + + (isdigit(line[i+1])?(line[i+1]-'0'):(line[i+1]-'A'+0xA)); + if (data[j] == 0xff) { + ff_len++; } - } - } while ( len != 0 ); - if ( init_scan ){ - addr += 0x10000; - if ( addr >= addr_max ){ // initial scan complete... - init_scan = 0; - addr = dpos; - } - } else { - addr += bsize; - if ( global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5) ){ - int perc; - perc = 100 - 100*(addr_max-addr)/addr_max; - if ( addr >= addr_max ) - perc = 100; - fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bReading 0x%.6x %3d %%", addr, perc); - } + if (data[j] == 0x00) { + null_len++; + } + i += 2; + j++; + } + if (init_scan) { + if (dsize > 0 && addr < dsize) { + fseek(dout, addr, SEEK_SET); + if (fread(line, 1, bsize, dout) == bsize && memcmp(line, data, bsize) == 0) { + dpos = addr; + dbg(2, "%s same at %d\n", TEMP_DATA_BIN, addr); + } else { + dbg(2, "%s differs at %d\n", TEMP_DATA_BIN, addr); + } + } + if (ff_len == j) { // data in sector - we've found max sector.. + addr_max = addr; + dbg(1, "Initial scan done - Download %dkB from device\n", (addr_max+1) >> 10); + } + len = 0; + } else { + if (null_len == j) { // 0x00 block - bad block.... + fprintf(stderr, "FIXME -- read bad block at 0x%.6x - retry ? skip ?\n%s\n", data_addr, line); + } + if (fwrite(data, 1, j, dout) != j) { + fatal(MYNAME ": Failed to write temp. binary file\n"); + } + if (ff_len == j) { // 0xff block - read complete... + len = ff_len; + addr_max = addr; + break; + } else { + len = 0; + } + } + } else if (strncmp(line, "$PMTK001,182,7,", 15) == 0) { // Command ACK + if (line[15] != '3') { + // fixme - we should timeout here when no log data has been received... + dbg(2, "\nLog req. failed (%c)\n", line[15]); + gb_sleep(10*1000); + retry_cnt++; + goto mtk_retry; + } + } + } + } while (len != 0); + if (init_scan) { + addr += 0x10000; + if (addr >= addr_max) { // initial scan complete... + init_scan = 0; + addr = dpos; + } + } else { + addr += bsize; + if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) { + int perc; + perc = 100 - 100*(addr_max-addr)/addr_max; + if (addr >= addr_max) { + perc = 100; + } + fprintf(stderr, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bReading 0x%.6x %3d %%", addr, perc); } + } + } + if (dout != NULL) { + fclose(dout); + } + if (global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5)) { + fprintf(stderr,"\n"); } - if ( dout != NULL ) - fclose(dout); - if ( global_opts.verbose_status || (global_opts.debug_level >= 2 && global_opts.debug_level < 5) ) - fprintf(stderr,"\n"); // Fixme - Order or. Enable - parse - erase ?? - if ( log_enabled || *OPT_log_enable=='1' ){ - i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); - dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail"); + if (log_enabled || *OPT_log_enable=='1') { + i = do_cmd(CMD_LOG_ENABLE, "PMTK001,182,4,3", NULL, 2); + dbg(3, " ---- LOG ENABLE ----%s\n", i==0?"Success":"Fail"); } else { - dbg(1, "Note !!! -- Logging is DISABLED !\n"); + dbg(1, "Note !!! -- Logging is DISABLED !\n"); } - if ( line != NULL ) - xfree(line); - if ( data != NULL ) - xfree(data); - + if (line != NULL) { + xfree(line); + } + if (data != NULL) { + xfree(data); + } + file_init(TEMP_DATA_BIN); file_read(); - file_deinit(); - - /* fixme -- we're assuming all went well - erase flash.... */ - if ( *OPT_erase != '0' ) { - mtk_erase(); - } - - return; + file_deinit(); + + /* fixme -- we're assuming all went well - erase flash.... */ + if (*OPT_erase != '0') { + mtk_erase(); + } + + return; } static route_head *trk_head = NULL; -static int add_trackpoint(int idx, unsigned long bmask, struct data_item *itm){ - char wp_name[20]; - waypoint *trk = waypt_new(); - - if ( global_opts.masked_objective & TRKDATAMASK && (trk_head == NULL || (mtk_info.track_event & MTK_EVT_START) ) ){ - char spds[50]; - trk_head = route_head_alloc(); - xasprintf(&trk_head->rte_name, "track-%d", 1+track_count() ); - - spds[0] = '\0'; - if ( mtk_info.speed > 0 ) - sprintf(spds, " when moving above %.0f km/h", mtk_info.speed/10.); - xasprintf(&trk_head->rte_desc, "Log every %.0f sec, %.0f m%s" - , mtk_info.period/10., mtk_info.distance/10., spds); - track_add_head(trk_head); +static int add_trackpoint(int idx, unsigned long bmask, struct data_item *itm) +{ + char wp_name[20]; + waypoint *trk = waypt_new(); + + if (global_opts.masked_objective & TRKDATAMASK && (trk_head == NULL || (mtk_info.track_event & MTK_EVT_START))) { + char spds[50]; + trk_head = route_head_alloc(); + xasprintf(&trk_head->rte_name, "track-%d", 1+track_count()); + + spds[0] = '\0'; + if (mtk_info.speed > 0) { + sprintf(spds, " when moving above %.0f km/h", mtk_info.speed/10.); } + xasprintf(&trk_head->rte_desc, "Log every %.0f sec, %.0f m%s" + , mtk_info.period/10., mtk_info.distance/10., spds); + track_add_head(trk_head); + } - if ( bmask & (1<latitude = itm->lat; - trk->longitude = itm->lon; - } else { - return -1; // GPX requires lat/lon... - } + if (bmask & (1<latitude = itm->lat; + trk->longitude = itm->lon; + } else { + return -1; // GPX requires lat/lon... + } - if ( bmask & (1<altitude = itm->height; - } - trk->creation_time = itm->timestamp; // in UTC.. - if ( bmask & (1<microseconds = MILLI_TO_MICRO(itm->timestamp_ms); - - if ( bmask & (1<pdop = itm->pdop; - if ( bmask & (1<hdop = itm->hdop; - if ( bmask & (1<vdop = itm->vdop; - - if ( bmask & (1<heading); - } - if ( bmask & (1<speed)); - } - if ( bmask & (1<valid){ - case 0x0040: trk->fix = fix_unknown;break; /* Estimated mode */ - case 0x0001: trk->fix = fix_none; break; /* "No Fix" */ - case 0x0002: trk->fix = fix_3d; break; /* "SPS" - 2d/3d ?*/ - case 0x0004: trk->fix = fix_dgps; break; - case 0x0008: trk->fix = fix_pps; break; /* Military GPS */ - - case 0x0010: /* "RTK" */ - case 0x0020: /* "FRTK" */ - case 0x0080: /* "Manual input mode" */ - case 0x0100: /* "Simulator";*/ - default: - trk->fix = fix_unknown; - break; - } - /* This is a flagrantly bogus position; don't queue it. - * The 747 does log some "real" positions with fix_none, though, - * so keep those. - */ - if ((trk->fix == fix_unknown || trk->fix == fix_none) && - trk->latitude - 90.0 < .000001 && trk->longitude < 0.000001) { - waypt_free(trk); - return -1; - } + if (bmask & (1<altitude = itm->height; + } + trk->creation_time = itm->timestamp; // in UTC.. + if (bmask & (1<microseconds = MILLI_TO_MICRO(itm->timestamp_ms); + } + + if (bmask & (1<pdop = itm->pdop; + } + if (bmask & (1<hdop = itm->hdop; + } + if (bmask & (1<vdop = itm->vdop; + } + + if (bmask & (1<heading); + } + if (bmask & (1<speed)); + } + if (bmask & (1<valid) { + case 0x0040: + trk->fix = fix_unknown; + break; /* Estimated mode */ + case 0x0001: + trk->fix = fix_none; + break; /* "No Fix" */ + case 0x0002: + trk->fix = fix_3d; + break; /* "SPS" - 2d/3d ?*/ + case 0x0004: + trk->fix = fix_dgps; + break; + case 0x0008: + trk->fix = fix_pps; + break; /* Military GPS */ + + case 0x0010: /* "RTK" */ + case 0x0020: /* "FRTK" */ + case 0x0080: /* "Manual input mode" */ + case 0x0100: /* "Simulator";*/ + default: + trk->fix = fix_unknown; + break; } - if ( bmask & (1<sat = itm->sat_used; - - // RCR is a bitmask of possibly several log reasons.. - // Holux devics use a Event prefix for each waypt. - if ( global_opts.masked_objective & WPTDATAMASK - && ( (bmask & (1<rcr & 0x0008) - || (mtk_info.track_event & MTK_EVT_WAYPT) - ) - ) - { - /* Button press -- create waypoint, start count at 1 */ - waypoint *w = waypt_dupe(trk); - - sprintf(wp_name, "WP%06d", waypt_count()+1); - w->shortname = xstrdup(wp_name); - waypt_add(w); + /* This is a flagrantly bogus position; don't queue it. + * The 747 does log some "real" positions with fix_none, though, + * so keep those. + */ + if ((trk->fix == fix_unknown || trk->fix == fix_none) && + trk->latitude - 90.0 < .000001 && trk->longitude < 0.000001) { + waypt_free(trk); + return -1; } - // In theory we would not add the waypoint to the list of - // trackpoints. But as the MTK logger restart the - // log session from the button press we would loose a - // trackpoint unless we include/duplicate it. + } + if (bmask & (1<sat = itm->sat_used; + } - if ( global_opts.masked_objective & TRKDATAMASK ){ - sprintf(wp_name, "TP%06d", idx); - trk->shortname = xstrdup(wp_name); + // RCR is a bitmask of possibly several log reasons.. + // Holux devics use a Event prefix for each waypt. + if (global_opts.masked_objective & WPTDATAMASK + && ((bmask & (1<rcr & 0x0008) + || (mtk_info.track_event & MTK_EVT_WAYPT) + ) + ) { + /* Button press -- create waypoint, start count at 1 */ + waypoint *w = waypt_dupe(trk); + + sprintf(wp_name, "WP%06d", waypt_count()+1); + w->shortname = xstrdup(wp_name); + waypt_add(w); + } + // In theory we would not add the waypoint to the list of + // trackpoints. But as the MTK logger restart the + // log session from the button press we would loose a + // trackpoint unless we include/duplicate it. - track_add_wpt(trk_head, trk); - } - return 0; + if (global_opts.masked_objective & TRKDATAMASK) { + sprintf(wp_name, "TP%06d", idx); + trk->shortname = xstrdup(wp_name); + + track_add_wpt(trk_head, trk); + } + return 0; } /********************** MTK Logger -- CSV output *************************/ static gbfile *cd; -static void mtk_csv_init(char *csv_fname, unsigned long bitmask){ - int i; - FILE *cf; - - dbg(1, "Opening csv output file %s...\n", csv_fname); - - // can't use gbfopen here - it will fatal() if file doesn't exist - if ( (cf = fopen(csv_fname, "r")) != NULL ) { - fclose(cf); - warning(MYNAME ": CSV file %s already exist ! Cowardly refusing to overwrite.\n", csv_fname); - return; +static void mtk_csv_init(char *csv_fname, unsigned long bitmask) +{ + int i; + FILE *cf; + + dbg(1, "Opening csv output file %s...\n", csv_fname); + + // can't use gbfopen here - it will fatal() if file doesn't exist + if ((cf = fopen(csv_fname, "r")) != NULL) { + fclose(cf); + warning(MYNAME ": CSV file %s already exist ! Cowardly refusing to overwrite.\n", csv_fname); + return; + } + + if ((cd = gbfopen(csv_fname, "w", MYNAME)) == NULL) { + fatal(MYNAME ": Can't open csv file '%s'\n", csv_fname); + } + + /* Add the header line */ + gbfprintf(cd, "INDEX,%s%s", ((1<timestamp)); - strftime(ts_str, sizeof(ts_str)-1, "%Y/%m/%d,%H:%M:%S", ts_tm); - - if ( bmask & (1<valid){ - case 0x0001: fix_str = "No fix"; break; - case 0x0002: fix_str = "SPS"; break; - case 0x0004: fix_str = "DGPS"; break; - case 0x0008: fix_str = "PPS"; break; /* Military GPS */ - case 0x0010: fix_str = "RTK"; break; /* RealTime Kinematic */ - case 0x0020: fix_str = "FRTK"; break; - case 0x0040: fix_str = "Estimated mode"; break; - case 0x0080: fix_str = "Manual input mode"; break; - case 0x0100: fix_str = "Simulator"; break; - default: fix_str = "???"; break; - } - } - gbfprintf(csvFile, "%d,", idx); - - // RCR is a bitmask of possibly several log reasons.. - if ( bmask & (1<rcr&0x0001?"T":"",itm->rcr&0x0002?"S":"" - , itm->rcr&0x0004?"D":"",itm->rcr&0x0008?"B":""); - - if ( bmask & (1<timestamp_ms:0); - - if ( bmask & (1<lat), itm->lat>0?'N':'S', - fabs(itm->lon), itm->lon>0?'E':'W'); - - if ( bmask & (1<height); - - if ( bmask & (1<speed); - - if ( bmask & (1<heading); - - if ( bmask & (1<dsta); - if ( bmask & (1<dage); - - if ( bmask & (1<pdop); - if ( bmask & (1<hdop); // note bug in MTK appl. 1.02 is output as 1.2 ! - if ( bmask & (1<vdop); - if ( bmask & (1<sat_used, itm->sat_view); - - if ( bmask & (1<sat_count;l++){ - slen = 0; - slen += sprintf(&sstr[slen], "%s%.2d" - , itm->sat_data[l].used?"#":"" - , itm->sat_data[l].id); - if ( bmask & (1<sat_data[l].elevation); - if ( bmask & (1<sat_data[l].azimut); - if ( bmask & (1<sat_data[l].snr); - - gbfprintf(csvFile, "%s%s" , do_sc?";":"", sstr); - do_sc = 1; +static int csv_line(gbfile *csvFile, int idx, unsigned long bmask, struct data_item *itm) +{ + struct tm *ts_tm; + char ts_str[30]; + const char *fix_str = ""; + + ts_tm = gmtime(&(itm->timestamp)); + strftime(ts_str, sizeof(ts_str)-1, "%Y/%m/%d,%H:%M:%S", ts_tm); + + if (bmask & (1<valid) { + case 0x0001: + fix_str = "No fix"; + break; + case 0x0002: + fix_str = "SPS"; + break; + case 0x0004: + fix_str = "DGPS"; + break; + case 0x0008: + fix_str = "PPS"; + break; /* Military GPS */ + case 0x0010: + fix_str = "RTK"; + break; /* RealTime Kinematic */ + case 0x0020: + fix_str = "FRTK"; + break; + case 0x0040: + fix_str = "Estimated mode"; + break; + case 0x0080: + fix_str = "Manual input mode"; + break; + case 0x0100: + fix_str = "Simulator"; + break; + default: + fix_str = "???"; + break; + } + } + gbfprintf(csvFile, "%d,", idx); + + // RCR is a bitmask of possibly several log reasons.. + if (bmask & (1<rcr&0x0001?"T":"",itm->rcr&0x0002?"S":"" + , itm->rcr&0x0004?"D":"",itm->rcr&0x0008?"B":""); + + if (bmask & (1<timestamp_ms:0); + } + + if (bmask & (1<lat), itm->lat>0?'N':'S', + fabs(itm->lon), itm->lon>0?'E':'W'); + + if (bmask & (1<height); + } + + if (bmask & (1<speed); + } + + if (bmask & (1<heading); + } + + if (bmask & (1<dsta); + } + if (bmask & (1<dage); + } + + if (bmask & (1<pdop); + } + if (bmask & (1<hdop); // note bug in MTK appl. 1.02 is output as 1.2 ! + } + if (bmask & (1<vdop); + } + if (bmask & (1<sat_used, itm->sat_view); + } + + if (bmask & (1<sat_count; l++) { + slen = 0; + slen += sprintf(&sstr[slen], "%s%.2d" + , itm->sat_data[l].used?"#":"" + , itm->sat_data[l].id); + if (bmask & (1<sat_data[l].elevation); } - gbfprintf(csvFile, ","); - } - - if ( bmask & (1<distance); - - gbfprintf(csvFile, "\n"); - return 0; + if (bmask & (1<sat_data[l].azimut); + } + if (bmask & (1<sat_data[l].snr); + } + + gbfprintf(csvFile, "%s%s" , do_sc?";":"", sstr); + do_sc = 1; + } + gbfprintf(csvFile, ","); + } + + if (bmask & (1<distance); + } + + gbfprintf(csvFile, "\n"); + return 0; } /********************* MTK Logger -- Parse functions *********************/ -int mtk_parse(unsigned char *data, int dataLen, unsigned int bmask){ - static int count = 0; - int i, k, sat_id, hspd; - unsigned char crc, hbuf[4]; - struct data_item itm; - - dbg(5,"Entering mtk_parse, count = %i, dataLen = %i\n", count, dataLen); - if ( global_opts.debug_level > 5 ) { - int j; - fprintf(stderr,"# Data block:"); - for(j=0;j 32 ) - sat_count = 32; // this can't happen ? or... - - itm.sat_count = sat_count; - sid_size = log_type[SID].size; - if ( sat_count > 0 ){ // handle 'Zero satellites in view issue' - if ( bmask & (1< 0 ){ - if ( bmask & (1< 0 ); - } - continue; // dont do any more checksum calc.. - break; - case 1< 5) { + int j; + fprintf(stderr,"# Data block:"); + for (j=0; j 32) { + sat_count = 32; // this can't happen ? or... + } + + itm.sat_count = sat_count; + sid_size = log_type[SID].size; + if (sat_count > 0) { // handle 'Zero satellites in view issue' + if (bmask & (1< 0) { + if (bmask & (1< 0); + } + continue; // dont do any more checksum calc.. + break; + case 1<= 16 - && memcmp(&data[0], &LOG_RST[0], 6) == 0 - && memcmp(&data[12], &LOG_RST[12], 4) == 0 ) - { - - cmd = le_read16(data + 8); - switch ( data[7] ){ - case 0x02: - bm = le_read32(data + 8); - dbg(1, "# Log bitmask is: %.8x\n", bm); - if ( mtk_device != MTK_LOGGER ) - bm &= 0x7fffffffU; - if ( mtk_device == HOLUX_GR245 ) - bm &= ~HOLUX245_MASK; - if ( mtk_info.bitmask != bm ){ - dbg(1," ########## Bitmask Change %.8x -> %.8x ###########\n", mtk_info.bitmask, bm); - mtk_info.track_event |= MTK_EVT_BITMASK; - } - mtk_info.bitmask = bm; - mtk_info.logLen = mtk_log_len(mtk_info.bitmask); - break; - case 0x03: - dbg(1, "# Log period change %.0f sec\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_PERIOD; - mtk_info.period = cmd; - break; - case 0x04: - dbg(1, "# Log distance change %.1f m\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_DISTANCE; - mtk_info.distance = cmd; - break; - case 0x05: - dbg(1, "# Log speed change %.1f km/h\n", cmd/10.); - mtk_info.track_event |= MTK_EVT_SPEED; - mtk_info.speed = cmd; - break; - case 0x06: - dbg(1, "# Log policy change 0x%.4x\n", cmd); - if ( cmd == 0x01 ) - dbg(1, "# Log policy change to OVERWRITE\n"); - if ( cmd == 0x02 ) - dbg(1, "# Log policy change to STOP\n"); - break; - case 0x07: - if ( cmd == 0x0106 ){ - dbg(5, "# GPS Logger# Turned On\n"); // Fixme - start new trk - mtk_info.track_event |= MTK_EVT_START; - } - if ( cmd == 0x0104 ) - dbg(5, "# GPS Logger# Log disabled\n"); - break; - default: - dbg(1, "## Unknown INFO 0x%.2x\n", data[7]); - break; +static int mtk_parse_info(const unsigned char *data, int dataLen) +{ + unsigned short cmd; + unsigned int bm; + + if (dataLen >= 16 + && memcmp(&data[0], &LOG_RST[0], 6) == 0 + && memcmp(&data[12], &LOG_RST[12], 4) == 0) { + + cmd = le_read16(data + 8); + switch (data[7]) { + case 0x02: + bm = le_read32(data + 8); + dbg(1, "# Log bitmask is: %.8x\n", bm); + if (mtk_device != MTK_LOGGER) { + bm &= 0x7fffffffU; } - } else { - if ( global_opts.debug_level > 0 ){ - fprintf(stderr,"#!! Invalid INFO block !! %d bytes\n >> ", dataLen); - for (bm=0;bm<16;bm++) fprintf(stderr, "%.2x ", data[bm]); - fprintf(stderr,"\n"); + if (mtk_device == HOLUX_GR245) { + bm &= ~HOLUX245_MASK; } - return 0; - } - return 16; + if (mtk_info.bitmask != bm) { + dbg(1," ########## Bitmask Change %.8x -> %.8x ###########\n", mtk_info.bitmask, bm); + mtk_info.track_event |= MTK_EVT_BITMASK; + } + mtk_info.bitmask = bm; + mtk_info.logLen = mtk_log_len(mtk_info.bitmask); + break; + case 0x03: + dbg(1, "# Log period change %.0f sec\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_PERIOD; + mtk_info.period = cmd; + break; + case 0x04: + dbg(1, "# Log distance change %.1f m\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_DISTANCE; + mtk_info.distance = cmd; + break; + case 0x05: + dbg(1, "# Log speed change %.1f km/h\n", cmd/10.); + mtk_info.track_event |= MTK_EVT_SPEED; + mtk_info.speed = cmd; + break; + case 0x06: + dbg(1, "# Log policy change 0x%.4x\n", cmd); + if (cmd == 0x01) { + dbg(1, "# Log policy change to OVERWRITE\n"); + } + if (cmd == 0x02) { + dbg(1, "# Log policy change to STOP\n"); + } + break; + case 0x07: + if (cmd == 0x0106) { + dbg(5, "# GPS Logger# Turned On\n"); // Fixme - start new trk + mtk_info.track_event |= MTK_EVT_START; + } + if (cmd == 0x0104) { + dbg(5, "# GPS Logger# Log disabled\n"); + } + break; + default: + dbg(1, "## Unknown INFO 0x%.2x\n", data[7]); + break; + } + } else { + if (global_opts.debug_level > 0) { + fprintf(stderr,"#!! Invalid INFO block !! %d bytes\n >> ", dataLen); + for (bm=0; bm<16; bm++) { + fprintf(stderr, "%.2x ", data[bm]); + } + fprintf(stderr,"\n"); + } + return 0; + } + return 16; } -static int mtk_log_len(unsigned int bitmask){ - int i, len; - - /* calculate the length of a binary log item. */ - switch ( mtk_device ){ - case HOLUX_M241: - case HOLUX_GR245: - len = 1; // add crc - break; - case MTK_LOGGER: - default: - len = 2; // add '*' + crc - break; - } - for (i=0;i<32;i++){ - if ( (1< DISTANCE && global_opts.debug_level > 0 ) - warning(MYNAME ": Unknown size/meaning of bit %d\n", i); - if ( (i == SID || i == ELEVATION || i == AZIMUTH || i == SNR) && (1< DISTANCE && global_opts.debug_level > 0) { + warning(MYNAME ": Unknown size/meaning of bit %d\n", i); + } + if ((i == SID || i == ELEVATION || i == AZIMUTH || i == SNR) && (1<= 5 && - data[0] == (0xff & 'H') && - data[1] == (0xff & 'O') && - data[2] == (0xff & 'L') && - data[3] == (0xff & 'U') && - data[4] == (0xff & 'X') ) { - return 1; - } - return 0; +static int is_holux_string(const unsigned char *data, int dataLen) +{ + if (mtk_device != MTK_LOGGER && + dataLen >= 5 && + data[0] == (0xff & 'H') && + data[1] == (0xff & 'O') && + data[2] == (0xff & 'L') && + data[3] == (0xff & 'U') && + data[4] == (0xff & 'X')) { + return 1; + } + return 0; } -static void file_read(void) { - long fsize, pos; - int i, j, k, bLen; - unsigned char buf[512]; - - memset(buf, '\0', sizeof(buf)); - - /* Get size of file to parse */ - fseek(fl, 0L, SEEK_END); - fsize = ftell(fl); - if ( fsize <= 0 ) - fatal(MYNAME ": File has size %ld\n", fsize); - - fseek(fl, 0L, SEEK_SET); - - /* Header: 20 bytes - 47 05 | 7f 1e 0e 00 | 04 01 | 32 00 00 00 e8 03 00 00 00 00 00 00 - - u16: Log count 'this 64kByte block' - ffff if not complete. - u32: Bitmask for logging. (default mask) - u16; ?? ?? Overwrite/Stop policy - u32: log period, sec*10 - u32: log distance , meters*10 - u32: log speed , km/h*10 - */ - - bLen = 0; - j = 0; - pos = 0; - - /* get default bitmask, log period/speed/distance */ - bLen = fread(buf, 1, 20, fl); - if ( bLen == 20 ){ - unsigned int mask, log_period, log_distance, log_speed, log_policy; +static void file_read(void) +{ + long fsize, pos; + int i, j, k, bLen; + unsigned char buf[512]; + + memset(buf, '\0', sizeof(buf)); + + /* Get size of file to parse */ + fseek(fl, 0L, SEEK_END); + fsize = ftell(fl); + if (fsize <= 0) { + fatal(MYNAME ": File has size %ld\n", fsize); + } + + fseek(fl, 0L, SEEK_SET); + + /* Header: 20 bytes + 47 05 | 7f 1e 0e 00 | 04 01 | 32 00 00 00 e8 03 00 00 00 00 00 00 + + u16: Log count 'this 64kByte block' - ffff if not complete. + u32: Bitmask for logging. (default mask) + u16; ?? ?? Overwrite/Stop policy + u32: log period, sec*10 + u32: log distance , meters*10 + u32: log speed , km/h*10 + */ + + bLen = 0; + j = 0; + pos = 0; + + /* get default bitmask, log period/speed/distance */ + bLen = fread(buf, 1, 20, fl); + if (bLen == 20) { + unsigned int mask, log_period, log_distance, log_speed, log_policy; + log_policy = le_read16(buf + 6); + + if (!(log_policy == 0x0104 || log_policy == 0x0106) && fsize > 0x10000) { + dbg(1, "Invalid initial log policy 0x%.4x - check next block\n", log_policy); + fseek(fl, 0x10000, SEEK_SET); + bLen = fread(buf, 1, 20, fl); log_policy = le_read16(buf + 6); + } + mask = le_read32(buf + 2); + if (mtk_device != MTK_LOGGER) { // clear Holux-specific 'low precision' bit + mask &= 0x7fffffffU; + } + log_period = le_read32(buf + 8); + log_distance = le_read32(buf + 12); + log_speed = le_read32(buf + 16); + + dbg(1, "Default Bitmask %.8x, Log every %.0f sec, %.0f m, %.0f km/h\n", + mask, log_period/10., log_distance/10., log_speed/10.); + mtk_info.bitmask = mask; + dbg(3, "Using initial bitmask %.8x for parsing the .bin file\n", mtk_info.bitmask); + + mtk_info.period = log_period; + mtk_info.distance = log_distance; + mtk_info.speed = log_speed; + } + mtk_info.track_event = 0; + + pos = 0x200; // skip header...first data position + fseek(fl, pos, SEEK_SET); + + /* read initial info blocks -- if any */ + do { + bLen = fread(buf, 1, 16, fl); + j = 0; + if (buf[0] == 0xaa) { // pre-validate to avoid error... + j = mtk_parse_info(buf, bLen); + pos += j; + } else if (is_holux_string(buf, bLen)) { + pos += j; + // Note -- Holux245 will have here...handled below.. + } + } while (j == 16); + j = bLen; + pos += j; + + mtk_info.logLen = mtk_log_len(mtk_info.bitmask); + dbg(3, "Log item size %d bytes\n", mtk_info.logLen); + if (csv_file && *csv_file) { + mtk_csv_init(csv_file, mtk_info.bitmask); + } - if ( !(log_policy == 0x0104 || log_policy == 0x0106) && fsize > 0x10000 ){ - dbg(1, "Invalid initial log policy 0x%.4x - check next block\n", log_policy); - fseek(fl, 0x10000, SEEK_SET); - bLen = fread(buf, 1, 20, fl); - log_policy = le_read16(buf + 6); - } - mask = le_read32(buf + 2); - if ( mtk_device != MTK_LOGGER ) { // clear Holux-specific 'low precision' bit - mask &= 0x7fffffffU; - } - log_period = le_read32(buf + 8); - log_distance = le_read32(buf + 12); - log_speed = le_read32(buf + 16); - - dbg(1, "Default Bitmask %.8x, Log every %.0f sec, %.0f m, %.0f km/h\n", - mask, log_period/10., log_distance/10., log_speed/10.); - mtk_info.bitmask = mask; - dbg(3, "Using initial bitmask %.8x for parsing the .bin file\n", mtk_info.bitmask); - - mtk_info.period = log_period; - mtk_info.distance = log_distance; - mtk_info.speed = log_speed; - } - mtk_info.track_event = 0; - - pos = 0x200; // skip header...first data position - fseek(fl, pos, SEEK_SET); - - /* read initial info blocks -- if any */ - do { - bLen = fread(buf, 1, 16, fl); - j = 0; - if ( buf[0] == 0xaa ){ // pre-validate to avoid error... - j = mtk_parse_info(buf, bLen); - pos += j; - } else if ( is_holux_string(buf, bLen) ) { - pos += j; - // Note -- Holux245 will have here...handled below.. - } - } while ( j == 16 ); - j = bLen; - pos += j; - - mtk_info.logLen = mtk_log_len(mtk_info.bitmask); - dbg(3, "Log item size %d bytes\n", mtk_info.logLen); - if ( csv_file && *csv_file ) - mtk_csv_init(csv_file, mtk_info.bitmask); - - while ( pos < fsize && (bLen = fread(&buf[j], 1, sizeof(buf)-j, fl)) > 0 ){ - bLen += j; - i = 0; - while ( (bLen - i) >= mtk_info.logLen ){ - k = 0; - if ( (bLen - i) >= 16 && memcmp(&buf[i], &LOG_RST[0], 6) == 0 - && memcmp(&buf[i+12], &LOG_RST[12], 4) == 0 ) - { - mtk_parse_info(&buf[i], (bLen-i)); - k = 16; - } else if ( is_holux_string(&buf[i], (bLen - i)) ) { - if ( memcmp(&buf[i+10], "WAYPNT", 6) == 0 ) - mtk_info.track_event |= MTK_EVT_WAYPT; - - k = 16; - // m241 - HOLUXGR241LOGGER or HOLUXGR241WAYPNT or HOLUXGR241LOGGER - // gr245 - HOLUXGR245LOGGER or HOLUXGR245WAYPNT - if (memcmp(&buf[i], "HOLUXGR245", 10) == 0) { - dbg(2, "Detected Holux GR245 !\n"); - holux245_init(); - } + while (pos < fsize && (bLen = fread(&buf[j], 1, sizeof(buf)-j, fl)) > 0) { + bLen += j; + i = 0; + while ((bLen - i) >= mtk_info.logLen) { + k = 0; + if ((bLen - i) >= 16 && memcmp(&buf[i], &LOG_RST[0], 6) == 0 + && memcmp(&buf[i+12], &LOG_RST[12], 4) == 0) { + mtk_parse_info(&buf[i], (bLen-i)); + k = 16; + } else if (is_holux_string(&buf[i], (bLen - i))) { + if (memcmp(&buf[i+10], "WAYPNT", 6) == 0) { + mtk_info.track_event |= MTK_EVT_WAYPT; + } - // skip the 4 spaces that may occur on every device - if ( memcmp(&buf[i+16], " ", 4) == 0 ){ // Assume loglen >= 20... - k += 4; - } - } else if ( buf[i] == 0xff && buf[i+1] == 0xff && buf[i+2] == 0xff && buf[i+3] == 0xff - /* && ((pos + 2*mtk_info.logLen) & 0xffff) < mtk_info.logLen */ ) - { - /* End of 64k block segment -- realign to next data area */ - - k = ((pos+mtk_info.logLen+1024)/0x10000) *0x10000 + 0x200; - i = sizeof(buf); - if ( k <= pos ) { - k += 0x10000; - } - dbg(3, "Jump %ld -> %d / 0x%.6x (fsize %ld) --- \n", pos, k, k, fsize); - if ( k > fsize ){ - dbg(3, "File parse complete !\n"); - pos = k; - break; - } else { - fseek(fl, k, SEEK_SET); - } - pos = k; - continue; - } else { - k = mtk_parse(&buf[i], mtk_info.logLen, mtk_info.bitmask); - } - - i += k; - pos += k; + k = 16; + // m241 - HOLUXGR241LOGGER or HOLUXGR241WAYPNT or HOLUXGR241LOGGER + // gr245 - HOLUXGR245LOGGER or HOLUXGR245WAYPNT + if (memcmp(&buf[i], "HOLUXGR245", 10) == 0) { + dbg(2, "Detected Holux GR245 !\n"); + holux245_init(); + } + + // skip the 4 spaces that may occur on every device + if (memcmp(&buf[i+16], " ", 4) == 0) { // Assume loglen >= 20... + k += 4; + } + } else if (buf[i] == 0xff && buf[i+1] == 0xff && buf[i+2] == 0xff && buf[i+3] == 0xff + /* && ((pos + 2*mtk_info.logLen) & 0xffff) < mtk_info.logLen */) { + /* End of 64k block segment -- realign to next data area */ + + k = ((pos+mtk_info.logLen+1024)/0x10000) *0x10000 + 0x200; + i = sizeof(buf); + if (k <= pos) { + k += 0x10000; + } + dbg(3, "Jump %ld -> %d / 0x%.6x (fsize %ld) --- \n", pos, k, k, fsize); + if (k > fsize) { + dbg(3, "File parse complete !\n"); + pos = k; + break; + } else { + fseek(fl, k, SEEK_SET); + } + pos = k; + continue; + } else { + k = mtk_parse(&buf[i], mtk_info.logLen, mtk_info.bitmask); } - memmove(buf, &buf[i], sizeof(buf)-i); - j = sizeof(buf)-i; - } - mtk_csv_deinit(); + + i += k; + pos += k; + } + memmove(buf, &buf[i], sizeof(buf)-i); + j = sizeof(buf)-i; + } + mtk_csv_deinit(); } @@ -1465,77 +1585,79 @@ static void file_read(void) { // GPS logger will only handle tracks - neither waypoints or tracks... ff_vecs_t mtk_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - mtk_rd_init, - NULL, - mtk_rd_deinit, - NULL, - mtk_read, - NULL, - NULL, - mtk_sargs, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_rd_init, + NULL, + mtk_rd_deinit, + NULL, + mtk_read, + NULL, + NULL, + mtk_sargs, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; ff_vecs_t mtk_m241_vecs = { - ff_type_serial, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - mtk_rd_init_m241, - NULL, - mtk_rd_deinit, - NULL, - mtk_read, - NULL, - NULL, - mtk_sargs, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_serial, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + mtk_rd_init_m241, + NULL, + mtk_rd_deinit, + NULL, + mtk_read, + NULL, + NULL, + mtk_sargs, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /* used for mtk-bin */ static arglist_t mtk_fargs[] = { - { "csv", &csv_file, "MTK compatible CSV output file", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "csv", &csv_file, "MTK compatible CSV output file", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t mtk_fvecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_none }, - file_init, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - mtk_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + mtk_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; ff_vecs_t mtk_m241_fvecs = { - ff_type_file, - { ff_cap_read, ff_cap_read, ff_cap_none }, - file_init_m241, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - mtk_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_read, ff_cap_none }, + file_init_m241, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + mtk_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; /* End file: mtk_logger.c */ /**************************************************************************/ diff --git a/gpsbabel/navicache.c b/gpsbabel/navicache.c index dfc39e9c6..5f398a018 100644 --- a/gpsbabel/navicache.c +++ b/gpsbabel/navicache.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2003 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -31,9 +31,11 @@ static char *noretired = NULL; static arglist_t nav_args[] = { - {"noretired", &noretired, "Suppress retired geocaches", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "noretired", &noretired, "Suppress retired geocaches", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define MYNAME "navicache" @@ -44,7 +46,7 @@ arglist_t nav_args[] = { static void nav_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded GPX support because expat was not installed.\n"); } static void @@ -54,160 +56,147 @@ nav_read(void) #else static struct -nc_type_mapping{ - geocache_type type; - const char *name; + nc_type_mapping { + geocache_type type; + const char *name; } nc_type_map[] = { - { gt_unknown, "unknown" }, - { gt_traditional, "normal" }, - { gt_multi, "Multi-part" }, - { gt_virtual, "Virtual" }, - { gt_event, "event" } + { gt_unknown, "unknown" }, + { gt_traditional, "normal" }, + { gt_multi, "Multi-part" }, + { gt_virtual, "Virtual" }, + { gt_event, "event" } }; static struct -nc_container_mapping{ - geocache_container type; - const char *name; + nc_container_mapping { + geocache_container type; + const char *name; } nc_container_map[] = { - { gc_other, "Unknown" }, - { gc_micro, "Micro" }, - { gc_regular, "Normal" }, - { gc_large, "Large" }, - { gc_virtual, "Virtual" } + { gc_other, "Unknown" }, + { gc_micro, "Micro" }, + { gc_regular, "Normal" }, + { gc_large, "Large" }, + { gc_virtual, "Virtual" } }; static geocache_type nc_mktype(const char *t) { - int i; - int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { - return nc_type_map[i].type; - } - } - return gt_unknown; + int i; + int sz = sizeof(nc_type_map) / sizeof(nc_type_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_type_map[i].name)) { + return nc_type_map[i].type; + } + } + return gt_unknown; } static geocache_container nc_mkcont(const char *t) { - int i; - int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); - - for (i = 0; i < sz; i++) { - if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { - return nc_container_map[i].type; - } - } - return gc_unknown; + int i; + int sz = sizeof(nc_container_map) / sizeof(nc_container_map[0]); + + for (i = 0; i < sz; i++) { + if (0 == case_ignore_strcmp(t, nc_container_map[i].name)) { + return nc_container_map[i].type; + } + } + return gc_unknown; } static void nav_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - const char *el; - const char **attr; - - el = xml_convert_to_char_string(xml_el); - attr = xml_convert_attrs_to_char_string(xml_attr); - if (0 == strcmp(el, "CacheDetails")) { - const char **ap; - geocache_data *gc_data; - wpt_tmp = waypt_new(); - gc_data = waypt_alloc_gc_data(wpt_tmp); - - for (ap = attr; *ap; ap+=2) { - if (0 == strcmp(ap[0], "cache_id")) { - int id; - - id = atoi(ap[1]); - xasprintf(&wpt_tmp->shortname, "N%05X", id); - xasprintf(&wpt_tmp->url, "%s%d", NC_URL, id); - } else - if (0 == strcmp(ap[0], "name")) { - wpt_tmp->description = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "user_name")) { - gc_data->placer = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "latitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->latitude); - } else - if (0 == strcmp(ap[0], "longitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->longitude); - } else - if (0 == strcmp(ap[0], "longitude")) { - sscanf(ap[1], "%lf", - &wpt_tmp->longitude); - } else - if (0 == strcmp(ap[0], "difficulty")) { - float x; - sscanf(ap[1], "%f", &x); - gc_data->diff = x * 10; - } else - if (0 == strcmp(ap[0], "terrain")) { - float x; - sscanf(ap[1], "%f", &x); - gc_data->terr = x * 10; - } else - if (0 == strcmp(ap[0], "cache_type")) { - gc_data->type = nc_mktype(ap[1]); - if (!strcmp(ap[1], "normal")) - wpt_tmp->icon_descr = "Geocache-regular"; - else if (!strcmp(ap[1], "multi-part")) - wpt_tmp->icon_descr = "Geocache-multi"; - else if (!strcmp(ap[1], "moving_travelling")) - wpt_tmp->icon_descr = "Geocache-moving"; - else { - xasprintf(&wpt_tmp->icon_descr, - "Geocache-%-.20s", ap[1]); - } - } else - if (0 == strcmp(ap[0], "hidden_date")) { - struct tm tm; - - sscanf(ap[1], "%d-%d-%d", - &tm.tm_year, - &tm.tm_mon, - &tm.tm_mday); - tm.tm_mon -= 1; - tm.tm_year -= 1900; - tm.tm_isdst = 0; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - wpt_tmp->creation_time = mktime(&tm); - } else - if (0 == strcmp(ap[0], "retired")) { - if (!strcmp(ap[1], "yes") && noretired) { - xfree(wpt_tmp); - return; - } - } else - if (0 == strcmp(ap[0], "cache_size")) { - gc_data->container = nc_mkcont(ap[1]); - } else - if (0 == strcmp(ap[0], "description")) { - gc_data->desc_long.is_html = 1; - gc_data->desc_long.utfstring = xstrdup(ap[1]); - } else - if (0 == strcmp(ap[0], "comments")) { - gc_data->desc_short.is_html = 1; - gc_data->desc_short.utfstring = xstrdup(ap[1]); - } - } - waypt_add(wpt_tmp); - } - - xml_free_converted_attrs(attr); - xml_free_converted_string(el); + const char *el; + const char **attr; + + el = xml_convert_to_char_string(xml_el); + attr = xml_convert_attrs_to_char_string(xml_attr); + if (0 == strcmp(el, "CacheDetails")) { + const char **ap; + geocache_data *gc_data; + wpt_tmp = waypt_new(); + gc_data = waypt_alloc_gc_data(wpt_tmp); + + for (ap = attr; *ap; ap+=2) { + if (0 == strcmp(ap[0], "cache_id")) { + int id; + + id = atoi(ap[1]); + xasprintf(&wpt_tmp->shortname, "N%05X", id); + xasprintf(&wpt_tmp->url, "%s%d", NC_URL, id); + } else if (0 == strcmp(ap[0], "name")) { + wpt_tmp->description = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "user_name")) { + gc_data->placer = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "latitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->latitude); + } else if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else if (0 == strcmp(ap[0], "longitude")) { + sscanf(ap[1], "%lf", + &wpt_tmp->longitude); + } else if (0 == strcmp(ap[0], "difficulty")) { + float x; + sscanf(ap[1], "%f", &x); + gc_data->diff = x * 10; + } else if (0 == strcmp(ap[0], "terrain")) { + float x; + sscanf(ap[1], "%f", &x); + gc_data->terr = x * 10; + } else if (0 == strcmp(ap[0], "cache_type")) { + gc_data->type = nc_mktype(ap[1]); + if (!strcmp(ap[1], "normal")) { + wpt_tmp->icon_descr = "Geocache-regular"; + } else if (!strcmp(ap[1], "multi-part")) { + wpt_tmp->icon_descr = "Geocache-multi"; + } else if (!strcmp(ap[1], "moving_travelling")) { + wpt_tmp->icon_descr = "Geocache-moving"; + } else { + xasprintf(&wpt_tmp->icon_descr, + "Geocache-%-.20s", ap[1]); + } + } else if (0 == strcmp(ap[0], "hidden_date")) { + struct tm tm; + + sscanf(ap[1], "%d-%d-%d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday); + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = 0; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + wpt_tmp->creation_time = mktime(&tm); + } else if (0 == strcmp(ap[0], "retired")) { + if (!strcmp(ap[1], "yes") && noretired) { + xfree(wpt_tmp); + return; + } + } else if (0 == strcmp(ap[0], "cache_size")) { + gc_data->container = nc_mkcont(ap[1]); + } else if (0 == strcmp(ap[0], "description")) { + gc_data->desc_long.is_html = 1; + gc_data->desc_long.utfstring = xstrdup(ap[1]); + } else if (0 == strcmp(ap[0], "comments")) { + gc_data->desc_short.is_html = 1; + gc_data->desc_short.utfstring = xstrdup(ap[1]); + } + } + waypt_add(wpt_tmp); + } + + xml_free_converted_attrs(attr); + xml_free_converted_string(el); } static void @@ -218,32 +207,32 @@ nav_end(void *data, const XML_Char *el) static void nav_rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); - psr = XML_ParserCreate(NULL); - if (!psr) { - fatal(MYNAME ":Cannot create XML parser\n"); - } + psr = XML_ParserCreate(NULL); + if (!psr) { + fatal(MYNAME ":Cannot create XML parser\n"); + } - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, nav_start, nav_end); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, nav_start, nav_end); } static void nav_read(void) { - int len; - char buf[MY_CBUF]; - - while ((len = gbfread(buf, 1, sizeof(buf), fin))) { - if (!XML_Parse(psr, buf, len, gbfeof(fin))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - } - - XML_ParserFree(psr); + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), fin))) { + if (!XML_Parse(psr, buf, len, gbfeof(fin))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + } + + XML_ParserFree(psr); } #endif @@ -251,20 +240,20 @@ nav_read(void) static void nav_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void nav_wr_init(const char *fname) { - fatal(MYNAME ": Does not support writing Navicache files.\n"); - fout = gbfopen(fname, "w", MYNAME); + fatal(MYNAME ": Does not support writing Navicache files.\n"); + fout = gbfopen(fname, "w", MYNAME); } static void nav_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void @@ -273,15 +262,15 @@ nav_write(void) } ff_vecs_t navicache_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_none }, - nav_rd_init, - nav_wr_init, - nav_rd_deinit, - nav_wr_deinit, - nav_read, - nav_write, - NULL, - nav_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + nav_rd_init, + nav_wr_init, + nav_rd_deinit, + nav_wr_deinit, + nav_read, + nav_write, + NULL, + nav_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/naviguide.c b/gpsbabel/naviguide.c index bdcb701ca..840a8ae02 100755 --- a/gpsbabel/naviguide.c +++ b/gpsbabel/naviguide.c @@ -1,6 +1,6 @@ /* Naviguide Routes - + Copyright (C) 2009 Erez Zuler @@ -24,7 +24,7 @@ #include "csv_util.h" #include "jeeps/gpsmath.h" #include -#include +#include #define MYNAME "Naviguide" @@ -37,33 +37,33 @@ /* Naviguide file header */ typedef struct { - gbuint16 nof_wp; /* Little endean format */ - char pad1[6]; /* 0xff, 0xff, 0x01, 0x00, 0x06, 0x00 */ - char signature[9]; /* cWaypoint */ - char pad2[4]; /* 0x01, 0x00, 0x00, 0x00 */ + gbuint16 nof_wp; /* Little endean format */ + char pad1[6]; /* 0xff, 0xff, 0x01, 0x00, 0x06, 0x00 */ + char signature[9]; /* cWaypoint */ + char pad2[4]; /* 0x01, 0x00, 0x00, 0x00 */ } ng_file_header_t; /* Naviguide waypoint/rout data */ -typedef struct{ - char pad1[8]; /* 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 */ - /* coordination are in old israeli grid */ - gbuint32 East; - gbuint32 North; - char pad2[2]; /* 0x01, 0x01 */ - gbuint32 Alt; - char CommentLength; +typedef struct { + char pad1[8]; /* 0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00 */ + /* coordination are in old israeli grid */ + gbuint32 East; + gbuint32 North; + char pad2[2]; /* 0x01, 0x01 */ + gbuint32 Alt; + char CommentLength; } ng_wp_data_t; -typedef struct{ - char pad1[2]; /* 0x01, 0x80 */ - gbuint16 next_wp; - char pad2[2]; /* 0x00, 0x00 */ +typedef struct { + char pad1[2]; /* 0x01, 0x80 */ + gbuint16 next_wp; + char pad2[2]; /* 0x00, 0x00 */ } ng_next_wp_t; typedef struct { - unsigned char chHeaderLen; - char strName[255]; - ng_wp_data_t wp_data; + unsigned char chHeaderLen; + char strName[255]; + ng_wp_data_t wp_data; } ng_wp_no_comment_t; @@ -96,12 +96,16 @@ static void ng_read_file_header(void); static arglist_t ng_args[] = { - {"output", &process, "'wp' - Create waypoint file , 'rte' - Create route file", - "rte", ARGTYPE_STRING, ARG_NOMINMAX}, - {"reorder", &reorder, "'n' - Keep the existing wp name, 'y' - rename waypoints", - "n", ARGTYPE_STRING, ARG_NOMINMAX}, - - ARG_TERMINATOR + { + "output", &process, "'wp' - Create waypoint file , 'rte' - Create route file", + "rte", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "reorder", &reorder, "'n' - Keep the existing wp name, 'y' - rename waypoints", + "n", ARGTYPE_STRING, ARG_NOMINMAX + }, + + ARG_TERMINATOR }; /*===================Utilities ==========================================*/ @@ -109,16 +113,16 @@ arglist_t ng_args[] = { static void ng_convert_datum(waypoint *wpt) { - double lat, lon, east, north, alt; - - east = (double) WPNC.wp_data.East; - north = (double) WPNC.wp_data.North; - alt = (double) WPNC.wp_data.Alt; - - GPS_Math_ICS_EN_To_WGS84(east, north, &lat, &lon); - wpt->latitude = lat; - wpt->longitude = lon; - wpt->altitude = alt; + double lat, lon, east, north, alt; + + east = (double) WPNC.wp_data.East; + north = (double) WPNC.wp_data.North; + alt = (double) WPNC.wp_data.Alt; + + GPS_Math_ICS_EN_To_WGS84(east, north, &lat, &lon); + wpt->latitude = lat; + wpt->longitude = lon; + wpt->altitude = alt; } @@ -126,184 +130,196 @@ ng_convert_datum(waypoint *wpt) /*=================== File read/write utilities ==========================================*/ static void -ng_fwrite_wp_data (char *s, char *d, ng_wp_data_t *wp_data, gbfile *f) { - int i; - char z[50]; - - memset (z, 0, 50); - - i = (s == NULL) ? 0 : strlen (s); - gbfwrite (&i, 1, 1, f); - gbfwrite (s, 1, i, f); - - gbfwrite (&wp_data->pad1[0], 8, 1, f); - gbfputint32 (wp_data->East, f); - gbfputint32 (wp_data->North, f); - gbfwrite (&wp_data->pad2[0], 2, 1, f); - gbfputint32 (wp_data->Alt, f); - - i = (d == NULL) ? 0 : strlen (d); - gbfwrite (&i, 1, 1, f); - gbfwrite (d, 1, i, f); - gbfwrite (z, 44, 1, f); +ng_fwrite_wp_data(char *s, char *d, ng_wp_data_t *wp_data, gbfile *f) +{ + int i; + char z[50]; + + memset(z, 0, 50); + + i = (s == NULL) ? 0 : strlen(s); + gbfwrite(&i, 1, 1, f); + gbfwrite(s, 1, i, f); + + gbfwrite(&wp_data->pad1[0], 8, 1, f); + gbfputint32(wp_data->East, f); + gbfputint32(wp_data->North, f); + gbfwrite(&wp_data->pad2[0], 2, 1, f); + gbfputint32(wp_data->Alt, f); + + i = (d == NULL) ? 0 : strlen(d); + gbfwrite(&i, 1, 1, f); + gbfwrite(d, 1, i, f); + gbfwrite(z, 44, 1, f); } static void -ng_fwrite_next_wp (ng_next_wp_t *nwp, gbfile *f) { - gbfwrite (nwp->pad1, 2, 1, f); - gbfputint16 (nwp->next_wp, f); - gbfwrite (nwp->pad2, 2, 1, f); +ng_fwrite_next_wp(ng_next_wp_t *nwp, gbfile *f) +{ + gbfwrite(nwp->pad1, 2, 1, f); + gbfputint16(nwp->next_wp, f); + gbfwrite(nwp->pad2, 2, 1, f); } static void -ng_fread_wp_data (char *d, ng_wp_no_comment_t *wpnc, gbfile *f) { +ng_fread_wp_data(char *d, ng_wp_no_comment_t *wpnc, gbfile *f) +{ + + int i; + + gbfread(&wpnc->chHeaderLen ,sizeof(wpnc->chHeaderLen), 1, f); + gbfread(&wpnc->strName, wpnc->chHeaderLen, 1, f); + wpnc->strName[wpnc->chHeaderLen] = 0; - int i; - - gbfread (&wpnc->chHeaderLen ,sizeof (wpnc->chHeaderLen), 1, f); - gbfread (&wpnc->strName, wpnc->chHeaderLen, 1, f); - wpnc->strName[wpnc->chHeaderLen] = 0; - - gbfread (&wpnc->wp_data, 8, 1, f); - wpnc->wp_data.East = gbfgetint32 (f); - wpnc->wp_data.North = gbfgetint32 (f); - gbfread (&wpnc->wp_data.pad2,2, 1, f); - wpnc->wp_data.Alt = gbfgetint32 (f); - gbfread (&wpnc->wp_data.CommentLength, 1, 1, f); - i = (int)wpnc->wp_data.CommentLength; + gbfread(&wpnc->wp_data, 8, 1, f); + wpnc->wp_data.East = gbfgetint32(f); + wpnc->wp_data.North = gbfgetint32(f); + gbfread(&wpnc->wp_data.pad2,2, 1, f); + wpnc->wp_data.Alt = gbfgetint32(f); + gbfread(&wpnc->wp_data.CommentLength, 1, 1, f); + i = (int)wpnc->wp_data.CommentLength; - /* Read the comment field */ - gbfread (d, i + 44, 1, f); + /* Read the comment field */ + gbfread(d, i + 44, 1, f); } static void -ng_fread_next_wp (ng_next_wp_t *nwp, gbfile *f) { - gbfread (&nwp->pad1, 2, 1, f); - nwp->next_wp = gbfgetint16 (f); - gbfread (&nwp->pad2, 2, 1, f); +ng_fread_next_wp(ng_next_wp_t *nwp, gbfile *f) +{ + gbfread(&nwp->pad1, 2, 1, f); + nwp->next_wp = gbfgetint16(f); + gbfread(&nwp->pad2, 2, 1, f); } /* =================== Write data functions ====================================*/ static void -ng_fill_header_default (void) { - ng_file_header_t default_header = { - 0x00, - {0xff, 0xff, 0x01, 0x00, 0x09, 0x00}, - {'C', 'W', 'a', 'y', 'P', 'o', 'i', 'n', 't'}, - {0x01, 0x00, 0x00, 0x00}, - }; - - ng_file_header =default_header; - +ng_fill_header_default(void) +{ + ng_file_header_t default_header = { + 0x00, + {0xff, 0xff, 0x01, 0x00, 0x09, 0x00}, + {'C', 'W', 'a', 'y', 'P', 'o', 'i', 'n', 't'}, + {0x01, 0x00, 0x00, 0x00}, + }; + + ng_file_header =default_header; + } static void -ng_fill_waypoint_default (void) { - ng_wp_data_t default_wp = { - {0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00}, - 0, - 0, - {0x01, 0x01}, - 0, - 0x00, - - }; - - ng_next_wp_t default_ng_next_wp = { - {0x01, 0x80}, - 0, - {0x00, 0x00}, - }; - - WPNC.wp_data = default_wp; - ng_next_wp = default_ng_next_wp; +ng_fill_waypoint_default(void) +{ + ng_wp_data_t default_wp = { + {0xfe, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00}, + 0, + 0, + {0x01, 0x01}, + 0, + 0x00, + + }; + + ng_next_wp_t default_ng_next_wp = { + {0x01, 0x80}, + 0, + {0x00, 0x00}, + }; + + WPNC.wp_data = default_wp; + ng_next_wp = default_ng_next_wp; } static void -ng_waypt_rd (const waypoint * wpt) { - char * s = NULL; - - char z[50]; - double lat, lon; - static int current_wp_ix=0; - - memset (z, 0, 50); - current_wp_ix++; - ng_fill_waypoint_default(); - - if (!GPS_Math_WGS84_To_ICS_EN(wpt->latitude, wpt->longitude, &lon, &lat)) { - fatal(MYNAME ": Waypoint %d is out of the israeli grid area", current_wp_ix); - } - - WPNC.wp_data.North = (gbuint32)lat; - WPNC.wp_data.East = (gbuint32)lon; - - if (reorder_wp) { - sprintf (temp_short_name, "A%03d", current_wp_ix); - s = temp_short_name; - } - - else - s = wpt->shortname; - - ng_fwrite_wp_data (s, wpt->description, &WPNC.wp_data, file_out); - - - /* if not Last WP, write the next one index */ - - if (nof_wp > current_wp_ix) { - ng_next_wp.next_wp = current_wp_ix + 1; - - ng_fwrite_next_wp (&ng_next_wp, file_out); - - } +ng_waypt_rd(const waypoint * wpt) +{ + char * s = NULL; + + char z[50]; + double lat, lon; + static int current_wp_ix=0; + + memset(z, 0, 50); + current_wp_ix++; + ng_fill_waypoint_default(); + + if (!GPS_Math_WGS84_To_ICS_EN(wpt->latitude, wpt->longitude, &lon, &lat)) { + fatal(MYNAME ": Waypoint %d is out of the israeli grid area", current_wp_ix); + } + + WPNC.wp_data.North = (gbuint32)lat; + WPNC.wp_data.East = (gbuint32)lon; + + if (reorder_wp) { + sprintf(temp_short_name, "A%03d", current_wp_ix); + s = temp_short_name; + } + + else { + s = wpt->shortname; + } + + ng_fwrite_wp_data(s, wpt->description, &WPNC.wp_data, file_out); + + + /* if not Last WP, write the next one index */ + + if (nof_wp > current_wp_ix) { + ng_next_wp.next_wp = current_wp_ix + 1; + + ng_fwrite_next_wp(&ng_next_wp, file_out); + + } } static void -header_write (void) { - ng_file_header.nof_wp = nof_wp; - gbfputint16 (nof_wp, file_out); - gbfwrite(&ng_file_header.pad1[0], 19, 1, file_out); +header_write(void) +{ + ng_file_header.nof_wp = nof_wp; + gbfputint16(nof_wp, file_out); + gbfwrite(&ng_file_header.pad1[0], 19, 1, file_out); } static void -data_write (void) { - nof_wp = waypt_count(); - if (nof_wp) { - header_write (); - waypt_disp_all(ng_waypt_rd); - } - else { - nof_wp = route_waypt_count(); - if (nof_wp) { - header_write (); - route_disp_all(NULL, NULL, ng_waypt_rd); - } - } -} +data_write(void) +{ + nof_wp = waypt_count(); + if (nof_wp) { + header_write(); + waypt_disp_all(ng_waypt_rd); + } else { + nof_wp = route_waypt_count(); + if (nof_wp) { + header_write(); + route_disp_all(NULL, NULL, ng_waypt_rd); + } + } +} static void -wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); - ng_fill_header_default (); - if (NULL != reorder) - if (!case_ignore_strcmp(reorder, "y")) {reorder_wp = 1;} +wr_init(const char *fname) +{ + file_out = gbfopen_le(fname, "wb", MYNAME); + ng_fill_header_default(); + if (NULL != reorder) + if (!case_ignore_strcmp(reorder, "y")) { + reorder_wp = 1; + } } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } /*=========================== Read data functions ==================================*/ @@ -311,23 +327,27 @@ wr_deinit(void) static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); + + ng_read_file_header(); - ng_read_file_header(); + if (NULL != process) { + if (!case_ignore_strcmp(process, "wp")) { + process_rte = 0; + } + if (!case_ignore_strcmp(process, "rte")) { + process_rte = 1; + } + } - if (NULL != process) { - if (!case_ignore_strcmp(process, "wp")) {process_rte = 0;} - if (!case_ignore_strcmp(process, "rte")) {process_rte = 1;} - } - } static void rd_deinit(void) { - gbfclose(file_in); - file_in = NULL; + gbfclose(file_in); + file_in = NULL; } @@ -335,81 +355,84 @@ rd_deinit(void) static void ng_read_file_header(void) { - - nof_wp = gbfgetint16 (file_in); - gbfread (&ng_file_header.pad1[0], 19, 1, file_in); - ng_file_header.nof_wp = nof_wp; - - - if (strncmp ("CWayPoint", ng_file_header.signature, 9)) - fatal ("\nInvalid Naviguide file format\n"); - - + + nof_wp = gbfgetint16(file_in); + gbfread(&ng_file_header.pad1[0], 19, 1, file_in); + ng_file_header.nof_wp = nof_wp; + + + if (strncmp("CWayPoint", ng_file_header.signature, 9)) { + fatal("\nInvalid Naviguide file format\n"); + } + + } static void data_read(void) { - int n; - unsigned i; - waypoint *wpt_tmp; - - if (process_rte) { - rte_head = route_head_alloc(); - rte_head->rte_waypt_ct = nof_wp; - route_add_head(rte_head); - } - - for (n = 0; n < nof_wp; ++n) { - - wpt_tmp = waypt_new (); - - /* Read waypoint data */ - - ng_fread_wp_data (strComment, &WPNC, file_in); - - - if (n < nof_wp - 1) { - /* - gbfread (&ng_next_wp.pad1[0], 2, 1, file_in); - ng_next_wp.next_wp = gbfgetint16 (file_in); - gbfread (&ng_next_wp.pad2[0], 2, 1, file_in); - */ - ng_fread_next_wp (&ng_next_wp, file_in); - - } - /* Clear commas form the comment for CSV file commonality */ - for (i = 0; i shortname = xstrdup (WPNC.strName); - wpt_tmp->description = xstrdup (strComment); - - if (process_rte) - route_add_wpt(rte_head, wpt_tmp); - else - waypt_add(wpt_tmp); - } + int n; + unsigned i; + waypoint *wpt_tmp; + + if (process_rte) { + rte_head = route_head_alloc(); + rte_head->rte_waypt_ct = nof_wp; + route_add_head(rte_head); + } + + for (n = 0; n < nof_wp; ++n) { + + wpt_tmp = waypt_new(); + + /* Read waypoint data */ + + ng_fread_wp_data(strComment, &WPNC, file_in); + + + if (n < nof_wp - 1) { + /* + gbfread (&ng_next_wp.pad1[0], 2, 1, file_in); + ng_next_wp.next_wp = gbfgetint16 (file_in); + gbfread (&ng_next_wp.pad2[0], 2, 1, file_in); + */ + ng_fread_next_wp(&ng_next_wp, file_in); + + } + /* Clear commas form the comment for CSV file commonality */ + for (i = 0; i shortname = xstrdup(WPNC.strName); + wpt_tmp->description = xstrdup(strComment); + + if (process_rte) { + route_add_wpt(rte_head, wpt_tmp); + } else { + waypt_add(wpt_tmp); + } + } } /* data_read */ ff_vecs_t ng_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - ng_args, - //CET_CHARSET_ASCII, 0 /* CET-REVIEW */ - CET_CHARSET_HEBREW, 0 + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + ng_args, + //CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + CET_CHARSET_HEBREW, 0 }; diff --git a/gpsbabel/navilink.c b/gpsbabel/navilink.c index e828983cd..42ddab0ef 100644 --- a/gpsbabel/navilink.c +++ b/gpsbabel/navilink.c @@ -48,8 +48,8 @@ static unsigned *route_ids; static unsigned route_id_ptr; static enum { - READING, - WRITING + READING, + WRITING } operation = READING; #define SERIAL_TIMEOUT 8000 @@ -89,68 +89,80 @@ static enum { static const char *const icon_table[] = { - "Star", - "Flag", - "House", - "Left Sign", - "Telegraph Pole", - "People", - "Fuel", - "Phone", - "Pole", - "Mountain", - "Water", - "Tree", - "Road Narrows", - "Crossroads", - "Road Fork", - "Turn Right", - "Turn Left", - "Bird", - "3D House", - "Trig Point", - "Tower", - "Cable Car", - "Church", - "Telegraph Pole", - "Skier", - "Anchor", - "Fish", - "Fishes", - "Rain", - "Fisherman", - "Tower", - "Boats", - "Boat", - "Bicycle", - "Railway Track", - "Dollar Sign", - "Bus", - "Camera", - "Fuel Pump", - "Cup", - "Merging Road", - "Plane", - "Red Cross", - "House", - "Parking" + "Star", + "Flag", + "House", + "Left Sign", + "Telegraph Pole", + "People", + "Fuel", + "Phone", + "Pole", + "Mountain", + "Water", + "Tree", + "Road Narrows", + "Crossroads", + "Road Fork", + "Turn Right", + "Turn Left", + "Bird", + "3D House", + "Trig Point", + "Tower", + "Cable Car", + "Church", + "Telegraph Pole", + "Skier", + "Anchor", + "Fish", + "Fishes", + "Rain", + "Fisherman", + "Tower", + "Boats", + "Boat", + "Bicycle", + "Railway Track", + "Dollar Sign", + "Bus", + "Camera", + "Fuel Pump", + "Cup", + "Merging Road", + "Plane", + "Red Cross", + "House", + "Parking" }; static arglist_t navilink_args[] = { - { "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "nukedlg", &nukedlg, "Clear the datalog", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - { "datalog", &datalog, "Read from datalogger buffer", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "power_off", &poweroff, "Command unit to power itself down", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nuketrk", &nuketrk, "Delete all track points", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukerte", &nukerte, "Delete all routes", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukewpt", &nukewpt, "Delete all waypoints", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "nukedlg", &nukedlg, "Clear the datalog", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + { + "datalog", &datalog, "Read from datalogger buffer", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "power_off", &poweroff, "Command unit to power itself down", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void (*write_waypoint)(const waypoint *) = NULL; @@ -164,49 +176,50 @@ static void (*write_route_end)(const route_head *track) = NULL; static int find_icon_from_descr(const char *descr) { - int i; + int i; - for (i = 0; descr && i < sizeof(icon_table) / sizeof(const char *); i++) { - if (strcmp(descr, icon_table[i]) == 0) - return i; - } + for (i = 0; descr && i < sizeof(icon_table) / sizeof(const char *); i++) { + if (strcmp(descr, icon_table[i]) == 0) { + return i; + } + } - return 0; + return 0; } static void free_waypoints(waypoint **waypts) { - waypoint **wayptp; + waypoint **wayptp; - for (wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) { - if (*wayptp) { - waypt_free(*wayptp); - } - } + for (wayptp = waypts; wayptp < waypts + MAX_WAYPOINTS; wayptp++) { + if (*wayptp) { + waypt_free(*wayptp); + } + } - xfree(waypts); + xfree(waypts); } static unsigned compare_waypoints(const waypoint *waypt1, const waypoint *waypt2) { - return waypt1->latitude == waypt2->latitude && - waypt1->longitude == waypt2->longitude && - waypt1->altitude == waypt2->altitude && - strcmp(waypt1->shortname, waypt2->shortname) == 0; + return waypt1->latitude == waypt2->latitude && + waypt1->longitude == waypt2->longitude && + waypt1->altitude == waypt2->altitude && + strcmp(waypt1->shortname, waypt2->shortname) == 0; } unsigned navilink_checksum_packet(const unsigned char *packet, unsigned length) { - unsigned checksum = 0; + unsigned checksum = 0; - while (length-- > 0) { - checksum += *packet++; - } + while (length-- > 0) { + checksum += *packet++; + } - return checksum & 0x7fff; + return checksum & 0x7fff; } #ifdef NAVILINK_DEBUG @@ -214,15 +227,19 @@ navilink_checksum_packet(const unsigned char *packet, unsigned length) static void dump_packet(char *prefix, unsigned char *packet, unsigned length) { - unsigned i; - - for (i = 0; i < length; i++ ) { - if ((i % 16) == 0) fprintf(stderr, "%s %08x :", prefix, i); - fprintf(stderr, " %02x", packet[i]); - if ((i % 16) == 15 || i == length - 1) fprintf(stderr, "\n"); - } - - fprintf(stderr, "\n"); + unsigned i; + + for (i = 0; i < length; i++) { + if ((i % 16) == 0) { + fprintf(stderr, "%s %08x :", prefix, i); + } + fprintf(stderr, " %02x", packet[i]); + if ((i % 16) == 15 || i == length - 1) { + fprintf(stderr, "\n"); + } + } + + fprintf(stderr, "\n"); } #endif @@ -230,38 +247,38 @@ dump_packet(char *prefix, unsigned char *packet, unsigned length) static void write_packet(unsigned type, const void *payload, unsigned length) { - unsigned char *packet = xmalloc(length + 9); + unsigned char *packet = xmalloc(length + 9); - packet[0] = 0xa0; - packet[1] = 0xa2; - le_write16(packet + 2, length + 1); - packet[4] = type; - memcpy(packet + 5, payload, length); - le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1)); - packet[length + 7] = 0xb0; - packet[length + 8] = 0xb3; + packet[0] = 0xa0; + packet[1] = 0xa2; + le_write16(packet + 2, length + 1); + packet[4] = type; + memcpy(packet + 5, payload, length); + le_write16(packet + length + 5, navilink_checksum_packet(packet + 4, length + 1)); + packet[length + 7] = 0xb0; + packet[length + 8] = 0xb3; #ifdef NAVILINK_DEBUG - dump_packet(">>>", packet + 4, length + 1); + dump_packet(">>>", packet + 4, length + 1); #endif - if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) { - fatal(MYNAME ": Write error\n"); - } + if (gbser_write(serial_handle, packet, length + 9) != gbser_OK) { + fatal(MYNAME ": Write error\n"); + } - xfree(packet); + xfree(packet); } static unsigned read_word(void) { - unsigned char buffer[2]; + unsigned char buffer[2]; - if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) { - fatal(MYNAME ": Read error\n"); - } + if (gbser_read_wait(serial_handle, buffer, 2, SERIAL_TIMEOUT) != 2) { + fatal(MYNAME ": Read error\n"); + } - return (buffer[1] << 8) | buffer[0]; + return (buffer[1] << 8) | buffer[0]; } /* @@ -279,561 +296,563 @@ read_packet(unsigned type, void *payload, unsigned minlength, unsigned maxlength, int handle_nak) { - unsigned size; - unsigned char *data; - unsigned checksum; + unsigned size; + unsigned char *data; + unsigned checksum; - if (read_word() != 0xa2a0) { - fatal(MYNAME ": Protocol error: Bad packet header." - " Is your NaviGPS in NAVILINK mode?\n"); - } + if (read_word() != 0xa2a0) { + fatal(MYNAME ": Protocol error: Bad packet header." + " Is your NaviGPS in NAVILINK mode?\n"); + } - if ((size = read_word()) <= minlength) { - fatal(MYNAME ": Protocol error: Packet too short\n"); - } + if ((size = read_word()) <= minlength) { + fatal(MYNAME ": Protocol error: Packet too short\n"); + } - data = xmalloc(size); + data = xmalloc(size); - if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) { - fatal(MYNAME ": Read error reading %d byte payload\n", size); - } + if (gbser_read_wait(serial_handle, data, size, SERIAL_TIMEOUT) != size) { + fatal(MYNAME ": Read error reading %d byte payload\n", size); + } #ifdef NAVILINK_DEBUG - dump_packet("<<<", data, size); + dump_packet("<<<", data, size); #endif - if (data[0] != type) { - if (handle_nak && data[0] == PID_NAK) { - return FALSE; - } + if (data[0] != type) { + if (handle_nak && data[0] == PID_NAK) { + return FALSE; + } - fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]); - } + fatal(MYNAME ": Protocol error: Bad packet type (expected 0x%02x but got 0x%02x)\n", type, data[0]); + } - if ((checksum = read_word()) != navilink_checksum_packet(data, size)) { - fatal(MYNAME ": Checksum error - expected %x got %x\n", - navilink_checksum_packet(data, size), checksum); - } + if ((checksum = read_word()) != navilink_checksum_packet(data, size)) { + fatal(MYNAME ": Checksum error - expected %x got %x\n", + navilink_checksum_packet(data, size), checksum); + } - if (read_word() != 0xb3b0) { - fatal(MYNAME ": Protocol error: Bad packet trailer\n"); - } + if (read_word() != 0xb3b0) { + fatal(MYNAME ": Protocol error: Bad packet trailer\n"); + } - if (size - 1 > maxlength) { - memcpy(payload, data + 1, maxlength); - } else { - memcpy(payload, data + 1, size - 1); - } + if (size - 1 > maxlength) { + memcpy(payload, data + 1, maxlength); + } else { + memcpy(payload, data + 1, size - 1); + } - xfree(data); + xfree(data); - return TRUE; + return TRUE; } static time_t decode_datetime(const unsigned char *buffer) { - struct tm tm; + struct tm tm; - tm.tm_sec = buffer[5]; - tm.tm_min = buffer[4]; - tm.tm_hour = buffer[3]; - tm.tm_mday = buffer[2]; - tm.tm_mon = buffer[1] - 1; - tm.tm_year = buffer[0] + 100; + tm.tm_sec = buffer[5]; + tm.tm_min = buffer[4]; + tm.tm_hour = buffer[3]; + tm.tm_mday = buffer[2]; + tm.tm_mon = buffer[1] - 1; + tm.tm_year = buffer[0] + 100; - return mkgmtime(&tm); + return mkgmtime(&tm); } static void encode_datetime(time_t datetime, unsigned char *buffer) { - struct tm *tm; - - if ((tm = gmtime(&datetime)) != NULL) { - buffer[0] = tm->tm_year - 100; - buffer[1] = tm->tm_mon + 1; - buffer[2] = tm->tm_mday; - buffer[3] = tm->tm_hour; - buffer[4] = tm->tm_min; - buffer[5] = tm->tm_sec; - } else { - memset(buffer, 0, 6); - } + struct tm *tm; + + if ((tm = gmtime(&datetime)) != NULL) { + buffer[0] = tm->tm_year - 100; + buffer[1] = tm->tm_mon + 1; + buffer[2] = tm->tm_mday; + buffer[3] = tm->tm_hour; + buffer[4] = tm->tm_min; + buffer[5] = tm->tm_sec; + } else { + memset(buffer, 0, 6); + } } static void decode_position(const unsigned char *buffer, waypoint *waypt) { - waypt->latitude = le_read32(buffer + 0) / 10000000.0; - waypt->longitude = le_read32(buffer + 4) / 10000000.0; - waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8)); + waypt->latitude = le_read32(buffer + 0) / 10000000.0; + waypt->longitude = le_read32(buffer + 4) / 10000000.0; + waypt->altitude = FEET_TO_METERS(le_read16(buffer + 8)); } static void encode_position(const waypoint *waypt, unsigned char *buffer) { - le_write32(buffer + 0, (int) (waypt->latitude * 10000000)); - le_write32(buffer + 4, (int) (waypt->longitude * 10000000)); - le_write16(buffer + 8, METERS_TO_FEET(waypt->altitude)); + le_write32(buffer + 0, (int)(waypt->latitude * 10000000)); + le_write32(buffer + 4, (int)(waypt->longitude * 10000000)); + le_write16(buffer + 8, METERS_TO_FEET(waypt->altitude)); } static unsigned decode_waypoint_id(const unsigned char *buffer) { - unsigned id = le_read16(buffer + 2); + unsigned id = le_read16(buffer + 2); - if (id >= MAX_WAYPOINTS) { - fatal(MYNAME ": Invalid waypoint ID\n"); - } + if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID\n"); + } - return id; + return id; } static waypoint * decode_waypoint(const unsigned char *buffer) { - waypoint *waypt = waypt_new(); + waypoint *waypt = waypt_new(); - decode_position(buffer + 12, waypt); - waypt->shortname = xstrdup((char *)buffer + 4); - waypt->icon_descr = icon_table[buffer[28]]; - waypt->creation_time = decode_datetime(buffer + 22); + decode_position(buffer + 12, waypt); + waypt->shortname = xstrdup((char *)buffer + 4); + waypt->icon_descr = icon_table[buffer[28]]; + waypt->creation_time = decode_datetime(buffer + 22); - return waypt; + return waypt; } static void encode_waypoint(const waypoint *waypt, unsigned char *buffer) { - buffer[0] = 0x00; - buffer[1] = 0x40; - le_write16(buffer + 2, 0); - strncpy((char *)buffer + 4, waypt->shortname, 6); - buffer[10] = 0; - buffer[11] = 0; - encode_position(waypt, buffer + 12); - encode_datetime(waypt->creation_time, buffer + 22); - buffer[28] = find_icon_from_descr(waypt->icon_descr); - buffer[29] = 0; - buffer[30] = 0x00; - buffer[31] = 0x7e; + buffer[0] = 0x00; + buffer[1] = 0x40; + le_write16(buffer + 2, 0); + strncpy((char *)buffer + 4, waypt->shortname, 6); + buffer[10] = 0; + buffer[11] = 0; + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = find_icon_from_descr(waypt->icon_descr); + buffer[29] = 0; + buffer[30] = 0x00; + buffer[31] = 0x7e; } static waypoint * decode_trackpoint(const unsigned char *buffer) { - waypoint *waypt = waypt_new(); + waypoint *waypt = waypt_new(); - decode_position(buffer + 12, waypt); - waypt->creation_time = decode_datetime(buffer + 22); - WAYPT_SET(waypt, course, le_read16(buffer + 2)); - WAYPT_SET(waypt, speed, KPH_TO_MPS(buffer[29] * 2)); + decode_position(buffer + 12, waypt); + waypt->creation_time = decode_datetime(buffer + 22); + WAYPT_SET(waypt, course, le_read16(buffer + 2)); + WAYPT_SET(waypt, speed, KPH_TO_MPS(buffer[29] * 2)); - return waypt; + return waypt; } static void encode_trackpoint(const waypoint *waypt, unsigned serial, unsigned char *buffer) { - double x; - double y; - int32 z; - char zc; - - GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc); - - le_write16(buffer + 0, serial); - le_write16(buffer + 2, WAYPT_GET(waypt, course, 0)); - le_write32(buffer + 4, x); - le_write32(buffer + 8, y); - encode_position(waypt, buffer + 12); - encode_datetime(waypt->creation_time, buffer + 22); - buffer[28] = z; - buffer[29] = MPS_TO_KPH(WAYPT_GET(waypt, speed, 0) / 2); - buffer[30] = 0x5a; - buffer[31] = 0x7e; + double x; + double y; + int32 z; + char zc; + + GPS_Math_WGS84_To_UTM_EN(waypt->latitude, waypt->longitude, &x, &y, &z, &zc); + + le_write16(buffer + 0, serial); + le_write16(buffer + 2, WAYPT_GET(waypt, course, 0)); + le_write32(buffer + 4, x); + le_write32(buffer + 8, y); + encode_position(waypt, buffer + 12); + encode_datetime(waypt->creation_time, buffer + 22); + buffer[28] = z; + buffer[29] = MPS_TO_KPH(WAYPT_GET(waypt, speed, 0) / 2); + buffer[30] = 0x5a; + buffer[31] = 0x7e; } static waypoint ** serial_read_waypoints(void) { - waypoint **waypts = NULL; - unsigned char information[32]; - unsigned short total; - unsigned short start; + waypoint **waypts = NULL; + unsigned char information[32]; + unsigned short total; + unsigned short start; - if (global_opts.masked_objective & RTEDATAMASK) { - waypts = xcalloc(MAX_WAYPOINTS, sizeof(waypoint *)); - } + if (global_opts.masked_objective & RTEDATAMASK) { + waypts = xcalloc(MAX_WAYPOINTS, sizeof(waypoint *)); + } - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - total = le_read16(information + 0); + total = le_read16(information + 0); - for (start = 0; start < total; start += 32) { - unsigned short count = total - start; - unsigned char payload[7]; - unsigned char *waypoints; - unsigned char *w; + for (start = 0; start < total; start += 32) { + unsigned short count = total - start; + unsigned char payload[7]; + unsigned char *waypoints; + unsigned char *w; - if (count > 32) count = 32; + if (count > 32) { + count = 32; + } - le_write32(payload + 0, start); - le_write16(payload + 4, count); - payload[6] = 1; + le_write32(payload + 0, start); + le_write16(payload + 4, count); + payload[6] = 1; - write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload)); + write_packet(PID_QRY_WAYPOINTS, payload, sizeof(payload)); - waypoints = xmalloc(count * 32); + waypoints = xmalloc(count * 32); - read_packet(PID_DATA, waypoints, count * 32, count * 32, FALSE); + read_packet(PID_DATA, waypoints, count * 32, count * 32, FALSE); - for (w = waypoints; w < waypoints + count * 32; w = w + 32) { - if (global_opts.masked_objective & WPTDATAMASK) { - waypt_add(decode_waypoint(w)); - } - if (global_opts.masked_objective & RTEDATAMASK) { - waypts[decode_waypoint_id(w)] = decode_waypoint(w); - } - } + for (w = waypoints; w < waypoints + count * 32; w = w + 32) { + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(w)); + } + if (global_opts.masked_objective & RTEDATAMASK) { + waypts[decode_waypoint_id(w)] = decode_waypoint(w); + } + } - xfree(waypoints); + xfree(waypoints); - if (global_opts.verbose_status) { - waypt_status_disp(total, start + count); - } - } + if (global_opts.verbose_status) { + waypt_status_disp(total, start + count); + } + } - return waypts; + return waypts; } static unsigned int serial_write_waypoint_packet(const waypoint *waypt) { - unsigned char data[32]; - unsigned char id[2]; + unsigned char data[32]; + unsigned char id[2]; - encode_waypoint(waypt, data); - write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); - if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { - fatal(MYNAME ": Could not write waypoint.\n"); - } + encode_waypoint(waypt, data); + write_packet(PID_ADD_A_WAYPOINT, data, sizeof(data)); + if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { + fatal(MYNAME ": Could not write waypoint.\n"); + } - return le_read16(id); + return le_read16(id); } static void serial_write_waypoint(const waypoint *waypt) { - serial_write_waypoint_packet(waypt); + serial_write_waypoint_packet(waypt); } static void serial_read_track(void) { - unsigned char information[32]; - unsigned int address; - unsigned short total; - route_head *track; + unsigned char information[32]; + unsigned int address; + unsigned short total; + route_head *track; - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - address = le_read32(information + 4); - total = le_read16(information + 12); + address = le_read32(information + 4); + total = le_read16(information + 12); - track = route_head_alloc(); - track_add_head(track); + track = route_head_alloc(); + track_add_head(track); - while (total > 0) { - unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS; - unsigned char payload[7]; - unsigned char *trackpoints; - unsigned char *t; + while (total > 0) { + unsigned short count = total < MAX_READ_TRACKPOINTS ? total : MAX_READ_TRACKPOINTS; + unsigned char payload[7]; + unsigned char *trackpoints; + unsigned char *t; - le_write32(payload + 0, address); - le_write16(payload + 4, count * 32); - payload[6] = 0x00; + le_write32(payload + 0, address); + le_write16(payload + 4, count * 32); + payload[6] = 0x00; - write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload)); + write_packet(PID_READ_TRACKPOINTS, payload, sizeof(payload)); - trackpoints = xmalloc(count * 32); + trackpoints = xmalloc(count * 32); - read_packet(PID_DATA, trackpoints, count * 32, count * 32, FALSE); - write_packet(PID_ACK, NULL, 0); + read_packet(PID_DATA, trackpoints, count * 32, count * 32, FALSE); + write_packet(PID_ACK, NULL, 0); - for (t = trackpoints; t < trackpoints + count * 32; t = t + 32) { - track_add_wpt(track, decode_trackpoint(t)); - } + for (t = trackpoints; t < trackpoints + count * 32; t = t + 32) { + track_add_wpt(track, decode_trackpoint(t)); + } - xfree(trackpoints); + xfree(trackpoints); - address = address + count * 32; - total = total - count; - } + address = address + count * 32; + total = total - count; + } } static void serial_write_track(void) { - unsigned char information[32]; - unsigned int address; - unsigned short total; - unsigned char data[7]; + unsigned char information[32]; + unsigned int address; + unsigned short total; + unsigned char data[7]; - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); - address = le_read32(information + 4); - total = le_read16(information + 12); + address = le_read32(information + 4); + total = le_read16(information + 12); - le_write32(data + 0, address + total * 32); - le_write16(data + 4, track_data_ptr - track_data); - data[6] = 0x00; + le_write32(data + 0, address + total * 32); + le_write16(data + 4, track_data_ptr - track_data); + data[6] = 0x00; - write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data)); - gb_sleep(10000); - write_packet(PID_DATA, track_data, track_data_ptr - track_data); - read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); + write_packet(PID_WRITE_TRACKPOINTS, data, sizeof(data)); + gb_sleep(10000); + write_packet(PID_DATA, track_data, track_data_ptr - track_data); + read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); - track_data_ptr = track_data; + track_data_ptr = track_data; } static void serial_write_track_start(const route_head *track) { - track_data = xmalloc(MAX_WRITE_TRACKPOINTS * 32); - track_data_ptr = track_data; - track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32; + track_data = xmalloc(MAX_WRITE_TRACKPOINTS * 32); + track_data_ptr = track_data; + track_data_end = track_data + MAX_WRITE_TRACKPOINTS * 32; } static void serial_write_track_point(const waypoint *waypt) { - if (track_data_ptr >= track_data_end) { - serial_write_track(); - } + if (track_data_ptr >= track_data_end) { + serial_write_track(); + } - encode_trackpoint(waypt, 0, track_data_ptr); + encode_trackpoint(waypt, 0, track_data_ptr); - track_data_ptr += 32; + track_data_ptr += 32; } static void serial_write_track_end(const route_head *track) { - if (track_data_ptr > track_data) { - serial_write_track(); - } + if (track_data_ptr > track_data) { + serial_write_track(); + } - xfree(track_data); + xfree(track_data); } static void serial_read_routes(waypoint **waypts) { - unsigned char information[32]; - unsigned char routec; - unsigned char r; - - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); - - routec = information[2]; - - for (r = 0; r < routec; r++) { - unsigned char payload[7]; - unsigned char routedata[320]; - route_head *route; - int sr; - - le_write32(payload + 0, r); - le_write16(payload + 2, 0); - payload[6] = 0x01; - - write_packet(PID_QRY_ROUTE, payload, sizeof(payload)); - read_packet(PID_DATA, routedata, 64, sizeof(routedata), FALSE); - - route = route_head_alloc(); - route->rte_num = routedata[2]; - route->rte_name = xstrdup((char *)routedata + 4); - route_add_head(route); - - for (sr = 0; sr < MAX_SUBROUTES; sr++) { - int w; - - for (w = 0; w < MAX_SUBROUTE_LENGTH; w++) { - unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w); - - if (id == 0xffffu) { - w = MAX_SUBROUTE_LENGTH; - sr = MAX_SUBROUTES; - } else if (id >= MAX_WAYPOINTS) { - fatal(MYNAME ": Invalid waypoint ID in route\n"); - } else if (waypts[id] == NULL) { - fatal(MYNAME ": Non-existent waypoint in route\n"); - } else { - route_add_wpt(route, waypt_dupe(waypts[id])); - } - } - } - } + unsigned char information[32]; + unsigned char routec; + unsigned char r; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); + + routec = information[2]; + + for (r = 0; r < routec; r++) { + unsigned char payload[7]; + unsigned char routedata[320]; + route_head *route; + int sr; + + le_write32(payload + 0, r); + le_write16(payload + 2, 0); + payload[6] = 0x01; + + write_packet(PID_QRY_ROUTE, payload, sizeof(payload)); + read_packet(PID_DATA, routedata, 64, sizeof(routedata), FALSE); + + route = route_head_alloc(); + route->rte_num = routedata[2]; + route->rte_name = xstrdup((char *)routedata + 4); + route_add_head(route); + + for (sr = 0; sr < MAX_SUBROUTES; sr++) { + int w; + + for (w = 0; w < MAX_SUBROUTE_LENGTH; w++) { + unsigned short id = le_read16(routedata + 34 + 32 * sr + 2 *w); + + if (id == 0xffffu) { + w = MAX_SUBROUTE_LENGTH; + sr = MAX_SUBROUTES; + } else if (id >= MAX_WAYPOINTS) { + fatal(MYNAME ": Invalid waypoint ID in route\n"); + } else if (waypts[id] == NULL) { + fatal(MYNAME ": Non-existent waypoint in route\n"); + } else { + route_add_wpt(route, waypt_dupe(waypts[id])); + } + } + } + } } static void serial_write_route_start(const route_head *route) { - route_ids = xmalloc(route->rte_waypt_ct * sizeof(unsigned)); - route_id_ptr = 0; + route_ids = xmalloc(route->rte_waypt_ct * sizeof(unsigned)); + route_id_ptr = 0; } static void serial_write_route_point(const waypoint *waypt) { - unsigned w; + unsigned w; - for (w = 0; w < MAX_WAYPOINTS; w++) { - if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) { - break; - } - } + for (w = 0; w < MAX_WAYPOINTS; w++) { + if (route_waypts[w] && compare_waypoints(waypt, route_waypts[w])) { + break; + } + } - if (w == MAX_WAYPOINTS) { - w = serial_write_waypoint_packet(waypt); - route_waypts[w] = waypt_dupe(waypt); - } + if (w == MAX_WAYPOINTS) { + w = serial_write_waypoint_packet(waypt); + route_waypts[w] = waypt_dupe(waypt); + } - route_ids[route_id_ptr++] = w; + route_ids[route_id_ptr++] = w; } static void serial_write_route_end(const route_head *route) { - unsigned char *data; - unsigned src; - unsigned sr; - unsigned char id[1]; - - if (route_id_ptr > MAX_ROUTE_LENGTH) { - fatal(MYNAME ": Route %s too long\n", route->rte_name); - } - - src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH; - data = xmalloc(32 + src * 32); - - le_write16(data + 0, 0x2000); - data[2] = 0; - data[3] = 0x20; - strncpy((char *)data + 4, route->rte_name, 6); - data[18] = 0; - data[19] = 0; - le_write32(data + 20, 0); - le_write32(data + 24, 0); - le_write16(data + 28, 0); - data[30] = 0x7b; - data[31] = 0x77; - - for (sr = 0; sr < src; sr++) { - unsigned char *srdata = data + 32 + 32 * sr; - unsigned pt_offset = MAX_SUBROUTE_LENGTH * sr; - unsigned pt; - - le_write16(srdata + 0, 0x2010); - - for (pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) { - if (pt_offset + pt < route_id_ptr) { - le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]); - } else { - le_write16(srdata + 2 + 2 * pt, 0xffffu); - } - } - - srdata[30] = 0x7f; - srdata[31] = 0x77; - } - - write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32); - if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { - fatal(MYNAME ": Could not add route.\n"); - } - - xfree(data); - xfree(route_ids); + unsigned char *data; + unsigned src; + unsigned sr; + unsigned char id[1]; + + if (route_id_ptr > MAX_ROUTE_LENGTH) { + fatal(MYNAME ": Route %s too long\n", route->rte_name); + } + + src = (route_id_ptr + MAX_SUBROUTE_LENGTH) / MAX_SUBROUTE_LENGTH; + data = xmalloc(32 + src * 32); + + le_write16(data + 0, 0x2000); + data[2] = 0; + data[3] = 0x20; + strncpy((char *)data + 4, route->rte_name, 6); + data[18] = 0; + data[19] = 0; + le_write32(data + 20, 0); + le_write32(data + 24, 0); + le_write16(data + 28, 0); + data[30] = 0x7b; + data[31] = 0x77; + + for (sr = 0; sr < src; sr++) { + unsigned char *srdata = data + 32 + 32 * sr; + unsigned pt_offset = MAX_SUBROUTE_LENGTH * sr; + unsigned pt; + + le_write16(srdata + 0, 0x2010); + + for (pt = 0; pt < MAX_SUBROUTE_LENGTH; pt++) { + if (pt_offset + pt < route_id_ptr) { + le_write16(srdata + 2 + 2 * pt, route_ids[pt_offset + pt]); + } else { + le_write16(srdata + 2 + 2 * pt, 0xffffu); + } + } + + srdata[30] = 0x7f; + srdata[31] = 0x77; + } + + write_packet(PID_ADD_A_ROUTE, data, 32 + src * 32); + if (!read_packet(PID_DATA, id, sizeof(id), sizeof(id), TRUE)) { + fatal(MYNAME ": Could not add route.\n"); + } + + xfree(data); + xfree(route_ids); } static int decode_sbp_usec(const unsigned char *buffer) { - int msec = le_read16(buffer); - return (msec % 1000) * 1000; + int msec = le_read16(buffer); + return (msec % 1000) * 1000; } static time_t decode_sbp_datetime_packed(const unsigned char *buffer) { - /* - * Packed_Date_Time_UTC: - * bit 31..22 :year*12+month (10 bits) : real year= year+2000 - * bit17.21: day (5bits) - * bit12.16: hour (5bits) - * bit6..11: min (6bits) - * bit0..5 : sec (6bits) - * - * 0 1 2 3 - * 01234567 01234567 01234567 01234567 - * ........ ........ ........ ........ - * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm - */ - - int months; - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - tm.tm_sec = buffer[0] & 0x3F; - tm.tm_min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2); - tm.tm_hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4); - tm.tm_mday = (buffer[2] & 0x3E) >> 1; - months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2; - tm.tm_mon = months % 12 - 1; - tm.tm_year = 100 + months / 12; - - return mkgmtime(&tm); + /* + * Packed_Date_Time_UTC: + * bit 31..22 :year*12+month (10 bits) : real year= year+2000 + * bit17.21: day (5bits) + * bit12.16: hour (5bits) + * bit6..11: min (6bits) + * bit0..5 : sec (6bits) + * + * 0 1 2 3 + * 01234567 01234567 01234567 01234567 + * ........ ........ ........ ........ + * SSSSSSMM MMMMHHHH Hdddddmm mmmmmmmm + */ + + int months; + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_sec = buffer[0] & 0x3F; + tm.tm_min = ((buffer[0] & 0xC0) >> 6) | ((buffer[1] & 0x0F) << 2); + tm.tm_hour = ((buffer[1] & 0xF0) >> 4) | ((buffer[2] & 0x01) << 4); + tm.tm_mday = (buffer[2] & 0x3E) >> 1; + months = ((buffer[2] & 0xC0) >> 6) | buffer[3] << 2; + tm.tm_mon = months % 12 - 1; + tm.tm_year = 100 + months / 12; + + return mkgmtime(&tm); } static void decode_sbp_position(const unsigned char *buffer, waypoint *waypt) { - waypt->latitude = le_read32(buffer + 0) / 10000000.0; - waypt->longitude = le_read32(buffer + 4) / 10000000.0; - waypt->altitude = le_read32(buffer + 8) / 100.0; + waypt->latitude = le_read32(buffer + 0) / 10000000.0; + waypt->longitude = le_read32(buffer + 4) / 10000000.0; + waypt->altitude = le_read32(buffer + 8) / 100.0; } waypoint * navilink_decode_logpoint(const unsigned char *buffer) { - waypoint *waypt = NULL; - waypt = waypt_new(); - - waypt->hdop = ((unsigned char)buffer[0]) * 0.2f; - waypt->sat = buffer[1]; - waypt->microseconds = decode_sbp_usec(buffer + 2); - waypt->creation_time = decode_sbp_datetime_packed(buffer + 4); - decode_sbp_position(buffer + 12, waypt); - WAYPT_SET(waypt, speed, le_read16(buffer + 24) * 0.01f); - WAYPT_SET(waypt, course, le_read16(buffer + 26) * 0.01f); - - return waypt; + waypoint *waypt = NULL; + waypt = waypt_new(); + + waypt->hdop = ((unsigned char)buffer[0]) * 0.2f; + waypt->sat = buffer[1]; + waypt->microseconds = decode_sbp_usec(buffer + 2); + waypt->creation_time = decode_sbp_datetime_packed(buffer + 4); + decode_sbp_position(buffer + 12, waypt); + WAYPT_SET(waypt, speed, le_read16(buffer + 24) * 0.01f); + WAYPT_SET(waypt, course, le_read16(buffer + 26) * 0.01f); + + return waypt; } /* @@ -847,149 +866,149 @@ static void read_datalog_info(unsigned int *seg1_addr, unsigned int *seg1_len, unsigned int *seg2_addr, unsigned int *seg2_len) { - unsigned char info[16]; - unsigned int flash_start_addr; - unsigned int flash_length; - unsigned int data_start_addr; - unsigned int next_blank_addr; - - write_packet(PID_INFO_DATALOG, NULL, 0); - read_packet(PID_DATA, info, sizeof(info), sizeof(info), FALSE); - - flash_start_addr = le_read32(info); - flash_length = le_read32(info + 4); - data_start_addr = le_read32(info + 8); - next_blank_addr = le_read32(info + 12); - - if (data_start_addr > next_blank_addr) { - /* usually there are two segments to be read */ - *seg1_addr = data_start_addr; - *seg1_len = flash_start_addr + flash_length - *seg1_addr; - *seg2_addr = flash_start_addr; - *seg2_len = next_blank_addr - flash_start_addr; - } else { - /* hasn't wrapped around yet, only one segment */ - *seg1_addr = data_start_addr; - *seg1_len = next_blank_addr - data_start_addr; - *seg2_addr = 0; - *seg2_len = 0; - } - - if (*seg1_len & 0x1F || *seg2_len & 0x1F) { - fatal(MYNAME ": Protocol error: datalog lengths %u, %u " - "not aligned to 32 bytes\n", *seg1_len, *seg2_len); - } + unsigned char info[16]; + unsigned int flash_start_addr; + unsigned int flash_length; + unsigned int data_start_addr; + unsigned int next_blank_addr; + + write_packet(PID_INFO_DATALOG, NULL, 0); + read_packet(PID_DATA, info, sizeof(info), sizeof(info), FALSE); + + flash_start_addr = le_read32(info); + flash_length = le_read32(info + 4); + data_start_addr = le_read32(info + 8); + next_blank_addr = le_read32(info + 12); + + if (data_start_addr > next_blank_addr) { + /* usually there are two segments to be read */ + *seg1_addr = data_start_addr; + *seg1_len = flash_start_addr + flash_length - *seg1_addr; + *seg2_addr = flash_start_addr; + *seg2_len = next_blank_addr - flash_start_addr; + } else { + /* hasn't wrapped around yet, only one segment */ + *seg1_addr = data_start_addr; + *seg1_len = next_blank_addr - data_start_addr; + *seg2_addr = 0; + *seg2_len = 0; + } + + if (*seg1_len & 0x1F || *seg2_len & 0x1F) { + fatal(MYNAME ": Protocol error: datalog lengths %u, %u " + "not aligned to 32 bytes\n", *seg1_len, *seg2_len); + } } static void read_datalog_records(route_head *track, unsigned int start_addr, unsigned int len) { - unsigned char logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN]; - unsigned int logpoints_len; - unsigned char payload[7]; - unsigned char *p; - - /* The protocol only supports reading 256 logpoints at once, so - * read small chunks until none left. */ - while (len > 0) { - logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len; - - le_write32(payload, start_addr); - le_write16(payload + 4, logpoints_len); - payload[6] = 0x01; - - write_packet(PID_READ_DATALOG, payload, sizeof(payload)); - read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, FALSE); - write_packet(PID_ACK, NULL, 0); - - for (p = logpoints; p < logpoints + logpoints_len; p += 32) { - track_add_wpt(track, navilink_decode_logpoint(p)); - } - - len -= logpoints_len; - start_addr += logpoints_len; - } + unsigned char logpoints[MAX_READ_LOGPOINTS * SBP_RECORD_LEN]; + unsigned int logpoints_len; + unsigned char payload[7]; + unsigned char *p; + + /* The protocol only supports reading 256 logpoints at once, so + * read small chunks until none left. */ + while (len > 0) { + logpoints_len = len > MAX_READ_LOGPOINTS ? MAX_READ_LOGPOINTS : len; + + le_write32(payload, start_addr); + le_write16(payload + 4, logpoints_len); + payload[6] = 0x01; + + write_packet(PID_READ_DATALOG, payload, sizeof(payload)); + read_packet(PID_DATA, logpoints, logpoints_len, logpoints_len, FALSE); + write_packet(PID_ACK, NULL, 0); + + for (p = logpoints; p < logpoints + logpoints_len; p += 32) { + track_add_wpt(track, navilink_decode_logpoint(p)); + } + + len -= logpoints_len; + start_addr += logpoints_len; + } } static void serial_read_datalog(void) { - route_head *track; - unsigned int seg1_addr; - unsigned int seg1_len; - unsigned int seg2_addr; - unsigned int seg2_len; - - read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len); - - track = route_head_alloc(); - track_add_head(track); - - if (seg1_len) { - read_datalog_records(track, seg1_addr, seg1_len); - } - - if (seg2_len) { - read_datalog_records(track, seg2_addr, seg2_len); - } + route_head *track; + unsigned int seg1_addr; + unsigned int seg1_len; + unsigned int seg2_addr; + unsigned int seg2_len; + + read_datalog_info(&seg1_addr, &seg1_len, &seg2_addr, &seg2_len); + + track = route_head_alloc(); + track_add_head(track); + + if (seg1_len) { + read_datalog_records(track, seg1_addr, seg1_len); + } + + if (seg2_len) { + read_datalog_records(track, seg2_addr, seg2_len); + } } static void file_read(void) { - unsigned char data[32]; - route_head *track = NULL; - - while (gbfread(data, sizeof(data), 1, file_handle) == 1) { - switch (le_read16(data)) { - case 0x2000: - fatal(MYNAME ": Route objects not supported in file sources\n"); - break; - case 0x2010: - fatal(MYNAME ": Subroute objects not supported in file sources\n"); - break; - case 0x4000: - if (global_opts.masked_objective & WPTDATAMASK) { - waypt_add(decode_waypoint(data)); - } - break; - default: - if (global_opts.masked_objective & TRKDATAMASK) { - if (track == NULL) { - track = route_head_alloc(); - track_add_head(track); - } - - track_add_wpt(track, decode_trackpoint(data)); - } - break; - } - } + unsigned char data[32]; + route_head *track = NULL; + + while (gbfread(data, sizeof(data), 1, file_handle) == 1) { + switch (le_read16(data)) { + case 0x2000: + fatal(MYNAME ": Route objects not supported in file sources\n"); + break; + case 0x2010: + fatal(MYNAME ": Subroute objects not supported in file sources\n"); + break; + case 0x4000: + if (global_opts.masked_objective & WPTDATAMASK) { + waypt_add(decode_waypoint(data)); + } + break; + default: + if (global_opts.masked_objective & TRKDATAMASK) { + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + + track_add_wpt(track, decode_trackpoint(data)); + } + break; + } + } } static void file_write_waypoint(const waypoint *waypt) { - unsigned char data[32]; + unsigned char data[32]; - encode_waypoint(waypt, data); - gbfwrite(data, sizeof(data), 1, file_handle); + encode_waypoint(waypt, data); + gbfwrite(data, sizeof(data), 1, file_handle); } static void file_write_track_start(const route_head *track) { - track_serial = 1; + track_serial = 1; } static void file_write_track_point(const waypoint *waypt) { - unsigned char data[32]; + unsigned char data[32]; - encode_trackpoint(waypt, track_serial++, data); - gbfwrite(data, sizeof(data), 1, file_handle); + encode_trackpoint(waypt, track_serial++, data); + gbfwrite(data, sizeof(data), 1, file_handle); } static void @@ -1000,7 +1019,7 @@ file_write_track_end(const route_head *track) static void file_write_route_start(const route_head *track) { - fatal(MYNAME ": Can't write routes to a file\n"); + fatal(MYNAME ": Can't write routes to a file\n"); } static void @@ -1016,214 +1035,215 @@ file_write_route_end(const route_head *track) static void nuke(void) { - if (nuketrk) { - unsigned char information[32]; - unsigned char data[7]; - - write_packet(PID_QRY_INFORMATION, NULL, 0); - read_packet(PID_DATA, information, - sizeof(information), sizeof(information), - FALSE); - - le_write32(data + 0, le_read32(information + 4)); - le_write16(data + 4, 0); - data[6] = 0; - - write_packet(PID_ERASE_TRACK, data, sizeof(data)); - read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); - } - - if (nukerte) { - unsigned char data[4]; - - le_write32(data, 0x00f00000); - write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data)); - if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { - fatal(MYNAME ": Could not nuke all routes.\n"); - } - } - - if (nukewpt) { - unsigned char data[4]; - - le_write32(data, 0x00f00000); - write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data)); - if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { - fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n"); - /* perhaps a better action would be to nuke routes for user. - * i.e. set nukerte when nukewpt is set */ - } - } - - if (nukedlg) { - write_packet(PID_CLEAR_DATALOG, NULL, 0); - /* The flash erase operation is time-consuming. Each sector (64KB) - * takes around 1 second. The total sectors for SBP is 10. - * So give the device some time to clear its datalog, in addition - * to SERIAL_TIMEOUT, which applies to read_packet() */ - gb_sleep(CLEAR_DATALOG_TIME * 1000); - read_packet(PID_ACK, NULL, 0, 0, FALSE); - } + if (nuketrk) { + unsigned char information[32]; + unsigned char data[7]; + + write_packet(PID_QRY_INFORMATION, NULL, 0); + read_packet(PID_DATA, information, + sizeof(information), sizeof(information), + FALSE); + + le_write32(data + 0, le_read32(information + 4)); + le_write16(data + 4, 0); + data[6] = 0; + + write_packet(PID_ERASE_TRACK, data, sizeof(data)); + read_packet(PID_CMD_OK, NULL, 0, 0, FALSE); + } + + if (nukerte) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_ROUTE, data, sizeof(data)); + if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { + fatal(MYNAME ": Could not nuke all routes.\n"); + } + } + + if (nukewpt) { + unsigned char data[4]; + + le_write32(data, 0x00f00000); + write_packet(PID_DEL_ALL_WAYPOINT, data, sizeof(data)); + if (!read_packet(PID_ACK, NULL, 0, 0, TRUE)) { + fatal(MYNAME ": You must nuke all routes before nuking waypoints.\n"); + /* perhaps a better action would be to nuke routes for user. + * i.e. set nukerte when nukewpt is set */ + } + } + + if (nukedlg) { + write_packet(PID_CLEAR_DATALOG, NULL, 0); + /* The flash erase operation is time-consuming. Each sector (64KB) + * takes around 1 second. The total sectors for SBP is 10. + * So give the device some time to clear its datalog, in addition + * to SERIAL_TIMEOUT, which applies to read_packet() */ + gb_sleep(CLEAR_DATALOG_TIME * 1000); + read_packet(PID_ACK, NULL, 0, 0, FALSE); + } } static void navilink_common_init(const char *name) { - if (gbser_is_serial(name)) { - if ((serial_handle = gbser_init(name)) == NULL) { - fatal(MYNAME ": Could not open serial port %s\n", name); - } - - if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) { - fatal(MYNAME ": Can't configure port\n"); - } - - write_packet(PID_SYNC, NULL, 0); - read_packet(PID_ACK, NULL, 0, 0, FALSE); - - /* nuke data before writing */ - if (operation == WRITING) - nuke(); - - write_waypoint = serial_write_waypoint; - write_track_start = serial_write_track_start; - write_track_point = serial_write_track_point; - write_track_end = serial_write_track_end; - write_route_start = serial_write_route_start; - write_route_point = serial_write_route_point; - write_route_end = serial_write_route_end; - } else { - char *mode = operation == READING ? "r" : "w+"; - file_handle = gbfopen(name, mode, MYNAME); - - write_waypoint = file_write_waypoint; - write_track_start = file_write_track_start; - write_track_point = file_write_track_point; - write_track_end = file_write_track_end; - write_route_start = file_write_route_start; - write_route_point = file_write_route_point; - write_route_end = file_write_route_end; - } - - return; + if (gbser_is_serial(name)) { + if ((serial_handle = gbser_init(name)) == NULL) { + fatal(MYNAME ": Could not open serial port %s\n", name); + } + + if (gbser_set_port(serial_handle, 115200, 8, 0, 1) != gbser_OK) { + fatal(MYNAME ": Can't configure port\n"); + } + + write_packet(PID_SYNC, NULL, 0); + read_packet(PID_ACK, NULL, 0, 0, FALSE); + + /* nuke data before writing */ + if (operation == WRITING) { + nuke(); + } + + write_waypoint = serial_write_waypoint; + write_track_start = serial_write_track_start; + write_track_point = serial_write_track_point; + write_track_end = serial_write_track_end; + write_route_start = serial_write_route_start; + write_route_point = serial_write_route_point; + write_route_end = serial_write_route_end; + } else { + char *mode = operation == READING ? "r" : "w+"; + file_handle = gbfopen(name, mode, MYNAME); + + write_waypoint = file_write_waypoint; + write_track_start = file_write_track_start; + write_track_point = file_write_track_point; + write_track_end = file_write_track_end; + write_route_start = file_write_route_start; + write_route_point = file_write_route_point; + write_route_end = file_write_route_end; + } + + return; } static void navilink_rd_init(const char *name) { - operation = READING; - navilink_common_init(name); + operation = READING; + navilink_common_init(name); } static void navilink_wr_init(const char *name) { - operation = WRITING; - navilink_common_init(name); + operation = WRITING; + navilink_common_init(name); } static void navilink_deinit(void) { - if (serial_handle) { - /* nuke data after reading */ - if (operation == READING) - nuke(); + if (serial_handle) { + /* nuke data after reading */ + if (operation == READING) { + nuke(); + } - if (poweroff) { - write_packet(PID_QUIT, NULL, 0); - } + if (poweroff) { + write_packet(PID_QUIT, NULL, 0); + } - gbser_deinit(serial_handle); - } + gbser_deinit(serial_handle); + } - if (file_handle) { - gbfclose(file_handle); - } + if (file_handle) { + gbfclose(file_handle); + } - return; + return; } static void navilink_read(void) { - if (datalog) { - if (global_opts.masked_objective & TRKDATAMASK) { - if (serial_handle) { - serial_read_datalog(); - } else if (file_handle) { - fatal(MYNAME ": Not supported. Use SBP format.\n"); - } - } - } else { - if (serial_handle) { - waypoint **waypts = NULL; - - if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) { - waypts = serial_read_waypoints(); - } - - if (global_opts.masked_objective & TRKDATAMASK) { - serial_read_track(); - } - - if (global_opts.masked_objective & RTEDATAMASK) { - serial_read_routes(waypts); - } - - if (waypts) { - free_waypoints(waypts); - } - } else if (file_handle) { - file_read(); - } - } + if (datalog) { + if (global_opts.masked_objective & TRKDATAMASK) { + if (serial_handle) { + serial_read_datalog(); + } else if (file_handle) { + fatal(MYNAME ": Not supported. Use SBP format.\n"); + } + } + } else { + if (serial_handle) { + waypoint **waypts = NULL; + + if (global_opts.masked_objective & (WPTDATAMASK|RTEDATAMASK)) { + waypts = serial_read_waypoints(); + } + + if (global_opts.masked_objective & TRKDATAMASK) { + serial_read_track(); + } + + if (global_opts.masked_objective & RTEDATAMASK) { + serial_read_routes(waypts); + } + + if (waypts) { + free_waypoints(waypts); + } + } else if (file_handle) { + file_read(); + } + } } static void navilink_write(void) { - if (datalog) { - fatal(MYNAME ": Writing to datalog not supported.\n"); - } - - switch (global_opts.objective) - { - case trkdata: - track_disp_all(write_track_start, - write_track_end, - write_track_point); - break; - case wptdata: - waypt_disp_all(write_waypoint); - break; - case rtedata: - if (serial_handle) { - route_waypts = serial_read_waypoints(); - } - route_disp_all(write_route_start, - write_route_end, - write_route_point); - if (route_waypts) { - free_waypoints(route_waypts); - route_waypts = NULL; - } - break; - default: - fatal(MYNAME ": Unknown objective.\n"); - } + if (datalog) { + fatal(MYNAME ": Writing to datalog not supported.\n"); + } + + switch (global_opts.objective) { + case trkdata: + track_disp_all(write_track_start, + write_track_end, + write_track_point); + break; + case wptdata: + waypt_disp_all(write_waypoint); + break; + case rtedata: + if (serial_handle) { + route_waypts = serial_read_waypoints(); + } + route_disp_all(write_route_start, + write_route_end, + write_route_point); + if (route_waypts) { + free_waypoints(route_waypts); + route_waypts = NULL; + } + break; + default: + fatal(MYNAME ": Unknown objective.\n"); + } } ff_vecs_t navilink_vecs = { - ff_type_serial, - FF_CAP_RW_ALL, - navilink_rd_init, - navilink_wr_init, - navilink_deinit, - navilink_deinit, - navilink_read, - navilink_write, - NULL, - navilink_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_serial, + FF_CAP_RW_ALL, + navilink_rd_init, + navilink_wr_init, + navilink_deinit, + navilink_deinit, + navilink_read, + navilink_write, + NULL, + navilink_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/navilink.h b/gpsbabel/navilink.h index d74eaaee4..58cf06002 100644 --- a/gpsbabel/navilink.h +++ b/gpsbabel/navilink.h @@ -39,8 +39,7 @@ int locosys_decode_file_id(char *header, size_t len); #ifdef THIS_IS_ONLY_FOR_REFERENCE /* Locosys SBP and SBN structures */ -typedef __packed struct -{ +typedef __packed struct { UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ @@ -54,13 +53,12 @@ typedef __packed struct INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ UINT8 bitFlags; /* bitFlags, default 0x00, bit 0=1 indicate the first point after power on */ UINT8 reserved; -} T_SBP; +} T_SBP; -typedef struct __packed -{ - UINT8 Mid; - UINT16 Valid; - UINT16 Mode; /* Nav Mode: bit map as follows: +typedef struct __packed { + UINT8 Mid; + UINT16 Valid; + UINT16 Mode; /* Nav Mode: bit map as follows: * Bits 2-0: GPS Fix Type * 000 = No Nav * 001 = 1 SV solution @@ -93,45 +91,45 @@ typedef struct __packed * 10 = DR sensor error * 11 = DR Test mode */ - UINT16 Week; /* Extended Week Number */ - UINT32 TOW; /* Time of Week [0 to 604800] in seconds with resolution 0.001 */ - UINT16 UtcYr; /* UTC Year [1980 to 3000] */ - UINT8 UtcMth; /* UTC Month [1 to 12] */ - UINT8 UtcDay; /* UTC Day [1 to 31] */ - UINT8 UtcHr; /* UTC Hour [0 to 23] */ - UINT8 UtcMin; /* UTC Minute [0 to 59] */ - UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ - UINT32 SVIDList; /* SVs in solution: Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */ - - INT32 Lat; /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */ - INT32 Lon; /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */ - INT32 AltE; /* Altitude from Ellipsoid in meters with resolution 0.01 */ - INT32 AltM; /* Altitude from Mean Sea Level in meters with resolution 0.01 */ - UINT8 Datum; /* Map datum */ - UINT16 Sog; /* Speed Over Ground in m/sec with resolution 0.01 */ - UINT16 Cog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */ - INT16 MagVar; /* Magnetic Variation - Reserved */ - INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ - INT16 HdRte; /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */ - UINT32 Ehpe; /* Expected Horizontal Position Error in meters with resolution 0.01 */ - UINT32 Evpe; /* Expected Horizontal Vertical Error in meters with resolution 0.01 */ - UINT32 Ete; /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */ - UINT16 Ehve; /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */ - INT32 ClkBias; /* Clock Bias in meters with resolution 0.01 */ - UINT32 ClkBiasE; /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */ - INT32 ClkDrift; /* Clock Drift in m/sec with resolution 0.01 */ - UINT32 ClkDriftE; /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */ - UINT32 Trvled; /* Distance Traveled since reset in meters (SiRFDrive only) */ - UINT16 TrvledE; /* Distance Traveled Error in meters (SiRFDrive only) */ - UINT16 HdE; /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */ - UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ - UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ - UINT8 Reserved; /* Reserved */ - - UINT16 ufSog; /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/ - UINT16 ufCog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered */ - -} T_SBN_REC; + UINT16 Week; /* Extended Week Number */ + UINT32 TOW; /* Time of Week [0 to 604800] in seconds with resolution 0.001 */ + UINT16 UtcYr; /* UTC Year [1980 to 3000] */ + UINT8 UtcMth; /* UTC Month [1 to 12] */ + UINT8 UtcDay; /* UTC Day [1 to 31] */ + UINT8 UtcHr; /* UTC Hour [0 to 23] */ + UINT8 UtcMin; /* UTC Minute [0 to 59] */ + UINT16 UtcSec; /* UTC Second [0 to 59] in seconds with resolution 0.001 */ + UINT32 SVIDList; /* SVs in solution: Bit 0=1: SV1, Bit 1=1: SV2, ... , Bit 31=1: SV32 */ + + INT32 Lat; /* Latitude [-90 to 90] in degrees with resolution 0.0000001 */ + INT32 Lon; /* Longitude [-180 to 180] in degrees with resolution 0.0000001 */ + INT32 AltE; /* Altitude from Ellipsoid in meters with resolution 0.01 */ + INT32 AltM; /* Altitude from Mean Sea Level in meters with resolution 0.01 */ + UINT8 Datum; /* Map datum */ + UINT16 Sog; /* Speed Over Ground in m/sec with resolution 0.01 */ + UINT16 Cog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01 */ + INT16 MagVar; /* Magnetic Variation - Reserved */ + INT16 ClmbRte; /* Climb rate in m/sec with resolution 0.01 */ + INT16 HdRte; /* Heading Rate in deg/sec with resolution 0.01 (SiRFDrive only) */ + UINT32 Ehpe; /* Expected Horizontal Position Error in meters with resolution 0.01 */ + UINT32 Evpe; /* Expected Horizontal Vertical Error in meters with resolution 0.01 */ + UINT32 Ete; /* Expected Time Error in meters with resolution 0.01 (SiRFDrive only) - Reserved */ + UINT16 Ehve; /* Expected Horizontal Velocity Error in m/sec with resolution 0.01 (SiRFDrive only) */ + INT32 ClkBias; /* Clock Bias in meters with resolution 0.01 */ + UINT32 ClkBiasE; /* Clock Bias Error in meters with resolution 0.01 (SiRFDrive only) */ + INT32 ClkDrift; /* Clock Drift in m/sec with resolution 0.01 */ + UINT32 ClkDriftE; /* Clock Drift in m/sec with resolution 0.01 (SiRFDrive only) */ + UINT32 Trvled; /* Distance Traveled since reset in meters (SiRFDrive only) */ + UINT16 TrvledE; /* Distance Traveled Error in meters (SiRFDrive only) */ + UINT16 HdE; /* Heading Error [0 to 180] in degrees with resolution 0.01 (SiRFDrive only) */ + UINT8 SVIDCnt; /* Number of SVs in solution [0 to 12] */ + UINT8 HDOP; /* HDOP [0..51] with resolution 0.2 */ + UINT8 Reserved; /* Reserved */ + + UINT16 ufSog; /* Speed Over Ground in m/sec with resolution 0.01 ,unfiltered*/ + UINT16 ufCog; /* Course Over Ground [0 to 360] in degrees with resolution 0.01, unfiltered */ + +} T_SBN_REC; #endif diff --git a/gpsbabel/navitel.c b/gpsbabel/navitel.c index 7b82d5c80..32d625263 100644 --- a/gpsbabel/navitel.c +++ b/gpsbabel/navitel.c @@ -37,117 +37,117 @@ static int trkpts; static void navitel_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } static void navitel_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void navitel_read_track(void) { - int points, i; - route_head *trk = NULL; + int points, i; + route_head *trk = NULL; - points = gbfgetint32(fin); - (void) gbfgetint32(fin); /* unknown */ + points = gbfgetint32(fin); + (void) gbfgetint32(fin); /* unknown */ - for (i = 0; i < points; i++) { - int lat, lon; - waypoint *wpt; + for (i = 0; i < points; i++) { + int lat, lon; + waypoint *wpt; - lon = gbfgetint32(fin); - lat = gbfgetint32(fin); + lon = gbfgetint32(fin); + lat = gbfgetint32(fin); - wpt = waypt_new(); - wpt->latitude = GPS_Math_Semi_To_Deg(lat & 0x7FFFFFFF); - wpt->longitude = GPS_Math_Semi_To_Deg(lon); + wpt = waypt_new(); + wpt->latitude = GPS_Math_Semi_To_Deg(lat & 0x7FFFFFFF); + wpt->longitude = GPS_Math_Semi_To_Deg(lon); - if ((lat >> 31) || (trk == NULL)) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - } + if ((lat >> 31) || (trk == NULL)) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + } } static void navitel_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void navitel_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void navitel_enum_trkpts(const waypoint *wpt) { - trkpts++; + trkpts++; } static void navitel_disp_trk_head(const route_head *trk) { - new_track = 1; + new_track = 1; } static void navitel_disp_trkpts(const waypoint *wpt) { - int lat, lon; + int lat, lon; - lat = GPS_Math_Deg_To_Semi(wpt->latitude); - lon = GPS_Math_Deg_To_Semi(wpt->longitude); + lat = GPS_Math_Deg_To_Semi(wpt->latitude); + lon = GPS_Math_Deg_To_Semi(wpt->longitude); - if (new_track) { - lat |= (1 << 31); - new_track = 0; - } + if (new_track) { + lat |= (1 << 31); + new_track = 0; + } - gbfputint32(lon, fout); - gbfputint32(lat, fout); + gbfputint32(lon, fout); + gbfputint32(lat, fout); } static void navitel_write_track(void) { - trkpts = 0; - track_disp_all(NULL, NULL, navitel_enum_trkpts); - if (trkpts > 10000) { - trkpts = 10000; - warning(MYNAME ": Can store only 10000 points per file!\n"); - } - - gbfputint32(trkpts, fout); - gbfputint32(1, fout); /* ? */ - track_disp_all(navitel_disp_trk_head, NULL, navitel_disp_trkpts); + trkpts = 0; + track_disp_all(NULL, NULL, navitel_enum_trkpts); + if (trkpts > 10000) { + trkpts = 10000; + warning(MYNAME ": Can store only 10000 points per file!\n"); + } + + gbfputint32(trkpts, fout); + gbfputint32(1, fout); /* ? */ + track_disp_all(navitel_disp_trk_head, NULL, navitel_disp_trkpts); } /**************************************************************************/ ff_vecs_t navitel_trk_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - navitel_rd_init, - navitel_wr_init, - navitel_rd_deinit, - navitel_wr_deinit, - navitel_read_track, - navitel_write_track, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* Nothing to convert */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + navitel_rd_init, + navitel_wr_init, + navitel_rd_deinit, + navitel_wr_deinit, + navitel_read_track, + navitel_write_track, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* Nothing to convert */ }; /**************************************************************************/ diff --git a/gpsbabel/netstumbler.c b/gpsbabel/netstumbler.c index be29aca03..43c84bb93 100644 --- a/gpsbabel/netstumbler.c +++ b/gpsbabel/netstumbler.c @@ -38,228 +38,247 @@ static void fix_netstumbler_dupes(void); static arglist_t netstumbler_args[] = { - {"nseicon", &nseicon, "Non-stealth encrypted icon name", - "Red Square", ARGTYPE_STRING, ARG_NOMINMAX }, - {"nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", - "Green Square", ARGTYPE_STRING, ARG_NOMINMAX }, - {"seicon", &seicon, "Stealth encrypted icon name", - "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, - {"sneicon", &sneicon, "Stealth non-encrypted icon name", - "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX }, - {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, - ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nseicon", &nseicon, "Non-stealth encrypted icon name", + "Red Square", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "nsneicon", &nsneicon, "Non-stealth non-encrypted icon name", + "Green Square", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "seicon", &seicon, "Stealth encrypted icon name", + "Red Diamond", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "sneicon", &sneicon, "Stealth non-encrypted icon name", + "Green Diamond", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL, + ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); - macstumbler = 0; + file_in = gbfopen(fname, "rb", MYNAME); + macstumbler = 0; } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void data_read(void) { - char *ibuf; - char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ - char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ - char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ - double lat = 0, lon = 0; - waypoint *wpt_tmp; - int line_no = 0; - int stealth_num = 0, whitespace_num = 0; - long flags = 0; - int speed = 0, channel = 0; - struct tm tm; - int line = 0; - - memset(&tm, 0, sizeof(tm)); - - while ((ibuf = gbfgetstr(file_in))) { - char *field; - int field_num, len, i, stealth = 0; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - ibuf = lrtrim(ibuf); - /* A sharp in column zero might be a comment. Or it might be - * something useful, like the date. - */ - - if (ibuf[0] == '#') { - if (strncmp(&ibuf[2], "$DateGMT:", 9) == 0) { - tm.tm_year = atoi(&ibuf[12]) - 1900; - tm.tm_mon = atoi(&ibuf[17]) - 1; - tm.tm_mday = atoi(&ibuf[20]); - } - - /* - * Mac stumbler files are the same, except - * use DDMM.mmm instad of DD.DDDD. - */ - if (strstr(ibuf, "Creator: MacStumbler")) { - macstumbler = 1; - } - - continue; - } - - field_num = 0; - line_no++; - field = csv_lineparse(ibuf, "\t", "", line_no); - - while (field) { - switch (field_num) { - case 0: /* lat */ - lat = atof(&field[2]); - if (field[0] == 'S') - lat = -lat; - if (macstumbler) { - lat = ddmm2degrees(lat); - } - break; - - case 1: /* long */ - lon = atof(&field[2]); - if (field[0] == 'W') - lon = -lon; - if (macstumbler) { - lon = ddmm2degrees(lon); - } - break; - - case 2: /* ( SSID ) */ - strcpy(ssid, &field[2]); /* zap "( " */ - len = strlen(ssid) - 2; - ssid[len] = 0; /* zap " )" */ - stealth = (len == 0); - /* don't alter SSID in snmac mode */ - if (!snmac) { - int found = 0; - /* check for all whitespace */ - for (i = 0; i < len && !found; i++) { - if (!isspace(ssid[i])) - found = 1; - } - - if (!stealth && !found) - snprintf(ssid, sizeof ssid, "Whitespace/%d", ++whitespace_num); - } - break; - - case 4: /* ( MAC address ) */ - strcpy(mac, &field[2]); /* zap "( " */ - mac[strlen(mac) - 2] = 0;/* zap " )" */ - break; - - case 5: /* time */ - tm.tm_hour = atoi(field); - tm.tm_min = atoi(&field[3]); - tm.tm_sec = atoi(&field[6]); - break; - - case 8: /* flags */ - flags = strtol(field, NULL, 16); - break; - - case 11: /* data rate */ - speed = atoi(field) / 10; - break; - - case 12: /* last channel */ - channel = atoi(field); - break; - - case 3: /* type */ - case 6: /* SNR/sig/noise */ - case 7: /* name */ - case 9: /* channel bits */ - case 10: /* beacon interval */ - default: - break; - } - - field_num++; - field = csv_lineparse(NULL, "\t", "", line_no); - } - - if (lat == 0 && lon == 0) /* skip records with no GPS data */ - continue; - - wpt_tmp = waypt_new(); - - if (stealth) { - if (!snmac) - snprintf(ssid, sizeof ssid, "Stealth/%d", ++stealth_num); - - if (flags & 0x0010) /* encrypted? */ - wpt_tmp->icon_descr = seicon; - else - wpt_tmp->icon_descr = sneicon; - } else { - if (flags & 0x0010) /* encrypted? */ - wpt_tmp->icon_descr = nseicon; - else - wpt_tmp->icon_descr = nsneicon; - } - - if (snmac) { - snprintf(desc, sizeof desc, "%s/%d Mbps/Ch %d", ssid, speed, channel); - wpt_tmp->shortname = xstrdup(mac); - } else { - snprintf(desc, sizeof desc, "%d Mbps/Ch %d/%s", speed, channel, mac); - wpt_tmp->shortname = xstrdup(ssid); - } - - wpt_tmp->description = xstrdup(desc); - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - wpt_tmp->creation_time = mktime(&tm); - - waypt_add(wpt_tmp); - } - fix_netstumbler_dupes(); + char *ibuf; + char ssid[2 + 32 + 2 + 1]; /* "( " + SSID + " )" + null */ + char mac[2 + 17 + 2 + 1]; /* "( " + MAC + " )" + null */ + char desc[sizeof ssid - 1 + 15 + 1]; /* room for channel/speed */ + double lat = 0, lon = 0; + waypoint *wpt_tmp; + int line_no = 0; + int stealth_num = 0, whitespace_num = 0; + long flags = 0; + int speed = 0, channel = 0; + struct tm tm; + int line = 0; + + memset(&tm, 0, sizeof(tm)); + + while ((ibuf = gbfgetstr(file_in))) { + char *field; + int field_num, len, i, stealth = 0; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + ibuf = lrtrim(ibuf); + /* A sharp in column zero might be a comment. Or it might be + * something useful, like the date. + */ + + if (ibuf[0] == '#') { + if (strncmp(&ibuf[2], "$DateGMT:", 9) == 0) { + tm.tm_year = atoi(&ibuf[12]) - 1900; + tm.tm_mon = atoi(&ibuf[17]) - 1; + tm.tm_mday = atoi(&ibuf[20]); + } + + /* + * Mac stumbler files are the same, except + * use DDMM.mmm instad of DD.DDDD. + */ + if (strstr(ibuf, "Creator: MacStumbler")) { + macstumbler = 1; + } + + continue; + } + + field_num = 0; + line_no++; + field = csv_lineparse(ibuf, "\t", "", line_no); + + while (field) { + switch (field_num) { + case 0: /* lat */ + lat = atof(&field[2]); + if (field[0] == 'S') { + lat = -lat; + } + if (macstumbler) { + lat = ddmm2degrees(lat); + } + break; + + case 1: /* long */ + lon = atof(&field[2]); + if (field[0] == 'W') { + lon = -lon; + } + if (macstumbler) { + lon = ddmm2degrees(lon); + } + break; + + case 2: /* ( SSID ) */ + strcpy(ssid, &field[2]); /* zap "( " */ + len = strlen(ssid) - 2; + ssid[len] = 0; /* zap " )" */ + stealth = (len == 0); + /* don't alter SSID in snmac mode */ + if (!snmac) { + int found = 0; + /* check for all whitespace */ + for (i = 0; i < len && !found; i++) { + if (!isspace(ssid[i])) { + found = 1; + } + } + + if (!stealth && !found) { + snprintf(ssid, sizeof ssid, "Whitespace/%d", ++whitespace_num); + } + } + break; + + case 4: /* ( MAC address ) */ + strcpy(mac, &field[2]); /* zap "( " */ + mac[strlen(mac) - 2] = 0;/* zap " )" */ + break; + + case 5: /* time */ + tm.tm_hour = atoi(field); + tm.tm_min = atoi(&field[3]); + tm.tm_sec = atoi(&field[6]); + break; + + case 8: /* flags */ + flags = strtol(field, NULL, 16); + break; + + case 11: /* data rate */ + speed = atoi(field) / 10; + break; + + case 12: /* last channel */ + channel = atoi(field); + break; + + case 3: /* type */ + case 6: /* SNR/sig/noise */ + case 7: /* name */ + case 9: /* channel bits */ + case 10: /* beacon interval */ + default: + break; + } + + field_num++; + field = csv_lineparse(NULL, "\t", "", line_no); + } + + if (lat == 0 && lon == 0) { /* skip records with no GPS data */ + continue; + } + + wpt_tmp = waypt_new(); + + if (stealth) { + if (!snmac) { + snprintf(ssid, sizeof ssid, "Stealth/%d", ++stealth_num); + } + + if (flags & 0x0010) { /* encrypted? */ + wpt_tmp->icon_descr = seicon; + } else { + wpt_tmp->icon_descr = sneicon; + } + } else { + if (flags & 0x0010) { /* encrypted? */ + wpt_tmp->icon_descr = nseicon; + } else { + wpt_tmp->icon_descr = nsneicon; + } + } + + if (snmac) { + snprintf(desc, sizeof desc, "%s/%d Mbps/Ch %d", ssid, speed, channel); + wpt_tmp->shortname = xstrdup(mac); + } else { + snprintf(desc, sizeof desc, "%d Mbps/Ch %d/%s", speed, channel, mac); + wpt_tmp->shortname = xstrdup(ssid); + } + + wpt_tmp->description = xstrdup(desc); + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + wpt_tmp->creation_time = mktime(&tm); + + waypt_add(wpt_tmp); + } + fix_netstumbler_dupes(); } -typedef struct -{ - unsigned long crc; - waypoint *wpt; +typedef struct { + unsigned long crc; + waypoint *wpt; } htable_t; static int compare(const void *a, const void *b) { - unsigned long crc_a = ((const htable_t *)a)->crc; - unsigned long crc_b = ((const htable_t *)b)->crc; - - /* we can't just return crc_a - crc_b because the return type is - * signed. - * */ - - if (crc_a < crc_b) - return -1; - else if (crc_a > crc_b) - return 1; - else { - /* CRCs are equal; we need to subsort on the description (which - * includes the MAC address) to guarantee the same ordering of - * the output for any qsort() implementation. this is strictly - * to make the testo script happy. - * */ - - waypoint *wpt_a = ((const htable_t *)a)->wpt; - waypoint *wpt_b = ((const htable_t *)b)->wpt; - - return strcmp(wpt_a->description, wpt_b->description); - } + unsigned long crc_a = ((const htable_t *)a)->crc; + unsigned long crc_b = ((const htable_t *)b)->crc; + + /* we can't just return crc_a - crc_b because the return type is + * signed. + * */ + + if (crc_a < crc_b) { + return -1; + } else if (crc_a > crc_b) { + return 1; + } else { + /* CRCs are equal; we need to subsort on the description (which + * includes the MAC address) to guarantee the same ordering of + * the output for any qsort() implementation. this is strictly + * to make the testo script happy. + * */ + + waypoint *wpt_a = ((const htable_t *)a)->wpt; + waypoint *wpt_b = ((const htable_t *)b)->wpt; + + return strcmp(wpt_a->description, wpt_b->description); + } } /* netstumbler data will have a lot of duplicate shortnames if the SSID @@ -271,55 +290,56 @@ static void fix_netstumbler_dupes(void) { - int i, ct = waypt_count(), serial = 0; - htable_t *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - const char *snptr; - char *tmp_sn; - unsigned long last_crc; - char ssid[32 + 5 + 1]; - - htable = (htable_t *) xmalloc(ct * sizeof *htable); - bh = htable; - - i = 0; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - bh->wpt = (waypoint *) elem; - snptr = bh->wpt->shortname; - tmp_sn = strlower(xstrdup(snptr)); - bh->crc = get_crc32(tmp_sn, strlen(snptr)); - xfree(tmp_sn); - i ++; - bh ++; - } - - qsort(htable, ct, sizeof *htable, compare); - - last_crc = htable[0].crc + 1; /* force mismatch */ - - for (i = 0, bh = htable; i < ct; i++, bh++) { - if (last_crc == bh->crc) { - snprintf(ssid, sizeof ssid, "%s/%d", bh->wpt->shortname, ++serial); - xfree(bh->wpt->shortname); - bh->wpt->shortname = xstrdup(ssid); - } else - last_crc = bh->crc; - } - - xfree(htable); + int i, ct = waypt_count(), serial = 0; + htable_t *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + const char *snptr; + char *tmp_sn; + unsigned long last_crc; + char ssid[32 + 5 + 1]; + + htable = (htable_t *) xmalloc(ct * sizeof *htable); + bh = htable; + + i = 0; + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + bh->wpt = (waypoint *) elem; + snptr = bh->wpt->shortname; + tmp_sn = strlower(xstrdup(snptr)); + bh->crc = get_crc32(tmp_sn, strlen(snptr)); + xfree(tmp_sn); + i ++; + bh ++; + } + + qsort(htable, ct, sizeof *htable, compare); + + last_crc = htable[0].crc + 1; /* force mismatch */ + + for (i = 0, bh = htable; i < ct; i++, bh++) { + if (last_crc == bh->crc) { + snprintf(ssid, sizeof ssid, "%s/%d", bh->wpt->shortname, ++serial); + xfree(bh->wpt->shortname); + bh->wpt->shortname = xstrdup(ssid); + } else { + last_crc = bh->crc; + } + } + + xfree(htable); } ff_vecs_t netstumbler_vecs = { - ff_type_file, - { ff_cap_read, ff_cap_none, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - netstumbler_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read, ff_cap_none, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + netstumbler_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/nmea.c b/gpsbabel/nmea.c index a3bac09b5..18e608a8e 100644 --- a/gpsbabel/nmea.c +++ b/gpsbabel/nmea.c @@ -107,12 +107,12 @@ ****************************************/ /* - * An input file may have both GGA and GLL and RMC sentences for the exact + * An input file may have both GGA and GLL and RMC sentences for the exact * same position fix. If we see a single GGA, start ignoring GLL's and RMC's. * GLL's will also be ignored if RMC's are found and GGA's not found. */ -/* +/* Zmarties notes: In practice, all fields of the NMEA sentences should be treated as optional - @@ -135,16 +135,16 @@ sentence is truncated - and missing part of the line, including the checksum. */ typedef enum { - gp_unknown = 0, - gpgga, - gplgll, - gprmc + gp_unknown = 0, + gpgga, + gplgll, + gprmc } preferred_posn_type; enum { - rm_unknown = 0, - rm_serial, - rm_file + rm_unknown = 0, + rm_serial, + rm_file } read_mode; static gbfile *file_in, *file_out; @@ -189,19 +189,21 @@ static waypoint * nmea_rd_posn(posn_status *); static void nmea_rd_posn_init(const char *fname); arglist_t nmea_args[] = { - {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, - {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "get_posn", &getposnarg, "Return current position as a waypoint", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, - {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + {"snlen", &snlenopt, "Max length of waypoint name to write", "6", ARGTYPE_INT, "1", "64" }, + {"gprmc", &opt_gprmc, "Read/write GPRMC sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgga", &opt_gpgga, "Read/write GPGGA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpvtg", &opt_gpvtg, "Read/write GPVTG sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"gpgsa", &opt_gpgsa, "Read/write GPGSA sentences", "1", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"date", &optdate, "Complete date-free tracks with given date (YYYYMMDD).", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + { + "get_posn", &getposnarg, "Return current position as a waypoint", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + {"pause", &opt_sleep, "Decimal seconds to pause between groups of strings", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"append_positioning", &opt_append, "Append realtime positioning data to the output file instead of truncating", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + {"baud", &opt_baud, "Speed in bits per second of serial port (baud=4800)", NULL, ARGTYPE_INT, ARG_NOMINMAX }, + {"gisteq", &opt_gisteq, "Write tracks for Gisteq Phototracker", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define CHECK_BOOL(a) if (a && (*a == '0')) a = NULL @@ -212,1153 +214,1169 @@ arglist_t nmea_args[] = { int nmea_cksum(const char *const buf) { - int x = 0 ; - const char *p; + int x = 0 ; + const char *p; - for (p = buf; *p; p++) { - x ^= *p; - } - return x; + for (p = buf; *p; p++) { + x ^= *p; + } + return x; } static void nmea_add_wpt(waypoint *wpt, route_head *trk) { - if (datum != DATUM_WGS84) { - double lat, lon, alt; - GPS_Math_Known_Datum_To_WGS84_M( - wpt->latitude, wpt->longitude, 0, - &lat, &lon, &alt, datum); - wpt->latitude = lat; - wpt->longitude = lon; - } - if (trk != NULL) track_add_wpt(trk, wpt); - else waypt_add(wpt); + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M( + wpt->latitude, wpt->longitude, 0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } + if (trk != NULL) { + track_add_wpt(trk, wpt); + } else { + waypt_add(wpt); + } } static void nmea_release_wpt(waypoint *wpt) { - if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) { - /* This waypoint isn't queued. - Release it, because we don't have any reference to this - waypoint (! memory leak !) */ - waypt_free(wpt); - } + if (wpt && ((wpt->Q.next == NULL) || (wpt->Q.next == &wpt->Q))) { + /* This waypoint isn't queued. + Release it, because we don't have any reference to this + waypoint (! memory leak !) */ + waypt_free(wpt); + } } static void nmea_rd_init(const char *fname) { - curr_waypt = NULL; - last_waypt = NULL; - last_time = -1; - datum = DATUM_WGS84; - had_checksum = 0; - - CHECK_BOOL(opt_gprmc); - CHECK_BOOL(opt_gpgga); - CHECK_BOOL(opt_gpvtg); - CHECK_BOOL(opt_gpgsa); - CHECK_BOOL(opt_gisteq); - - QUEUE_INIT(&pcmpt_head); - - if (getposnarg) { - getposn = 1; - } - - /* A special case hack that gets our current position and returns - * it as one waypoint. - */ - if (getposn) { - waypoint *wpt; - posn_status st; - nmea_rd_posn_init(fname); - wpt = nmea_rd_posn(&st); - if (!wpt) { - return; - } - if (wpt->shortname) { - xfree(wpt->shortname); - } - wpt->shortname = xstrdup("Position"); - nmea_add_wpt(wpt, NULL); - return; - } - - read_mode = rm_file; - file_in = gbfopen(fname, "rb", MYNAME); + curr_waypt = NULL; + last_waypt = NULL; + last_time = -1; + datum = DATUM_WGS84; + had_checksum = 0; + + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + CHECK_BOOL(opt_gisteq); + + QUEUE_INIT(&pcmpt_head); + + if (getposnarg) { + getposn = 1; + } + + /* A special case hack that gets our current position and returns + * it as one waypoint. + */ + if (getposn) { + waypoint *wpt; + posn_status st; + nmea_rd_posn_init(fname); + wpt = nmea_rd_posn(&st); + if (!wpt) { + return; + } + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("Position"); + nmea_add_wpt(wpt, NULL); + return; + } + + read_mode = rm_file; + file_in = gbfopen(fname, "rb", MYNAME); } static void nmea_rd_deinit(void) { - switch(read_mode) { - case rm_serial: - gbser_deinit(gbser_handle); - break; - case rm_file: - gbfclose(file_in); - file_in = NULL; - break; - default: - fatal("nmea_rd_deinit: illegal read_mode.\n"); - break; - } + switch (read_mode) { + case rm_serial: + gbser_deinit(gbser_handle); + break; + case rm_file: + gbfclose(file_in); + file_in = NULL; + break; + default: + fatal("nmea_rd_deinit: illegal read_mode.\n"); + break; + } } static void nmea_wr_init(const char *portname) { - CHECK_BOOL(opt_gprmc); - CHECK_BOOL(opt_gpgga); - CHECK_BOOL(opt_gpvtg); - CHECK_BOOL(opt_gpgsa); - CHECK_BOOL(opt_gisteq); - - append_output = atoi(opt_append); - - file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME); - - sleepus = -1; - if ( opt_sleep ) { - if ( *opt_sleep ) { - sleepus = 1e6 * atof(opt_sleep); - } - else { - sleepus = -1; - } - } - - mkshort_handle = (struct short_handle*) mkshort_new_handle(); - setshort_length(mkshort_handle, atoi(snlenopt)); - - if (opt_gisteq) { - opt_gpgga = NULL; - opt_gpvtg = NULL; - opt_gpgsa = NULL; - } + CHECK_BOOL(opt_gprmc); + CHECK_BOOL(opt_gpgga); + CHECK_BOOL(opt_gpvtg); + CHECK_BOOL(opt_gpgsa); + CHECK_BOOL(opt_gisteq); + + append_output = atoi(opt_append); + + file_out = gbfopen(portname, append_output ? "a+" : "w+", MYNAME); + + sleepus = -1; + if (opt_sleep) { + if (*opt_sleep) { + sleepus = 1e6 * atof(opt_sleep); + } else { + sleepus = -1; + } + } + + mkshort_handle = (struct short_handle*) mkshort_new_handle(); + setshort_length(mkshort_handle, atoi(snlenopt)); + + if (opt_gisteq) { + opt_gpgga = NULL; + opt_gpvtg = NULL; + opt_gpgsa = NULL; + } } static void nmea_wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } static void nmea_set_waypoint_time(waypoint *wpt, struct tm *time, int microseconds) { - if (time->tm_year == 0) - { - wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use == 0) - { - wpt->wpt_flags.fmt_use = 1; - without_date++; - } - } - else - { - wpt->creation_time = mkgmtime(time); - wpt->microseconds = microseconds; - if (wpt->wpt_flags.fmt_use != 0) - { - wpt->wpt_flags.fmt_use = 0; - without_date--; - } - } + if (time->tm_year == 0) { + wpt->creation_time = ((((time_t)time->tm_hour * 60) + time->tm_min) * 60) + time->tm_sec; + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use == 0) { + wpt->wpt_flags.fmt_use = 1; + without_date++; + } + } else { + wpt->creation_time = mkgmtime(time); + wpt->microseconds = microseconds; + if (wpt->wpt_flags.fmt_use != 0) { + wpt->wpt_flags.fmt_use = 0; + without_date--; + } + } } static void gpgll_parse(char *ibuf) { - double latdeg, lngdeg, microseconds; - char lngdir, latdir; - double hmsd; - int hms; - char valid = 0; - waypoint *waypt; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%lf,%c,", - &latdeg,&latdir, - &lngdeg,&lngdir, - &hmsd,&valid); - - if (valid != 'A') - return; - - hms = (int) hmsd; - microseconds = MILLI_TO_MICRO(1000 * (hmsd - hms)); - - tm.tm_sec = hms % 100; - hms = hms / 100; - tm.tm_min = hms % 100; - hms = hms / 100; - tm.tm_hour = hms % 100; - - last_read_time = hms; - - waypt = waypt_new(); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; + double latdeg, lngdeg, microseconds; + char lngdir, latdir; + double hmsd; + int hms; + char valid = 0; + waypoint *waypt; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGLL,%lf,%c,%lf,%c,%lf,%c,", + &latdeg,&latdir, + &lngdeg,&lngdir, + &hmsd,&valid); + + if (valid != 'A') { + return; + } + + hms = (int) hmsd; + microseconds = MILLI_TO_MICRO(1000 * (hmsd - hms)); + + tm.tm_sec = hms % 100; + hms = hms / 100; + tm.tm_min = hms % 100; + hms = hms / 100; + tm.tm_hour = hms % 100; + + last_read_time = hms; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; } static void gpgga_parse(char *ibuf) { - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - double alt; - int fix = fix_unknown; - int nsats = 0; - double hdop; - char altunits; - waypoint *waypt; - double microseconds; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", - &hms, &latdeg,&latdir, - &lngdeg,&lngdir, - &fix,&nsats,&hdop,&alt,&altunits); - - /* - * In serial mode, allow the fix with an invalid position through - * as serial units will often spit a remembered position up and - * that is more comfortable than nothing at all... - */ - if ((fix <= 0) && (read_mode != rm_serial)) { - return; - } - - last_read_time = hms; - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - waypt = waypt_new(); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->altitude = alt; - - waypt->sat = nsats; - - waypt->hdop = hdop; - - switch (fix) { - case 0: - waypt->fix = fix_none; - break; - case 1: - waypt->fix = (nsats>3)?(fix_3d):(fix_2d); - break; - case 2: - waypt->fix = fix_dgps; - break; - case 3: - waypt->fix = fix_pps; - break; - } - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + double alt; + int fix = fix_unknown; + int nsats = 0; + double hdop; + char altunits; + waypoint *waypt; + double microseconds; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + sscanf(ibuf,"$GPGGA,%lf,%lf,%c,%lf,%c,%d,%d,%lf,%lf,%c", + &hms, &latdeg,&latdir, + &lngdeg,&lngdir, + &fix,&nsats,&hdop,&alt,&altunits); + + /* + * In serial mode, allow the fix with an invalid position through + * as serial units will often spit a remembered position up and + * that is more comfortable than nothing at all... + */ + if ((fix <= 0) && (read_mode != rm_serial)) { + return; + } + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + waypt = waypt_new(); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->altitude = alt; + + waypt->sat = nsats; + + waypt->hdop = hdop; + + switch (fix) { + case 0: + waypt->fix = fix_none; + break; + case 1: + waypt->fix = (nsats>3)?(fix_3d):(fix_2d); + break; + case 2: + waypt->fix = fix_dgps; + break; + case 3: + waypt->fix = fix_pps; + break; + } + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; } static void gprmc_parse(char *ibuf) { - double latdeg, lngdeg; - char lngdir, latdir; - double hms; - char fix; - unsigned int dmy; - double speed,course; - waypoint *waypt; - double microseconds; - char *dmybuf; - int i; - - if (trk_head == NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - } - - /* - * Read everything except the dmy, in case lngdeg - * and lngdir are missing. - */ - sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf", - &hms, &fix, &latdeg, &latdir, - &lngdeg, &lngdir, - &speed, &course); - - if (fix != 'A') { - /* ignore this fix - it is invalid */ - return; - } - - /* Skip past nine commas in ibuf to reach the dmy value */ - for (dmybuf=ibuf,i=0; i<9; i++) { - dmybuf= strchr(dmybuf, ','); - if(dmybuf==NULL) { - /* If we run out of commas, the sentence is invalid. */ - return; - } - dmybuf++; - } - - /* Now read dmy from the correct position */ - sscanf(dmybuf,"%u", &dmy); - - last_read_time = hms; - microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - tm.tm_year = dmy % 100 + 100; - dmy = dmy / 100; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; - - if (posn_type == gpgga) { - /* capture useful data update and exit */ - if (curr_waypt) { - if (! WAYPT_HAS(curr_waypt, speed)) - WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed)); - if (! WAYPT_HAS(curr_waypt, course)) - WAYPT_SET(curr_waypt, course, course); - /* The change of date wasn't recorded when - * going from 235959 to 000000. */ - nmea_set_waypoint_time(curr_waypt, &tm, microseconds); - } - /* This point is both a waypoint and a trackpoint. */ - if (amod_waypoint) { - waypt_add(waypt_dupe(curr_waypt)); - amod_waypoint = 0; - } - return; - } - - waypt = waypt_new(); - - WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); - - WAYPT_SET(waypt, course, course); - - nmea_set_waypoint_time(waypt, &tm, microseconds); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - nmea_release_wpt(curr_waypt); - curr_waypt = waypt; - - /* This point is both a waypoint and a trackpoint. */ - if (amod_waypoint) { - waypt_add(waypt_dupe(waypt)); - amod_waypoint = 0; - } + double latdeg, lngdeg; + char lngdir, latdir; + double hms; + char fix; + unsigned int dmy; + double speed,course; + waypoint *waypt; + double microseconds; + char *dmybuf; + int i; + + if (trk_head == NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + } + + /* + * Read everything except the dmy, in case lngdeg + * and lngdir are missing. + */ + sscanf(ibuf,"$GPRMC,%lf,%c,%lf,%c,%lf,%c,%lf,%lf", + &hms, &fix, &latdeg, &latdir, + &lngdeg, &lngdir, + &speed, &course); + + if (fix != 'A') { + /* ignore this fix - it is invalid */ + return; + } + + /* Skip past nine commas in ibuf to reach the dmy value */ + for (dmybuf=ibuf,i=0; i<9; i++) { + dmybuf= strchr(dmybuf, ','); + if (dmybuf==NULL) { + /* If we run out of commas, the sentence is invalid. */ + return; + } + dmybuf++; + } + + /* Now read dmy from the correct position */ + sscanf(dmybuf,"%u", &dmy); + + last_read_time = hms; + microseconds = MILLI_TO_MICRO(1000 * (hms - (int)hms)); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 100 + 100; + dmy = dmy / 100; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + + if (posn_type == gpgga) { + /* capture useful data update and exit */ + if (curr_waypt) { + if (! WAYPT_HAS(curr_waypt, speed)) { + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed)); + } + if (! WAYPT_HAS(curr_waypt, course)) { + WAYPT_SET(curr_waypt, course, course); + } + /* The change of date wasn't recorded when + * going from 235959 to 000000. */ + nmea_set_waypoint_time(curr_waypt, &tm, microseconds); + } + /* This point is both a waypoint and a trackpoint. */ + if (amod_waypoint) { + waypt_add(waypt_dupe(curr_waypt)); + amod_waypoint = 0; + } + return; + } + + waypt = waypt_new(); + + WAYPT_SET(waypt, speed, KNOTS_TO_MPS(speed)); + + WAYPT_SET(waypt, course, course); + + nmea_set_waypoint_time(waypt, &tm, microseconds); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + nmea_release_wpt(curr_waypt); + curr_waypt = waypt; + + /* This point is both a waypoint and a trackpoint. */ + if (amod_waypoint) { + waypt_add(waypt_dupe(waypt)); + amod_waypoint = 0; + } } static void gpwpl_parse(char *ibuf) { - waypoint *waypt; - double latdeg, lngdeg; - char latdir, lngdir; - char sname[99]; - - sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", - &latdeg,&latdir, - &lngdeg,&lngdir, - sname); - - waypt = waypt_new(); - - if (latdir == 'S') latdeg = -latdeg; - waypt->latitude = ddmm2degrees(latdeg); - if (lngdir == 'W') lngdeg = -lngdeg; - waypt->longitude = ddmm2degrees(lngdeg); - - waypt->shortname = xstrdup(sname); - - curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */ - nmea_add_wpt(waypt, NULL); + waypoint *waypt; + double latdeg, lngdeg; + char latdir, lngdir; + char sname[99]; + + sscanf(ibuf,"$GPWPL,%lf,%c,%lf,%c,%[^*]", + &latdeg,&latdir, + &lngdeg,&lngdir, + sname); + + waypt = waypt_new(); + + if (latdir == 'S') { + latdeg = -latdeg; + } + waypt->latitude = ddmm2degrees(latdeg); + if (lngdir == 'W') { + lngdeg = -lngdeg; + } + waypt->longitude = ddmm2degrees(lngdeg); + + waypt->shortname = xstrdup(sname); + + curr_waypt = NULL; /* waypoints won't be updated with GPS fixes */ + nmea_add_wpt(waypt, NULL); } static void gpzda_parse(char *ibuf) { - double hms; - int dd, mm, yy, lclhrs, lclmins; - - sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", - &hms, &dd, &mm, &yy, &lclhrs, &lclmins); - tm.tm_sec = (int) hms % 100; - tm.tm_min = (((int) hms - tm.tm_sec) / 100) % 100; - tm.tm_hour = (int) hms / 10000; - tm.tm_mday = dd; - tm.tm_mon = mm - 1; - tm.tm_year = yy - 1900; + double hms; + int dd, mm, yy, lclhrs, lclmins; + + sscanf(ibuf,"$GPZDA,%lf,%d,%d,%d,%d,%d", + &hms, &dd, &mm, &yy, &lclhrs, &lclmins); + tm.tm_sec = (int) hms % 100; + tm.tm_min = (((int) hms - tm.tm_sec) / 100) % 100; + tm.tm_hour = (int) hms / 10000; + tm.tm_mday = dd; + tm.tm_mon = mm - 1; + tm.tm_year = yy - 1900; } static void gpgsa_parse(char *ibuf) { - char fixauto; - char fix; - int prn[12]; - int scn,cnt; - float pdop=0,hdop=0,vdop=0; - char* tok=0; - - memset(prn,0xff,sizeof(prn)); - - scn = sscanf(ibuf,"$GPGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - &fixauto, &fix, - &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5], - &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]); - - /* - sscanf has scanned all the leftmost elements - we'll rescan by skipping 15 commas to the dops - */ - tok = ibuf; - for (cnt=0;(tok)&&(cnt<15);cnt++) - { - tok = strchr(tok,','); - if (!tok) break; - tok++; - } - if (tok) sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop); - - - if (curr_waypt) { - - if (curr_waypt->fix!=fix_dgps) { - if (fix=='3') curr_waypt->fix=fix_3d; - else if (fix=='2') curr_waypt->fix=fix_2d; - } - - curr_waypt->pdop = pdop; - curr_waypt->hdop = hdop; - curr_waypt->vdop = vdop; - - if (curr_waypt->sat <= 0) { - for (cnt=0;cnt<12;cnt++) - curr_waypt->sat += (prn[cnt]>0)?(1):(0); - } - } - + char fixauto; + char fix; + int prn[12]; + int scn,cnt; + float pdop=0,hdop=0,vdop=0; + char* tok=0; + + memset(prn,0xff,sizeof(prn)); + + scn = sscanf(ibuf,"$GPGSA,%c,%c,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", + &fixauto, &fix, + &prn[0],&prn[1],&prn[2],&prn[3],&prn[4],&prn[5], + &prn[6],&prn[7],&prn[8],&prn[9],&prn[10],&prn[11]); + + /* + sscanf has scanned all the leftmost elements + we'll rescan by skipping 15 commas to the dops + */ + tok = ibuf; + for (cnt=0; (tok)&&(cnt<15); cnt++) { + tok = strchr(tok,','); + if (!tok) { + break; + } + tok++; + } + if (tok) { + sscanf(tok,"%f,%f,%f",&pdop,&hdop,&vdop); + } + + + if (curr_waypt) { + + if (curr_waypt->fix!=fix_dgps) { + if (fix=='3') { + curr_waypt->fix=fix_3d; + } else if (fix=='2') { + curr_waypt->fix=fix_2d; + } + } + + curr_waypt->pdop = pdop; + curr_waypt->hdop = hdop; + curr_waypt->vdop = vdop; + + if (curr_waypt->sat <= 0) { + for (cnt=0; cnt<12; cnt++) { + curr_waypt->sat += (prn[cnt]>0)?(1):(0); + } + } + } + } static void gpvtg_parse(char *ibuf) { - float course; - char ct; - float magcourse; - char cm; - double speed_n; - char cn; - double speed_k; - char ck; - - sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", - &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); - - if (curr_waypt) { - WAYPT_SET(curr_waypt, course, course); - - if (speed_k>0) - WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k)) - else - WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n)); - - } - + float course; + char ct; + float magcourse; + char cm; + double speed_n; + char cn; + double speed_k; + char ck; + + sscanf(ibuf,"$GPVTG,%f,%c,%f,%c,%lf,%c,%lf,%c", + &course,&ct,&magcourse,&cm,&speed_n,&cn,&speed_k,&ck); + + if (curr_waypt) { + WAYPT_SET(curr_waypt, course, course); + + if (speed_k>0) + WAYPT_SET(curr_waypt, speed, KPH_TO_MPS(speed_k)) + else { + WAYPT_SET(curr_waypt, speed, KNOTS_TO_MPS(speed_n)); + } + + } + } /* * AVMAP EKP-IV Tracks - a proprietary (and very weird) extended NMEA. - * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972 + * https://sourceforge.net/tracker/?func=detail&atid=489478&aid=1640814&group_id=58972 */ -static +static double pcmpt_deg(int d) { - int deg; - double minutes; + int deg; + double minutes; - deg = d / 100000; - minutes = (((d / 100000.0) - deg) * 100) / 60.0; - return (double) deg + minutes; + deg = d / 100000; + minutes = (((d / 100000.0) - deg) * 100) / 60.0; + return (double) deg + minutes; } void pcmpt_parse(char *ibuf) { - int i, j1, j2, j3, j4, j5, j6; - int lat, lon; - char altflag, u1, u2; - float alt, f1, f2; - char coords[20] = {0}; - int dmy, hms; - - dmy = hms = 0; - - sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%[^,],%d,%f,%d,%f,%c,%d,%c,%d", - &j1, &j2, &j3, &altflag, &alt, &j4, (char *) &coords, - &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms); - - if (altflag == 'D' && curr_waypt && alt > 0) { - curr_waypt->altitude = alt /*+ 500*/; - return; - } - - /* - * There are a couple of different second line records, but we - * don't care about them. - */ - if (j2 != 1) { - return; - } - - sscanf(coords, "%d%n", &lat, &i); - if (coords[i] == 'S') lat = -lat; - sscanf(coords + i + 1, "%d%n", &lon, &i); - if (coords[i] == 'W') lon= -lon; - - if (lat || lon) { - curr_waypt = waypt_new(); - curr_waypt->longitude = pcmpt_deg(lon); - curr_waypt->latitude = pcmpt_deg(lat); - - tm.tm_sec = (long) hms % 100; - hms = hms / 100; - tm.tm_min = (long) hms % 100; - hms = hms / 100; - tm.tm_hour = (long) hms % 100; - - tm.tm_year = dmy % 10000 - 1900; - dmy = dmy / 10000; - tm.tm_mon = dmy % 100 - 1; - dmy = dmy / 100; - tm.tm_mday = dmy; - nmea_set_waypoint_time(curr_waypt, &tm, 0); - ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q); - } else { - queue *elem, *tmp; - route_head *trk_head; - - if (QUEUE_EMPTY(&pcmpt_head)) { - return; - } - - /* - * Since we oh-so-cleverly inserted points at the head, - * we can rip through the queue forward now to get our -` * handy-dandy reversing effect. - */ - trk_head = route_head_alloc(); - track_add_head(trk_head); - QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) { - waypoint *wpt = (waypoint *) dequeue(elem); - nmea_add_wpt(wpt, trk_head); - } - } + int i, j1, j2, j3, j4, j5, j6; + int lat, lon; + char altflag, u1, u2; + float alt, f1, f2; + char coords[20] = {0}; + int dmy, hms; + + dmy = hms = 0; + + sscanf(ibuf,"$PCMPT,%d,%d,%d,%c,%f,%d,%[^,],%d,%f,%d,%f,%c,%d,%c,%d", + &j1, &j2, &j3, &altflag, &alt, &j4, (char *) &coords, + &j5, &f1, &j6, &f2, &u1, &dmy, &u2, &hms); + + if (altflag == 'D' && curr_waypt && alt > 0) { + curr_waypt->altitude = alt /*+ 500*/; + return; + } + + /* + * There are a couple of different second line records, but we + * don't care about them. + */ + if (j2 != 1) { + return; + } + + sscanf(coords, "%d%n", &lat, &i); + if (coords[i] == 'S') { + lat = -lat; + } + sscanf(coords + i + 1, "%d%n", &lon, &i); + if (coords[i] == 'W') { + lon= -lon; + } + + if (lat || lon) { + curr_waypt = waypt_new(); + curr_waypt->longitude = pcmpt_deg(lon); + curr_waypt->latitude = pcmpt_deg(lat); + + tm.tm_sec = (long) hms % 100; + hms = hms / 100; + tm.tm_min = (long) hms % 100; + hms = hms / 100; + tm.tm_hour = (long) hms % 100; + + tm.tm_year = dmy % 10000 - 1900; + dmy = dmy / 10000; + tm.tm_mon = dmy % 100 - 1; + dmy = dmy / 100; + tm.tm_mday = dmy; + nmea_set_waypoint_time(curr_waypt, &tm, 0); + ENQUEUE_HEAD(&pcmpt_head, &curr_waypt->Q); + } else { + queue *elem, *tmp; + route_head *trk_head; + + if (QUEUE_EMPTY(&pcmpt_head)) { + return; + } + + /* + * Since we oh-so-cleverly inserted points at the head, + * we can rip through the queue forward now to get our + ` * handy-dandy reversing effect. + */ + trk_head = route_head_alloc(); + track_add_head(trk_head); + QUEUE_FOR_EACH(&pcmpt_head, elem, tmp) { + waypoint *wpt = (waypoint *) dequeue(elem); + nmea_add_wpt(wpt, trk_head); + } + } } static void nmea_fix_timestamps(route_head *track) { - if ((trk_head == NULL) || (without_date == 0)) return; - - if (tm.tm_year == 0) - { - queue *elem, *temp; - waypoint *prev = NULL; - time_t delta_tm; - - if (optdate == NULL) - { - warning(MYNAME ": No date found within track (all points dropped)!\n"); - warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); - track_del_head(track); - return; - } - delta_tm = mkgmtime(&opt_tm); - - QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) - { - waypoint *wpt = (waypoint *)elem; - - wpt->creation_time += delta_tm; - if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) /* go over midnight ? */ - { - delta_tm += SECONDS_PER_DAY; - wpt->creation_time += SECONDS_PER_DAY; - } - prev = wpt; - } - } - else - { - time_t prev; - queue *elem; - - tm.tm_hour = 23; /* last date found */ - tm.tm_min = 59; - tm.tm_sec = 59; - - prev = mkgmtime(&tm); - - /* go backward through the track and complete timestamps */ - - for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) - { - waypoint *wpt = (waypoint *)elem; - - if (wpt->wpt_flags.fmt_use != 0) - { - time_t dt; - - wpt->wpt_flags.fmt_use = 0; /* reset flag */ - - dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; - wpt->creation_time += dt; - if (wpt->creation_time > prev) - wpt->creation_time+=SECONDS_PER_DAY; - } - prev = wpt->creation_time; - } - } + if ((trk_head == NULL) || (without_date == 0)) { + return; + } + + if (tm.tm_year == 0) { + queue *elem, *temp; + waypoint *prev = NULL; + time_t delta_tm; + + if (optdate == NULL) { + warning(MYNAME ": No date found within track (all points dropped)!\n"); + warning(MYNAME ": Please use option \"date\" to preset a valid date for thoose tracks.\n"); + track_del_head(track); + return; + } + delta_tm = mkgmtime(&opt_tm); + + QUEUE_FOR_EACH(&track->waypoint_list, elem, temp) { + waypoint *wpt = (waypoint *)elem; + + wpt->creation_time += delta_tm; + if ((prev != NULL) && (prev->creation_time > wpt->creation_time)) { /* go over midnight ? */ + delta_tm += SECONDS_PER_DAY; + wpt->creation_time += SECONDS_PER_DAY; + } + prev = wpt; + } + } else { + time_t prev; + queue *elem; + + tm.tm_hour = 23; /* last date found */ + tm.tm_min = 59; + tm.tm_sec = 59; + + prev = mkgmtime(&tm); + + /* go backward through the track and complete timestamps */ + + for (elem = QUEUE_LAST(&track->waypoint_list); elem != &track->waypoint_list; elem=elem->prev) { + waypoint *wpt = (waypoint *)elem; + + if (wpt->wpt_flags.fmt_use != 0) { + time_t dt; + + wpt->wpt_flags.fmt_use = 0; /* reset flag */ + + dt = (prev / SECONDS_PER_DAY) * SECONDS_PER_DAY; + wpt->creation_time += dt; + if (wpt->creation_time > prev) { + wpt->creation_time+=SECONDS_PER_DAY; + } + } + prev = wpt->creation_time; + } + } } void nmea_parse_one_line(char *ibuf) { - char *ck; - int ckval, ckcmp; - char *tbuf = lrtrim(ibuf); - - /* - * GISTEQ PhotoTracker (stupidly) puts a bogus field in front - * of the line. Look for it and toss it. - */ - if (0 == strncmp(tbuf, "---,", 4)) tbuf += 4; - - if (*tbuf != '$') return; - - ck = strrchr(tbuf, '*'); - if (ck != NULL) { - *ck = '\0'; - ckval = nmea_cksum(&tbuf[1]); - *ck = '*'; - ck++; - sscanf(ck, "%2X", &ckcmp); - if (ckval != ckcmp) { + char *ck; + int ckval, ckcmp; + char *tbuf = lrtrim(ibuf); + + /* + * GISTEQ PhotoTracker (stupidly) puts a bogus field in front + * of the line. Look for it and toss it. + */ + if (0 == strncmp(tbuf, "---,", 4)) { + tbuf += 4; + } + + if (*tbuf != '$') { + return; + } + + ck = strrchr(tbuf, '*'); + if (ck != NULL) { + *ck = '\0'; + ckval = nmea_cksum(&tbuf[1]); + *ck = '*'; + ck++; + sscanf(ck, "%2X", &ckcmp); + if (ckval != ckcmp) { #if 0 - printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); - printf("NMEA %s\n", tbuf); + printf("ckval %X, %X, %s\n", ckval, ckcmp, ck); + printf("NMEA %s\n", tbuf); #endif - return; - } - - had_checksum = 1; - } - else if (had_checksum) { - /* we have had a checksum on all previous sentences, but not on this - one, which probably indicates this line is truncated */ - had_checksum = 0; - return; - } - - if(strstr(tbuf+1,"$")!=NULL) - { - /* If line has more than one $, there is probably an error in it. */ - return; - } - - /* @@@ zmarties: The parse routines all assume all fields are present, but - the NMEA format allows any field to be missed out if there is no data - for that field. Rather than change all the parse routines, we first - substitute a default value of zero for any missing field. - */ - if (strstr(tbuf, ",,")) - { - tbuf = gstrsub(tbuf, ",,", ",0,"); - } - - if (0 == strncmp(tbuf, "$GPWPL,", 7)) { - gpwpl_parse(tbuf); - } else - if (opt_gpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { - posn_type = gpgga; - gpgga_parse(tbuf); - } else - if (opt_gprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { - if (posn_type != gpgga) { - posn_type = gprmc; - } - /* - * Always call gprmc_parse() because like GPZDA - * it contains the full date. - */ - gprmc_parse(tbuf); - } else - if (0 == strncmp(tbuf, "$GPGLL,", 7)) { - if ((posn_type != gpgga) && (posn_type != gprmc)) { - gpgll_parse(tbuf); - } - } else - if (0 == strncmp(tbuf, "$GPZDA,",7)) { - gpzda_parse(tbuf); - } else - if (0 == strncmp(tbuf, "$PCMPT,", 7)) { - pcmpt_parse(tbuf); - } else - if (opt_gpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { - gpvtg_parse(tbuf); /* speed and course */ - } else - if (opt_gpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { - gpgsa_parse(tbuf); /* GPS fix */ - } else - if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) { - amod_waypoint = 1; - } - - if (tbuf != ibuf) { - /* clear up the dynamic buffer we used because substition was required */ - xfree(tbuf); - } + return; + } + + had_checksum = 1; + } else if (had_checksum) { + /* we have had a checksum on all previous sentences, but not on this + one, which probably indicates this line is truncated */ + had_checksum = 0; + return; + } + + if (strstr(tbuf+1,"$")!=NULL) { + /* If line has more than one $, there is probably an error in it. */ + return; + } + + /* @@@ zmarties: The parse routines all assume all fields are present, but + the NMEA format allows any field to be missed out if there is no data + for that field. Rather than change all the parse routines, we first + substitute a default value of zero for any missing field. + */ + if (strstr(tbuf, ",,")) { + tbuf = gstrsub(tbuf, ",,", ",0,"); + } + + if (0 == strncmp(tbuf, "$GPWPL,", 7)) { + gpwpl_parse(tbuf); + } else if (opt_gpgga && (0 == strncmp(tbuf, "$GPGGA,", 7))) { + posn_type = gpgga; + gpgga_parse(tbuf); + } else if (opt_gprmc && (0 == strncmp(tbuf, "$GPRMC,", 7))) { + if (posn_type != gpgga) { + posn_type = gprmc; + } + /* + * Always call gprmc_parse() because like GPZDA + * it contains the full date. + */ + gprmc_parse(tbuf); + } else if (0 == strncmp(tbuf, "$GPGLL,", 7)) { + if ((posn_type != gpgga) && (posn_type != gprmc)) { + gpgll_parse(tbuf); + } + } else if (0 == strncmp(tbuf, "$GPZDA,",7)) { + gpzda_parse(tbuf); + } else if (0 == strncmp(tbuf, "$PCMPT,", 7)) { + pcmpt_parse(tbuf); + } else if (opt_gpvtg && (0 == strncmp(tbuf, "$GPVTG,",7))) { + gpvtg_parse(tbuf); /* speed and course */ + } else if (opt_gpgsa && (0 == strncmp(tbuf, "$GPGSA,",7))) { + gpgsa_parse(tbuf); /* GPS fix */ + } else if (0 == strncmp(tbuf, "$ADPMB,5,0", 10)) { + amod_waypoint = 1; + } + + if (tbuf != ibuf) { + /* clear up the dynamic buffer we used because substition was required */ + xfree(tbuf); + } } static void nmea_read(void) { - char *ibuf; - char *ck; - double lt = -1; - int line = -1; - - posn_type = gp_unknown; - trk_head = NULL; - without_date = 0; - memset(&tm, 0, sizeof(tm)); - opt_tm = tm; - - /* This was done in rd_init() */ - if (getposn) { - return; - } - - if (optdate) - { - memset(&opt_tm, 0, sizeof(opt_tm)); - - ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); - if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) - fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); - else if (opt_tm.tm_year < 70) - fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); - } - - curr_waypt = NULL; - - while ((ibuf = gbfgetstr(file_in))) { - char *sdatum, *cx; - - line++; - - if ((line == 0) & file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) { - /* special hack for Sony GPS-CS1 files: - they are fully (?) nmea compatible, but come with a header line like - "@Sonygps/ver1.0/wgs-84". */ - /* The Sony GPS-CS3KA extends that line even further - so we now look for the second field to be / - delimited. - @Sonygps/ver1.0/wgs-84/gps-cs3.0 - */ - - /* Check the GPS datum */ - cx = strchr(&ibuf[12], '/'); - if (cx != NULL) { - char *edatum; - sdatum = cx + 1; - edatum = strchr(sdatum, '/'); - if (edatum) { - *edatum = 0; - } - datum = GPS_Lookup_Datum_Index(sdatum); - if (datum < 0) - fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum); - } - continue; - } - - nmea_parse_one_line(ibuf); - if (lt != last_read_time && curr_waypt && trk_head) { - if (curr_waypt != last_waypt) { - nmea_add_wpt(curr_waypt, trk_head); - last_waypt = curr_waypt; - } - lt = last_read_time; - } - } - - /* try to complete date-less trackpoints */ - nmea_fix_timestamps(trk_head); + char *ibuf; + char *ck; + double lt = -1; + int line = -1; + + posn_type = gp_unknown; + trk_head = NULL; + without_date = 0; + memset(&tm, 0, sizeof(tm)); + opt_tm = tm; + + /* This was done in rd_init() */ + if (getposn) { + return; + } + + if (optdate) { + memset(&opt_tm, 0, sizeof(opt_tm)); + + ck = (char *)strptime(optdate, "%Y%m%d", &opt_tm); + if ((ck == NULL) || (*ck != '\0') || (strlen(optdate) != 8)) { + fatal(MYNAME ": Invalid date \"%s\"!\n", optdate); + } else if (opt_tm.tm_year < 70) { + fatal(MYNAME ": Date \"%s\" is out of range (have to be 19700101 or later)!\n", optdate); + } + } + + curr_waypt = NULL; + + while ((ibuf = gbfgetstr(file_in))) { + char *sdatum, *cx; + + line++; + + if ((line == 0) & file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + if ((line == 0) && (case_ignore_strncmp(ibuf, "@SonyGPS/ver", 12) == 0)) { + /* special hack for Sony GPS-CS1 files: + they are fully (?) nmea compatible, but come with a header line like + "@Sonygps/ver1.0/wgs-84". */ + /* The Sony GPS-CS3KA extends that line even further + so we now look for the second field to be / + delimited. + @Sonygps/ver1.0/wgs-84/gps-cs3.0 + */ + + /* Check the GPS datum */ + cx = strchr(&ibuf[12], '/'); + if (cx != NULL) { + char *edatum; + sdatum = cx + 1; + edatum = strchr(sdatum, '/'); + if (edatum) { + *edatum = 0; + } + datum = GPS_Lookup_Datum_Index(sdatum); + if (datum < 0) { + fatal(MYNAME "/SonyGPS: Unsupported datum \"%s\" in source data!\n", sdatum); + } + } + continue; + } + + nmea_parse_one_line(ibuf); + if (lt != last_read_time && curr_waypt && trk_head) { + if (curr_waypt != last_waypt) { + nmea_add_wpt(curr_waypt, trk_head); + last_waypt = curr_waypt; + } + lt = last_read_time; + } + } + + /* try to complete date-less trackpoints */ + nmea_fix_timestamps(trk_head); } void nmea_rd_posn_init(const char *fname) { - if ((gbser_handle = gbser_init(fname)) != NULL) { - read_mode = rm_serial; - gbser_set_speed(gbser_handle, 4800); - } else { - fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); - } - - gbser_flush(gbser_handle); - - if (opt_baud) { - if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { - fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); - } - } - posn_fname = fname; + if ((gbser_handle = gbser_init(fname)) != NULL) { + read_mode = rm_serial; + gbser_set_speed(gbser_handle, 4800); + } else { + fatal(MYNAME ": Could not open '%s' for position tracking.\n", fname); + } + + gbser_flush(gbser_handle); + + if (opt_baud) { + if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) { + fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud); + } + } + posn_fname = fname; } static void -safe_print(int cnt, const char *b) +safe_print(int cnt, const char *b) { - int i; - for (i = 0; i < cnt; i++) { - char c = isprint(b[i]) ? b[i] : '.'; - fputc(c, stderr); - } + int i; + for (i = 0; i < cnt; i++) { + char c = isprint(b[i]) ? b[i] : '.'; + fputc(c, stderr); + } } static void reset_sirf_to_nmea(int br); -static +static int hunt_sirf(void) { - /* Try to place the common BR's first to speed searching */ - static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1}; - static int *brp = &br[0]; - char ibuf[1024]; - - for (brp = br; *brp > 0; brp++) { - int rv; - if (global_opts.debug_level > 1) { - fprintf(stderr, "Trying %d\n", *brp); - } - - /* - * Cycle our port's data speed and spray the "change to NMEA - * mode to the device. - */ - gbser_set_speed(gbser_handle, *brp); - reset_sirf_to_nmea(*brp); - - rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), - 1000, 0x0a, 0x0d); - /* - * If we didn't get a read error but did get a string that - * started with a dollar sign, we're probably in NMEA mode - * now. - */ - if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') { - return 1; - } - - /* - * If nothing was received, it's not a sirf part. Fast exit. - */ - if (rv < 0) { - return 0; - } - } - return 0; + /* Try to place the common BR's first to speed searching */ + static int br[] = {38400, 9600, 57600, 115200, 19200, 4800, -1}; + static int *brp = &br[0]; + char ibuf[1024]; + + for (brp = br; *brp > 0; brp++) { + int rv; + if (global_opts.debug_level > 1) { + fprintf(stderr, "Trying %d\n", *brp); + } + + /* + * Cycle our port's data speed and spray the "change to NMEA + * mode to the device. + */ + gbser_set_speed(gbser_handle, *brp); + reset_sirf_to_nmea(*brp); + + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), + 1000, 0x0a, 0x0d); + /* + * If we didn't get a read error but did get a string that + * started with a dollar sign, we're probably in NMEA mode + * now. + */ + if ((rv > -1) && (strlen(ibuf) > 0) && ibuf[0] == '$') { + return 1; + } + + /* + * If nothing was received, it's not a sirf part. Fast exit. + */ + if (rv < 0) { + return 0; + } + } + return 0; } static waypoint * nmea_rd_posn(posn_status *posn_status) { - char ibuf[1024]; - static double lt = -1; - int i; - int am_sirf = 0; - - /* - * Read a handful of sentences, collecting the best info we - * can. If the timestamp changes (indicating the sequence is - * about to restart and thus the one we're collecting isn't going - * to get any better than we now have) hand that back to the caller. - */ - - for (i = 0; i < 10; i++) { - int rv; - ibuf[0] = 0; - rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); - if (global_opts.debug_level > 1) { - safe_print(strlen(ibuf), ibuf); - } - if (rv < 0) { - if (am_sirf == 0) { - if (global_opts.debug_level > 1) { - warning(MYNAME ": Attempting sirf mode.\n"); - } - /* This is tacky, we have to change speed - * to 9600bps to tell it to speak NMEA at - * 4800. - */ - am_sirf = hunt_sirf(); - if (am_sirf) { - i = 0; - continue; - } - } - fatal(MYNAME ": No data received on %s.\n", posn_fname); - } - nmea_parse_one_line(ibuf); - if (lt != last_read_time) { - if (last_read_time) { - waypoint *w = curr_waypt; - - lt = last_read_time; - curr_waypt = NULL; - - return w; - } - } - } - return NULL; + char ibuf[1024]; + static double lt = -1; + int i; + int am_sirf = 0; + + /* + * Read a handful of sentences, collecting the best info we + * can. If the timestamp changes (indicating the sequence is + * about to restart and thus the one we're collecting isn't going + * to get any better than we now have) hand that back to the caller. + */ + + for (i = 0; i < 10; i++) { + int rv; + ibuf[0] = 0; + rv = gbser_read_line(gbser_handle, ibuf, sizeof(ibuf), 2000, 0x0a, 0x0d); + if (global_opts.debug_level > 1) { + safe_print(strlen(ibuf), ibuf); + } + if (rv < 0) { + if (am_sirf == 0) { + if (global_opts.debug_level > 1) { + warning(MYNAME ": Attempting sirf mode.\n"); + } + /* This is tacky, we have to change speed + * to 9600bps to tell it to speak NMEA at + * 4800. + */ + am_sirf = hunt_sirf(); + if (am_sirf) { + i = 0; + continue; + } + } + fatal(MYNAME ": No data received on %s.\n", posn_fname); + } + nmea_parse_one_line(ibuf); + if (lt != last_read_time) { + if (last_read_time) { + waypoint *w = curr_waypt; + + lt = last_read_time; + curr_waypt = NULL; + + return w; + } + } + } + return NULL; } static void nmea_wayptpr(const waypoint *wpt) { - char obuf[200]; - double lat,lon; - char *s; - int cksum; - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - if (global_opts.synthesize_shortnames) - s = mkshort_from_wpt(mkshort_handle, wpt); - else { - s = mkshort(mkshort_handle, wpt->shortname); - } - - snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', s - - ); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - if (sleepus >= 0) { - gbfflush(file_out); - gb_sleep(sleepus); - } - - xfree(s); - + char obuf[200]; + double lat,lon; + char *s; + int cksum; + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + if (global_opts.synthesize_shortnames) { + s = mkshort_from_wpt(mkshort_handle, wpt); + } else { + s = mkshort(mkshort_handle, wpt->shortname); + } + + snprintf(obuf, sizeof(obuf), "GPWPL,%08.3f,%c,%09.3f,%c,%s", + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', s + + ); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + if (sleepus >= 0) { + gbfflush(file_out); + gb_sleep(sleepus); + } + + xfree(s); + } -void +void nmea_track_init(const route_head *rte) { - last_time = -1; + last_time = -1; } void nmea_trackpt_pr(const waypoint *wpt) { - char obuf[200]; - char fix='0'; - double lat,lon; - int cksum; - struct tm *tm; - time_t hms; - time_t ymd; - - if ( opt_sleep ) { - gbfflush( file_out ); - if ( last_time > 0 ) { - if ( sleepus >= 0 ) { - gb_sleep( sleepus ); - } - else { - long wait_time = wpt->creation_time - last_time; - if ( wait_time > 0 ) { - gb_sleep( wait_time * 1000000 ); - } - } - } - last_time = wpt->creation_time; - } - - lat = degrees2ddmm(wpt->latitude); - lon = degrees2ddmm(wpt->longitude); - - tm = gmtime(&wpt->creation_time); - if ( tm ) { - hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; - ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; - } else { - hms = 0; - ymd = 0; - } - - switch (wpt->fix) - { - case fix_dgps: - fix='2'; - /* or */ - case fix_3d: - case fix_2d: - fix='1'; - break; - case fix_pps: - fix='3'; - break; - default: - fix='0'; - } - - if (opt_gprmc) { - snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", - (double) hms + (wpt->microseconds / 1000000.0), - fix=='0' ? 'V' : 'A', - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), - WAYPT_HAS(wpt, course) ? (wpt->course):(0), - (int) ymd); - cksum = nmea_cksum(obuf); - - /* GISTeq doesn't care about the checksum, but wants this prefixed, so - * we can write it with abandon. - */ - if (opt_gisteq) { - gbfprintf(file_out, "---,"); - } - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - if (opt_gpgga) { - snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", - (double) hms + (wpt->microseconds / 1000000.0), - fabs(lat), lat < 0 ? 'S' : 'N', - fabs(lon), lon < 0 ? 'W' : 'E', - fix, - (wpt->sat>0)?(wpt->sat):(0), - (wpt->hdop>0)?(wpt->hdop):(0.0), - wpt->altitude == unknown_alt ? 0 : wpt->altitude); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) { - snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", - WAYPT_HAS(wpt, course) ? (wpt->course):(0), - WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), - WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0) ); - - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - - if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) { - - switch (wpt->fix) - { - case fix_dgps: - /* or */ - case fix_3d: - fix='3'; - break; - case fix_2d: - fix='2'; - break; - default: - fix=0; - } - snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f", - fix, - (wpt->pdop>0)?(wpt->pdop):(0), - (wpt->hdop>0)?(wpt->hdop):(0), - (wpt->vdop>0)?(wpt->vdop):(0) ); - cksum = nmea_cksum(obuf); - gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); - } - gbfflush(file_out); + char obuf[200]; + char fix='0'; + double lat,lon; + int cksum; + struct tm *tm; + time_t hms; + time_t ymd; + + if (opt_sleep) { + gbfflush(file_out); + if (last_time > 0) { + if (sleepus >= 0) { + gb_sleep(sleepus); + } else { + long wait_time = wpt->creation_time - last_time; + if (wait_time > 0) { + gb_sleep(wait_time * 1000000); + } + } + } + last_time = wpt->creation_time; + } + + lat = degrees2ddmm(wpt->latitude); + lon = degrees2ddmm(wpt->longitude); + + tm = gmtime(&wpt->creation_time); + if (tm) { + hms = tm->tm_hour * 10000 + tm->tm_min * 100 + tm->tm_sec; + ymd = tm->tm_mday * 10000 + tm->tm_mon * 100 + tm->tm_year; + } else { + hms = 0; + ymd = 0; + } + + switch (wpt->fix) { + case fix_dgps: + fix='2'; + /* or */ + case fix_3d: + case fix_2d: + fix='1'; + break; + case fix_pps: + fix='3'; + break; + default: + fix='0'; + } + + if (opt_gprmc) { + snprintf(obuf, sizeof(obuf), "GPRMC,%010.3f,%c,%08.3f,%c,%09.3f,%c,%.2f,%.2f,%06d,,", + (double) hms + (wpt->microseconds / 1000000.0), + fix=='0' ? 'V' : 'A', + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + (int) ymd); + cksum = nmea_cksum(obuf); + + /* GISTeq doesn't care about the checksum, but wants this prefixed, so + * we can write it with abandon. + */ + if (opt_gisteq) { + gbfprintf(file_out, "---,"); + } + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if (opt_gpgga) { + snprintf(obuf, sizeof(obuf), "GPGGA,%010.3f,%08.3f,%c,%09.3f,%c,%c,%02d,%.1f,%.3f,M,0.0,M,,", + (double) hms + (wpt->microseconds / 1000000.0), + fabs(lat), lat < 0 ? 'S' : 'N', + fabs(lon), lon < 0 ? 'W' : 'E', + fix, + (wpt->sat>0)?(wpt->sat):(0), + (wpt->hdop>0)?(wpt->hdop):(0.0), + wpt->altitude == unknown_alt ? 0 : wpt->altitude); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + if ((opt_gpvtg) && (WAYPT_HAS(wpt, course) || WAYPT_HAS(wpt, speed))) { + snprintf(obuf,sizeof(obuf),"GPVTG,%.3f,T,0,M,%.3f,N,%.3f,K", + WAYPT_HAS(wpt, course) ? (wpt->course):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KNOTS(wpt->speed):(0), + WAYPT_HAS(wpt, speed) ? MPS_TO_KPH(wpt->speed):(0)); + + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + + if ((opt_gpgsa) && (wpt->fix!=fix_unknown)) { + + switch (wpt->fix) { + case fix_dgps: + /* or */ + case fix_3d: + fix='3'; + break; + case fix_2d: + fix='2'; + break; + default: + fix=0; + } + snprintf(obuf,sizeof(obuf),"GPGSA,A,%c,,,,,,,,,,,,,%.1f,%.1f,%.1f", + fix, + (wpt->pdop>0)?(wpt->pdop):(0), + (wpt->hdop>0)?(wpt->hdop):(0), + (wpt->vdop>0)?(wpt->vdop):(0)); + cksum = nmea_cksum(obuf); + gbfprintf(file_out, "$%s*%02X\n", obuf, cksum); + } + gbfflush(file_out); } static void nmea_write(void) { - waypt_disp_all(nmea_wayptpr); - track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); + waypt_disp_all(nmea_wayptpr); + track_disp_all(nmea_track_init, NULL, nmea_trackpt_pr); } static void nmea_wr_posn_init(const char *fname) { - nmea_wr_init(fname); + nmea_wr_init(fname); } static void nmea_wr_posn(waypoint *wpt) { - nmea_trackpt_pr(wpt); + nmea_trackpt_pr(wpt); } static void @@ -1369,21 +1387,25 @@ nmea_wr_posn_deinit(void) ff_vecs_t nmea_vecs = { - ff_type_file, - { (ff_cap)(ff_cap_read | ff_cap_write), - (ff_cap)(ff_cap_read | ff_cap_write), - ff_cap_none}, - nmea_rd_init, - nmea_wr_init, - nmea_rd_deinit, - nmea_wr_deinit, - nmea_read, - nmea_write, - NULL, - nmea_args, - CET_CHARSET_ASCII, 0, /* CET-REVIEW */ - { nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, - nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit } + ff_type_file, + { + (ff_cap)(ff_cap_read | ff_cap_write), + (ff_cap)(ff_cap_read | ff_cap_write), + ff_cap_none + }, + nmea_rd_init, + nmea_wr_init, + nmea_rd_deinit, + nmea_wr_deinit, + nmea_read, + nmea_write, + NULL, + nmea_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { + nmea_rd_posn_init, nmea_rd_posn, nmea_rd_deinit, + nmea_wr_posn_init, nmea_wr_posn, nmea_wr_posn_deinit + } }; /* @@ -1396,43 +1418,44 @@ ff_vecs_t nmea_vecs = { static void sirf_write(unsigned char *buf) { - int i, chksum = 0; - int len = buf[2] << 8 | buf[3]; + int i, chksum = 0; + int len = buf[2] << 8 | buf[3]; - for (i = 0; i < len; i++) { - chksum += buf[4 + i]; - } - chksum &= 0x7fff; + for (i = 0; i < len; i++) { + chksum += buf[4 + i]; + } + chksum &= 0x7fff; - buf[len + 4] = chksum >> 8; - buf[len + 5] = chksum & 0xff; + buf[len + 4] = chksum >> 8; + buf[len + 5] = chksum & 0xff; - gbser_write(gbser_handle, buf, len + 8); /* 4 at front, 4 at back */ + gbser_write(gbser_handle, buf, len + 8); /* 4 at front, 4 at back */ } static void reset_sirf_to_nmea(int br) { - static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18, - 0x81, 0x02, - 0x01, 0x01, /* GGA */ - 0x00, 0x00, /* suppress GLL */ - 0x01, 0x00, /* suppress GSA */ - 0x05, 0x00, /* suppress GSV */ - 0x01, 0x01, /* use RMC for date*/ - 0x00, 0x00, /* suppress VTG */ - 0x00, 0x01, /* output rate */ - 0x00, 0x01, /* unused recommended values */ - 0x00, 0x01, - 0x00, 0x01, /* ZDA */ - 0x12, 0xc0, /* 4800 bps */ - 0x00, 0x00, /* checksum */ - 0xb0, 0xb3}; /* packet end */ - /* repopulate bit rate */ - pkt[26] = br >> 8; - pkt[27] = br & 0xff; - - sirf_write(pkt); - gb_sleep(250 * 1000); - gbser_flush(gbser_handle); + static unsigned char pkt[] = {0xa0, 0xa2, 0x00, 0x18, + 0x81, 0x02, + 0x01, 0x01, /* GGA */ + 0x00, 0x00, /* suppress GLL */ + 0x01, 0x00, /* suppress GSA */ + 0x05, 0x00, /* suppress GSV */ + 0x01, 0x01, /* use RMC for date*/ + 0x00, 0x00, /* suppress VTG */ + 0x00, 0x01, /* output rate */ + 0x00, 0x01, /* unused recommended values */ + 0x00, 0x01, + 0x00, 0x01, /* ZDA */ + 0x12, 0xc0, /* 4800 bps */ + 0x00, 0x00, /* checksum */ + 0xb0, 0xb3 + }; /* packet end */ + /* repopulate bit rate */ + pkt[26] = br >> 8; + pkt[27] = br & 0xff; + + sirf_write(pkt); + gb_sleep(250 * 1000); + gbser_flush(gbser_handle); } diff --git a/gpsbabel/nmn4.c b/gpsbabel/nmn4.c index bb02c00be..8cc2c0efe 100644 --- a/gpsbabel/nmn4.c +++ b/gpsbabel/nmn4.c @@ -1,22 +1,22 @@ - /* +/* - Support for Navigon Mobile Navigator .rte files. + Support for Navigon Mobile Navigator .rte files. - Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ /* @@ -42,8 +42,8 @@ static char *index_opt; static arglist_t nmn4_args[] = { - {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR + {"index", &index_opt, "Index of route to write (if more than one in source)", NULL, ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; @@ -52,173 +52,177 @@ arglist_t nmn4_args[] = { static char * nmn4_concat(char *arg0, ...) { - va_list args; - char *src, *res; - - res = NULL; - va_start(args, arg0); - src = (char *)arg0; - - while (src != NULL) - { - char *c = lrtrim(src); - - if (*c != '\0') - { - if (res == NULL) - res = xstrdup(c); - else - { - res = xstrappend(res, " "); - res = xstrappend(res, c); - } - } - xfree(src); - src = va_arg(args, char *); - } - va_end(args); - - return res; + va_list args; + char *src, *res; + + res = NULL; + va_start(args, arg0); + src = (char *)arg0; + + while (src != NULL) { + char *c = lrtrim(src); + + if (*c != '\0') { + if (res == NULL) { + res = xstrdup(c); + } else { + res = xstrappend(res, " "); + res = xstrappend(res, c); + } + } + xfree(src); + src = va_arg(args, char *); + } + va_end(args); + + return res; } static void nmn4_check_line(char *line) { - char *c = line; - int i = 0; - while ((c = strchr(c, '|'))) - { - c++; - i++; - } - is_fatal((i != 15), - MYNAME ": Invalid or unknown structure!"); + char *c = line; + int i = 0; + while ((c = strchr(c, '|'))) { + c++; + i++; + } + is_fatal((i != 15), + MYNAME ": Invalid or unknown structure!"); } static void nmn4_read_data(void) { - char *buff; - char *str, *c; - int column; - int line = 0; - - char *zip1, *zip2, *city, *street, *number; - route_head *route; - waypoint *wpt; - - route = route_head_alloc(); - route_add_head(route); - - while ((buff = gbfgetstr(fin))) - { - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - str = buff = lrtrim(buff); - if (*buff == '\0') continue; - - nmn4_check_line(buff); - - /* for a quiet compiler */ - zip1 = zip2 = city = street = number = NULL; - - wpt = waypt_new(); - - column = -1; - c = csv_lineparse(str, "|", "", column++); - while (c != NULL) - { - switch(column) - { - case 0: /* "-" */ /* unknown fields for the moment */ - case 1: /* "-" */ - case 2: /* "-" */ - case 3: /* "-" */ - case 9: /* "-" */ - case 10: /* "-" */ - case 13: /* "-" */ - case 14: /* "-" */ - case 15: /* "" */ - break; - - case 4: /* ZIP Code */ - if (*c != '-') - zip1 = xstrdup(c); - else - zip1 = xstrdup(""); - break; - - case 5: /* City */ - if (*c != '-') - city = xstrdup(c); - else - city = xstrdup(""); - break; - - case 6: /* ZIP Code -2- */ - if (*c != '-') - zip2 = xstrdup(c); - else - zip2 = xstrdup(""); - break; - - case 7: /* Street */ - if (*c != '-') - street = xstrdup(c); - else - street = xstrdup(""); - break; - - case 8: /* Number */ - if (*c != '-') - number = xstrdup(c); - else - number = xstrdup(""); - - /* - This is our final index - All stuff for generating names or comments - is hold locally. - - We don't have fields for street, city or zip-code. - Instead we construct a description from that. - */ - - if (strcmp(zip1, zip2) == 0) *zip2 = '\0'; - if (*city != '\0') - { - /* - if any field following city has a value, add a comma to city - */ - if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) - city = xstrappend(city, ","); - } - - /* concats all fields to one string and release */ - wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); - break; - - case 11: /* longitude */ - sscanf(c, "%lf", &wpt->longitude); - break; - - case 12: /* latitude */ - sscanf(c, "%lf", &wpt->latitude); - break; - - } - c = csv_lineparse(NULL, "|", "", column++); - } - route_add_wpt(route, wpt); - } + char *buff; + char *str, *c; + int column; + int line = 0; + + char *zip1, *zip2, *city, *street, *number; + route_head *route; + waypoint *wpt; + + route = route_head_alloc(); + route_add_head(route); + + while ((buff = gbfgetstr(fin))) { + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + str = buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + + nmn4_check_line(buff); + + /* for a quiet compiler */ + zip1 = zip2 = city = street = number = NULL; + + wpt = waypt_new(); + + column = -1; + c = csv_lineparse(str, "|", "", column++); + while (c != NULL) { + switch (column) { + case 0: /* "-" */ /* unknown fields for the moment */ + case 1: /* "-" */ + case 2: /* "-" */ + case 3: /* "-" */ + case 9: /* "-" */ + case 10: /* "-" */ + case 13: /* "-" */ + case 14: /* "-" */ + case 15: /* "" */ + break; + + case 4: /* ZIP Code */ + if (*c != '-') { + zip1 = xstrdup(c); + } else { + zip1 = xstrdup(""); + } + break; + + case 5: /* City */ + if (*c != '-') { + city = xstrdup(c); + } else { + city = xstrdup(""); + } + break; + + case 6: /* ZIP Code -2- */ + if (*c != '-') { + zip2 = xstrdup(c); + } else { + zip2 = xstrdup(""); + } + break; + + case 7: /* Street */ + if (*c != '-') { + street = xstrdup(c); + } else { + street = xstrdup(""); + } + break; + + case 8: /* Number */ + if (*c != '-') { + number = xstrdup(c); + } else { + number = xstrdup(""); + } + + /* + This is our final index + All stuff for generating names or comments + is hold locally. + + We don't have fields for street, city or zip-code. + Instead we construct a description from that. + */ + + if (strcmp(zip1, zip2) == 0) { + *zip2 = '\0'; + } + if (*city != '\0') { + /* + if any field following city has a value, add a comma to city + */ + if ((*street != '\0') || (*number != '\0') || (*zip2 != '\0')) { + city = xstrappend(city, ","); + } + } + + /* concats all fields to one string and release */ + wpt->description = nmn4_concat(zip1, city, street, number, zip2, NULL); + break; + + case 11: /* longitude */ + sscanf(c, "%lf", &wpt->longitude); + break; + + case 12: /* latitude */ + sscanf(c, "%lf", &wpt->latitude); + break; + + } + c = csv_lineparse(NULL, "|", "", column++); + } + route_add_wpt(route, wpt); + } } -static void +static void nmn4_route_hdr(const route_head *route) { - curr_rte_num++; + curr_rte_num++; } -static void +static void nmn4_route_tlr(const route_head *rte) { } @@ -226,46 +230,47 @@ nmn4_route_tlr(const route_head *rte) static void nmn4_write_waypt(const waypoint *wpt) { - char city[128], street[128], zipc[32], number[32]; - - if (curr_rte_num != target_rte_num) return; - - strncpy(city, "-", sizeof(city)); - strncpy(street, "-", sizeof(street)); - strncpy(zipc, "-", sizeof(zipc)); - strncpy(number, "-", sizeof(number)); - - /* - Population of specific data used by Navigon may come in the - future or it may be impossible. We currently output only the - coordinates in the output, but this is sufficient for Navigon. - - The coordinates are the only item we are about guaranteed to have - when converting to any from any format, so we leave the other - fields unpopulated. So i have to pay Navigon a compliment for - implementing a simple data exchange. - */ - - gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", - zipc, city, zipc, street, number, - wpt->longitude, wpt->latitude); + char city[128], street[128], zipc[32], number[32]; + + if (curr_rte_num != target_rte_num) { + return; + } + + strncpy(city, "-", sizeof(city)); + strncpy(street, "-", sizeof(street)); + strncpy(zipc, "-", sizeof(zipc)); + strncpy(number, "-", sizeof(number)); + + /* + Population of specific data used by Navigon may come in the + future or it may be impossible. We currently output only the + coordinates in the output, but this is sufficient for Navigon. + + The coordinates are the only item we are about guaranteed to have + when converting to any from any format, so we leave the other + fields unpopulated. So i have to pay Navigon a compliment for + implementing a simple data exchange. + */ + + gbfprintf(fout, "-|-|-|-|%s|%s|%s|%s|%s|-|-|%.5f|%.5f|-|-|\r\n", + zipc, city, zipc, street, number, + wpt->longitude, wpt->latitude); } static void nmn4_write_data(void) { - - target_rte_num = 1; - - if (index_opt != NULL) - { - target_rte_num = atoi(index_opt); - is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), - MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); - } - - curr_rte_num = 0; - route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); + + target_rte_num = 1; + + if (index_opt != NULL) { + target_rte_num = atoi(index_opt); + is_fatal(((target_rte_num > (int) route_count()) || (target_rte_num < 1)), + MYNAME ": invalid route number %d (1..%d))!\n", target_rte_num, route_count()); + } + + curr_rte_num = 0; + route_disp_all(nmn4_route_hdr, nmn4_route_tlr, nmn4_write_waypt); } @@ -274,51 +279,51 @@ nmn4_write_data(void) static void nmn4_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); + fin = gbfopen(fname, "rb", MYNAME); } static void nmn4_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void nmn4_read(void) { - nmn4_read_data(); + nmn4_read_data(); } static void nmn4_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); } static void nmn4_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void nmn4_write(void) { - nmn4_write_data(); + nmn4_write_data(); } /* --------------------------------------------------------------------------- */ ff_vecs_t nmn4_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, - nmn4_rd_init, - nmn4_wr_init, - nmn4_rd_deinit, - nmn4_wr_deinit, - nmn4_read, - nmn4_write, - NULL, - nmn4_args, - CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read | ff_cap_write}, + nmn4_rd_init, + nmn4_wr_init, + nmn4_rd_deinit, + nmn4_wr_deinit, + nmn4_read, + nmn4_write, + NULL, + nmn4_args, + CET_CHARSET_MS_ANSI, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/nukedata.c b/gpsbabel/nukedata.c index 6dc8fccbb..cc1fee05e 100644 --- a/gpsbabel/nukedata.c +++ b/gpsbabel/nukedata.c @@ -1,7 +1,7 @@ /* nukedata: remove all (waypoint|tracks|routes) from the stream. - + Copyright (C) 2005 Robert Lipe robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" @@ -30,35 +30,41 @@ static char *nukewpts, *nuketrks, *nukertes; static arglist_t nuke_args[] = { - {"waypoints", &nukewpts, "Remove all waypoints from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - {"tracks", &nuketrks, "Remove all tracks from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - {"routes", &nukertes, "Remove all routes from data stream", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - ARG_TERMINATOR + { + "waypoints", &nukewpts, "Remove all waypoints from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + { + "tracks", &nuketrks, "Remove all tracks from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + { + "routes", &nukertes, "Remove all routes from data stream", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + } , + ARG_TERMINATOR }; -static void +static void nuke_process(void) { - if (*nukewpts != '0') { - waypt_flush_all(); - } - if (*nuketrks != '0') { - route_flush_all_tracks(); - } - if (*nukertes != '0') { - route_flush_all_routes(); - } + if (*nukewpts != '0') { + waypt_flush_all(); + } + if (*nuketrks != '0') { + route_flush_all_tracks(); + } + if (*nukertes != '0') { + route_flush_all_routes(); + } } filter_vecs_t nuke_vecs = { - NULL, - nuke_process, - NULL, - NULL, - nuke_args + NULL, + nuke_process, + NULL, + NULL, + nuke_args }; #endif diff --git a/gpsbabel/osm.c b/gpsbabel/osm.c index f96871998..3686321f4 100644 --- a/gpsbabel/osm.c +++ b/gpsbabel/osm.c @@ -1,4 +1,4 @@ -/* +/* Support for "OpenStreetMap" data files (.xml) @@ -26,12 +26,11 @@ static char *opt_tag, *opt_tagnd, *created_by; -static arglist_t osm_args[] = -{ - { "tag", &opt_tag, "Write additional way tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "tagnd", &opt_tagnd, "Write additional node tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR +static arglist_t osm_args[] = { + { "tag", &opt_tag, "Write additional way tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "tagnd", &opt_tagnd, "Write additional node tag key/value pairs", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { "created_by", &created_by, "Use this value as custom created_by value","GPSBabel", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; #define MYNAME "osm" @@ -54,47 +53,47 @@ static int wpt_loaded, rte_loaded; static xg_callback osm_node, osm_node_tag, osm_node_end; static xg_callback osm_way, osm_way_nd, osm_way_tag, osm_way_end; -static +static xg_tag_mapping osm_map[] = { - { osm_node, cb_start, "/osm/node" }, - { osm_node_tag, cb_start, "/osm/node/tag" }, - { osm_node_end, cb_end, "/osm/node" }, - { osm_way, cb_start, "/osm/way" }, - { osm_way_nd, cb_start, "/osm/way/nd" }, - { osm_way_tag, cb_start, "/osm/way/tag" }, - { osm_way_end, cb_end, "/osm/way" }, - { NULL, 0, NULL } + { osm_node, cb_start, "/osm/node" }, + { osm_node_tag, cb_start, "/osm/node/tag" }, + { osm_node_end, cb_end, "/osm/node" }, + { osm_way, cb_start, "/osm/way" }, + { osm_way_nd, cb_start, "/osm/way/nd" }, + { osm_way_tag, cb_start, "/osm/way/tag" }, + { osm_way_end, cb_end, "/osm/way" }, + { NULL, 0, NULL } }; #endif // HAVE_LIBEXPAT static const char *osm_features[] = { - "- dummy -", /* 0 */ - "aeroway", /* 1 */ - "amenity", /* 2 */ - "building", /* 3 */ - "cycleway", /* 4 */ - "railway", /* 5 */ - "highway", /* 6 */ - "historic", /* 7 */ - "landuse", /* 8 */ - "leisure", /* 9 */ - "man_made", /* 10 */ - "military", /* 11 */ - "natural", /* 12 */ - "place", /* 13 */ - "power", /* 14 */ - "shop", /* 15 */ - "sport", /* 16 */ - "tourism", /* 17 */ - "waterway", /* 18 */ - "aerialway", /* 19 */ - NULL + "- dummy -", /* 0 */ + "aeroway", /* 1 */ + "amenity", /* 2 */ + "building", /* 3 */ + "cycleway", /* 4 */ + "railway", /* 5 */ + "highway", /* 6 */ + "historic", /* 7 */ + "landuse", /* 8 */ + "leisure", /* 9 */ + "man_made", /* 10 */ + "military", /* 11 */ + "natural", /* 12 */ + "place", /* 13 */ + "power", /* 14 */ + "shop", /* 15 */ + "sport", /* 16 */ + "tourism", /* 17 */ + "waterway", /* 18 */ + "aerialway", /* 19 */ + NULL }; typedef struct osm_icon_mapping_s { - const int key; - const char *value; - const char *icon; + const int key; + const char *value; + const char *icon; } osm_icon_mapping_t; @@ -102,9 +101,9 @@ typedef struct osm_icon_mapping_s { static osm_icon_mapping_t osm_icon_mappings[] = { - /* cycleway ...*/ + /* cycleway ...*/ - /* highway ...*/ + /* highway ...*/ // { 6, "mini_roundabout", "?" }, // { 6, "stop", "?" }, @@ -124,9 +123,9 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 6, "turning_circle", "?" }, // { 6, "User Defined", "?" }, - /* waterway ... */ + /* waterway ... */ - { 18, "dock", "Dock" }, + { 18, "dock", "Dock" }, // { 18, "lock_gate", "?" }, // { 18, "turning_point", "?" }, // { 18, "aqueduct", "?" }, @@ -137,36 +136,36 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 18, "weir", "?" }, // { 18, "User Defined", "?" }, - /* railway ... */ + /* railway ... */ // { 5, "station", "?" }, // { 5, "halt", "?" }, // { 5, "tram_stop", "?" }, // { 5, "viaduct", "?" }, - { 5, "crossing", "Crossing" }, + { 5, "crossing", "Crossing" }, // { 5, "level_crossing", "?" }, // { 5, "subway_entrance", "?" }, // { 5, "turntable", "?" }, // { 5, "User Defined", "?" }, - /* aeroway ... */ + /* aeroway ... */ - { 1, "aerodrome", "Airport" }, - { 1, "terminal", "Airport" }, - { 1, "helipad", "Heliport" }, + { 1, "aerodrome", "Airport" }, + { 1, "terminal", "Airport" }, + { 1, "helipad", "Heliport" }, // { 1, "User Defined", "?" }, - /* aerialway ... */ + /* aerialway ... */ // { 19, "User Defined", "?" }, - /* power ... */ + /* power ... */ // { 14, "tower", "?" }, // { 14, "sub_station", "?" }, // { 14, "generator", "?" }, - /* man_made ... */ + /* man_made ... */ // { 10, "works", "?" }, // { 10, "beacon", "?" }, @@ -185,60 +184,60 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 10, "crane", "?" }, // { 10, "User Defined", "?" }, - /* building ... */ + /* building ... */ - { 3, "yes", "Building" }, + { 3, "yes", "Building" }, // { 3, "User Defined", "?" }, - /* leisure ... */ + /* leisure ... */ // { 9, "sports_centre", "?" }, - { 9, "golf_course", "Golf Course" }, - { 9, "stadium", "Stadium" }, + { 9, "golf_course", "Golf Course" }, + { 9, "stadium", "Stadium" }, // { 9, "track", "?" }, // { 9, "pitch", "?" }, // { 9, "water_park", "?" }, - { 9, "marina", "Marina" }, + { 9, "marina", "Marina" }, // { 9, "slipway", "?" }, - { 9, "fishing", "Fishing Area" }, + { 9, "fishing", "Fishing Area" }, // { 9, "nature_reserve", "?" }, - { 9, "park", "Park" }, + { 9, "park", "Park" }, // { 9, "playground", "?" }, // { 9, "garden", "?" }, // { 9, "common", "?" }, // { 9, "User Defined", "?" }, - /* amenity ... */ + /* amenity ... */ - { 2, "pub", "Bar" }, + { 2, "pub", "Bar" }, // { 2, "biergarten", "?" }, - { 2, "nightclub", "Bar" }, + { 2, "nightclub", "Bar" }, // { 2, "cafe", "?" }, - { 2, "restaurant", "Restaurant" }, - { 2, "fast_food", "Fast Food" }, - { 2, "parking", "Parking Area" }, + { 2, "restaurant", "Restaurant" }, + { 2, "fast_food", "Fast Food" }, + { 2, "parking", "Parking Area" }, // { 2, "bicycle_parking", "?" }, // { 2, "bicycle_rental", "?" }, - { 2, "car_rental", "Car Rental" }, + { 2, "car_rental", "Car Rental" }, // { 2, "car_sharing", "?" }, // { 2, "taxi", "?" }, - { 2, "fuel", "Gas Station" }, - { 2, "telephone", "Telephone" }, - { 2, "toilets", "Restroom" }, + { 2, "fuel", "Gas Station" }, + { 2, "telephone", "Telephone" }, + { 2, "toilets", "Restroom" }, // { 2, "recycling", "?" }, // { 2, "public_building", "?" }, - { 2, "townhall", "City Hall" }, + { 2, "townhall", "City Hall" }, // { 2, "place_of_worship", "?" }, // { 2, "grave_yard", "?" }, - { 2, "post_office", "Post Office" }, + { 2, "post_office", "Post Office" }, // { 2, "post_box", "?" }, - { 2, "school", "School" }, + { 2, "school", "School" }, // { 2, "university", "?" }, // { 2, "college", "?" }, - { 2, "pharmacy", "Pharmacy" }, - { 2, "hospital", "Medical Facility" }, + { 2, "pharmacy", "Pharmacy" }, + { 2, "hospital", "Medical Facility" }, // { 2, "library", "?" }, - { 2, "police", "Police Station" }, + { 2, "police", "Police Station" }, // { 2, "fire_station", "?" }, // { 2, "bus_station", "?" }, // { 2, "theatre", "?" }, @@ -246,16 +245,16 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 2, "arts_centre", "?" }, // { 2, "courthouse", "?" }, // { 2, "prison", "?" }, - { 2, "bank", "Bank" }, + { 2, "bank", "Bank" }, // { 2, "bureau_de_change", "?" }, // { 2, "atm", "?" }, // { 2, "fountain", "?" }, // { 2, "User Defined", "?" }, - /* shop ... */ + /* shop ... */ // { 15, "supermarket", "?" }, - { 15, "convenience", "Convenience Store" }, + { 15, "convenience", "Convenience Store" }, // { 15, "butcher", "?" }, // { 15, "bicycle", "?" }, // { 15, "doityourself", "?" }, @@ -265,25 +264,25 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 15, "kiosk", "?" }, // { 15, "User Defined", "?" }, - /* tourism ... */ - - { 17, "information", "Information" }, - { 17, "hotel", "Hotel" }, - { 17, "motel", "Lodging" }, - { 17, "guest_house", "Lodging" }, - { 17, "hostel", "Lodging" }, - { 17, "camp_site", "Campground" }, - { 17, "caravan_site", "RV Park" }, - { 17, "picnic_site", "Picnic Area" }, - { 17, "viewpoint", "Scenic Area" }, + /* tourism ... */ + + { 17, "information", "Information" }, + { 17, "hotel", "Hotel" }, + { 17, "motel", "Lodging" }, + { 17, "guest_house", "Lodging" }, + { 17, "hostel", "Lodging" }, + { 17, "camp_site", "Campground" }, + { 17, "caravan_site", "RV Park" }, + { 17, "picnic_site", "Picnic Area" }, + { 17, "viewpoint", "Scenic Area" }, // { 17, "theme_park", "?" }, // { 17, "attraction", "?" }, - { 17, "zoo", "Zoo" }, + { 17, "zoo", "Zoo" }, // { 17, "artwork", "?" }, - { 17, "museum", "Museum" }, + { 17, "museum", "Museum" }, // { 17, "User Defined", "?" }, - /* historic ... */ + /* historic ... */ // { 7, "castle", "?" }, // { 7, "monument", "?" }, @@ -293,14 +292,14 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 7, "battlefield", "?" }, // { 7, "User Defined", "?" }, - /* landuse ... */ + /* landuse ... */ // { 8, "farm", "?" }, // { 8, "quarry", "?" }, // { 8, "landfill", "?" }, // { 8, "basin", "?" }, // { 8, "reservoir", "?" }, - { 8, "forest", "Forest" }, + { 8, "forest", "Forest" }, // { 8, "allotments", "?" }, // { 8, "residential", "?" }, // { 8, "retail", "?" }, @@ -310,13 +309,13 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 8, "greenfield", "?" }, // { 8, "railway", "?" }, // { 8, "construction", "?" }, - { 8, "military", "Military" }, - { 8, "cemetery", "Cemetery" }, + { 8, "military", "Military" }, + { 8, "cemetery", "Cemetery" }, // { 8, "village_green", "?" }, // { 8, "recreation_ground", "?" }, // { 8, "User Defined", "?" }, - /* military ... */ + /* military ... */ // { 11, "airfield", "?" }, // { 11, "bunker", "?" }, @@ -326,7 +325,7 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 11, "naval_base", "?" }, // { 11, "User Defined", "?" }, - /* natural ... */ + /* natural ... */ // { 12, "spring", "?" }, // { 12, "peak", "?" }, @@ -342,13 +341,13 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 12, "water", "?" }, // { 12, "coastline", "?" }, // { 12, "mud", "?" }, - { 12, "beach", "Beach" }, + { 12, "beach", "Beach" }, // { 12, "bay", "?" }, // { 12, "land", "?" }, // { 12, "cave_entrance", "?" }, // { 12, "User Defined", "?" }, - /* sport ... */ + /* sport ... */ // { 16, "10pin", "?" }, // { 16, "athletics", "?" }, @@ -377,30 +376,30 @@ static osm_icon_mapping_t osm_icon_mappings[] = { // { 16, "skating", "?" }, // { 16, "skateboard", "?" }, // { 16, "soccer", "?" }, - { 16, "swimming", "Swimming Area" }, - { 16, "skiing", "Skiing Area" }, + { 16, "swimming", "Swimming Area" }, + { 16, "skiing", "Skiing Area" }, // { 16, "table_tennis", "?" }, // { 16, "tennis", "?" }, // { 16, "orienteering", "?" }, // { 16, "User Defined", "?" }, - /* place ... */ + /* place ... */ // { 13, "continent", "?" }, // { 13, "country", "?" }, // { 13, "state", "?" }, // { 13, "region", "?" }, // { 13, "county", "?" }, - { 13, "city", "City (Large)" }, - { 13, "town", "City (Medium)" }, - { 13, "village", "City (Small)" }, + { 13, "city", "City (Large)" }, + { 13, "town", "City (Medium)" }, + { 13, "village", "City (Small)" }, // { 13, "hamlet", "?" }, // { 13, "suburb", "?" }, // { 13, "locality", "?" }, // { 13, "island", "?" }, // { 13, "User Defined", "?" }, - { -1, NULL, NULL } + { -1, NULL, NULL } }; #if ! HAVE_LIBEXPAT @@ -408,7 +407,7 @@ static osm_icon_mapping_t osm_icon_mappings[] = { void osm_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \" MYNAME \" support because expat was not installed.\n"); } void @@ -426,287 +425,286 @@ osm_read(void) static void osm_features_init(void) { - int i; - - keys = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); - values = avltree_init(0, MYNAME); - - /* the first of osm_features is a place holder */ - for (i = 1; osm_features[i]; i++) - avltree_insert(keys, osm_features[i], gb_int2ptr(i)); - - for (i = 0; osm_icon_mappings[i].value; i++) { - char buff[128]; - - buff[0] = osm_icon_mappings[i].key; - strncpy(&buff[1], osm_icon_mappings[i].value, sizeof(buff) - 1); - avltree_insert(values, buff, (const void *)&osm_icon_mappings[i]); - } + int i; + + keys = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + values = avltree_init(0, MYNAME); + + /* the first of osm_features is a place holder */ + for (i = 1; osm_features[i]; i++) { + avltree_insert(keys, osm_features[i], gb_int2ptr(i)); + } + + for (i = 0; osm_icon_mappings[i].value; i++) { + char buff[128]; + + buff[0] = osm_icon_mappings[i].key; + strncpy(&buff[1], osm_icon_mappings[i].value, sizeof(buff) - 1); + avltree_insert(values, buff, (const void *)&osm_icon_mappings[i]); + } } static char osm_feature_ikey(const char *key) { - int result; - const void *p; - - if (avltree_find(keys, key, &p)) - result = gb_ptr2int(p); - else - result = -1; - - return result; + int result; + const void *p; + + if (avltree_find(keys, key, &p)) { + result = gb_ptr2int(p); + } else { + result = -1; + } + + return result; } static char * osm_feature_symbol(const int ikey, const char *value) { - char *result; - char buff[128]; - osm_icon_mapping_t *data; + char *result; + char buff[128]; + osm_icon_mapping_t *data; - buff[0] = ikey; - strncpy(&buff[1], value, sizeof(buff) - 1); + buff[0] = ikey; + strncpy(&buff[1], value, sizeof(buff) - 1); - if (avltree_find(values, buff, (void *)&data)) - result = xstrdup(data->icon); - else - xasprintf(&result, "%s:%s", osm_features[ikey], value); + if (avltree_find(values, buff, (void *)&data)) { + result = xstrdup(data->icon); + } else { + xasprintf(&result, "%s:%s", osm_features[ikey], value); + } - return result; + return result; } static char * osm_strip_html(const char *str) { - utf_string utf; - utf.is_html = 1; - utf.utfstring = (char *)str; + utf_string utf; + utf.is_html = 1; + utf.utfstring = (char *)str; - return strip_html(&utf); // util.c + return strip_html(&utf); // util.c } -static void +static void osm_node_end(const char *args, const char **unused) { - if (wpt) { - if (wpt->wpt_flags.fmt_use) - waypt_add(wpt); - else - waypt_free(wpt); - wpt = NULL; - } + if (wpt) { + if (wpt->wpt_flags.fmt_use) { + waypt_add(wpt); + } else { + waypt_free(wpt); + } + wpt = NULL; + } } -static void +static void osm_node(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - wpt = waypt_new(); - - while (*avp) { - if (strcmp(avp[0], "id") == 0) { - xasprintf(&wpt->description, "osm-id %s", avp[1]); - if (! avltree_insert(waypoints, avp[1], (void *)wpt)) - warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]); - else - wpt->wpt_flags.fmt_use = 1; - } - else if (strcmp(avp[0], "user") == 0) ; - else if (strcmp(avp[0], "lat") == 0) - wpt->latitude = atof(avp[1]); - else if (strcmp(avp[0], "lon") == 0) - wpt->longitude = atof(avp[1]); - else if (strcmp(avp[0], "timestamp") == 0) - wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); - - avp += 2; - } + const char **avp = &attrv[0]; + + wpt = waypt_new(); + + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&wpt->description, "osm-id %s", avp[1]); + if (! avltree_insert(waypoints, avp[1], (void *)wpt)) { + warning(MYNAME ": Duplicate osm-id %s!\n", avp[1]); + } else { + wpt->wpt_flags.fmt_use = 1; + } + } else if (strcmp(avp[0], "user") == 0) ; + else if (strcmp(avp[0], "lat") == 0) { + wpt->latitude = atof(avp[1]); + } else if (strcmp(avp[0], "lon") == 0) { + wpt->longitude = atof(avp[1]); + } else if (strcmp(avp[0], "timestamp") == 0) { + wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + } + + avp += 2; + } } -static void +static void osm_node_tag(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - const char *key = "", *value = ""; - char *str; - signed char ikey; - - while (*avp) { - if (strcmp(avp[0], "k") == 0) - key = avp[1]; - else if (strcmp(avp[0], "v") == 0) - value = avp[1]; - avp+=2; - } - - str = osm_strip_html(value); - - if (strcmp(key, "name") == 0) { - if (! wpt->shortname) - wpt->shortname = xstrdup(str); - } - else if (strcmp(key, "name:en") == 0) { - if (wpt->shortname) - xfree(wpt->shortname); - wpt->shortname = xstrdup(str); - } - else if ((ikey = osm_feature_ikey(key)) >= 0) { - wpt->icon_descr = osm_feature_symbol(ikey, value); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - else if (strcmp(key, "note") == 0) { - if (wpt->notes) { - char *tmp; - xasprintf(&tmp, "%s; %s", wpt->notes, str); - xfree(wpt->notes); - wpt->notes = tmp; - } - else - wpt->notes = xstrdup(str); - } - else if (strcmp(key, "gps:hdop") == 0) { - wpt->hdop = atof(str); - } - else if (strcmp(key, "gps:vdop") == 0) { - wpt->vdop = atof(str); - } - else if (strcmp(key, "gps:pdop") == 0) { - wpt->pdop = atof(str); - } - else if (strcmp(key, "gps:sat") == 0) { - wpt->sat = atoi(str); - } - else if (strcmp(key, "gps:fix") == 0) { - if (strcmp(str, "2d") == 0) { - wpt->fix = fix_2d; - } - else if (strcmp(str, "3d") == 0) { - wpt->fix = fix_3d; - } - else if (strcmp(str, "dgps") == 0) { - wpt->fix = fix_dgps; - } - else if (strcmp(str, "pps") == 0) { - wpt->fix = fix_pps; - } - else if (strcmp(str, "none") == 0) { - wpt->fix = fix_none; - } - } - - xfree(str); + const char **avp = &attrv[0]; + const char *key = "", *value = ""; + char *str; + signed char ikey; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) { + key = avp[1]; + } else if (strcmp(avp[0], "v") == 0) { + value = avp[1]; + } + avp+=2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! wpt->shortname) { + wpt->shortname = xstrdup(str); + } + } else if (strcmp(key, "name:en") == 0) { + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup(str); + } else if ((ikey = osm_feature_ikey(key)) >= 0) { + wpt->icon_descr = osm_feature_symbol(ikey, value); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } else if (strcmp(key, "note") == 0) { + if (wpt->notes) { + char *tmp; + xasprintf(&tmp, "%s; %s", wpt->notes, str); + xfree(wpt->notes); + wpt->notes = tmp; + } else { + wpt->notes = xstrdup(str); + } + } else if (strcmp(key, "gps:hdop") == 0) { + wpt->hdop = atof(str); + } else if (strcmp(key, "gps:vdop") == 0) { + wpt->vdop = atof(str); + } else if (strcmp(key, "gps:pdop") == 0) { + wpt->pdop = atof(str); + } else if (strcmp(key, "gps:sat") == 0) { + wpt->sat = atoi(str); + } else if (strcmp(key, "gps:fix") == 0) { + if (strcmp(str, "2d") == 0) { + wpt->fix = fix_2d; + } else if (strcmp(str, "3d") == 0) { + wpt->fix = fix_3d; + } else if (strcmp(str, "dgps") == 0) { + wpt->fix = fix_dgps; + } else if (strcmp(str, "pps") == 0) { + wpt->fix = fix_pps; + } else if (strcmp(str, "none") == 0) { + wpt->fix = fix_none; + } + } + + xfree(str); } -static void +static void osm_way(const char *args, const char **attrv) { - const char **avp = &attrv[0]; + const char **avp = &attrv[0]; - rte = route_head_alloc(); + rte = route_head_alloc(); - while (*avp) { - if (strcmp(avp[0], "id") == 0) { - xasprintf(&rte->rte_desc, "osm-id %s", avp[1]); - } - avp += 2; - } + while (*avp) { + if (strcmp(avp[0], "id") == 0) { + xasprintf(&rte->rte_desc, "osm-id %s", avp[1]); + } + avp += 2; + } } -static void +static void osm_way_nd(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "ref") == 0) { - waypoint *tmp; - if (avltree_find(waypoints, avp[1], (void *)&tmp)) { - tmp = waypt_dupe(tmp); - route_add_wpt(rte, tmp); - } - else - warning(MYNAME ": Way reference id \"%s\" wasn't listed under nodes!\n", avp[1]); - } - avp += 2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "ref") == 0) { + waypoint *tmp; + if (avltree_find(waypoints, avp[1], (void *)&tmp)) { + tmp = waypt_dupe(tmp); + route_add_wpt(rte, tmp); + } else { + warning(MYNAME ": Way reference id \"%s\" wasn't listed under nodes!\n", avp[1]); + } + } + avp += 2; + } } -static void +static void osm_way_tag(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - const char *key = "", *value = ""; - char *str; - - while (*avp) { - if (strcmp(avp[0], "k") == 0) - key = avp[1]; - else if (strcmp(avp[0], "v") == 0) - value = avp[1]; - avp += 2; - } - - str = osm_strip_html(value); - - if (strcmp(key, "name") == 0) { - if (! rte->rte_name) - rte->rte_name = xstrdup(str); - } - else if (strcmp(key, "name:en") == 0) { - if (rte->rte_name) - xfree(rte->rte_name); - rte->rte_name = xstrdup(str); - } - - xfree(str); + const char **avp = &attrv[0]; + const char *key = "", *value = ""; + char *str; + + while (*avp) { + if (strcmp(avp[0], "k") == 0) { + key = avp[1]; + } else if (strcmp(avp[0], "v") == 0) { + value = avp[1]; + } + avp += 2; + } + + str = osm_strip_html(value); + + if (strcmp(key, "name") == 0) { + if (! rte->rte_name) { + rte->rte_name = xstrdup(str); + } + } else if (strcmp(key, "name:en") == 0) { + if (rte->rte_name) { + xfree(rte->rte_name); + } + rte->rte_name = xstrdup(str); + } + + xfree(str); } -static void +static void osm_way_end(const char *args, const char **unused) { - if (rte) { - route_add_head(rte); - rte = NULL; - } + if (rte) { + route_add_head(rte); + rte = NULL; + } } -static void +static void osm_rd_init(const char *fname) { - wpt = NULL; - rte = NULL; - wpt_loaded = 0; - rte_loaded = 0; + wpt = NULL; + rte = NULL; + wpt_loaded = 0; + rte_loaded = 0; - waypoints = avltree_init(0, MYNAME); - if (! keys) - osm_features_init(); + waypoints = avltree_init(0, MYNAME); + if (! keys) { + osm_features_init(); + } - xml_init(fname, osm_map, NULL); + xml_init(fname, osm_map, NULL); } -static void +static void osm_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void osm_rd_deinit(void) { - xml_deinit(); - avltree_done(waypoints); + xml_deinit(); + avltree_done(waypoints); } /*******************************************************************************/ @@ -716,269 +714,291 @@ osm_rd_deinit(void) static void osm_init_icons(void) { - int i; + int i; - if (icons) return; + if (icons) { + return; + } - icons = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); + icons = avltree_init(AVLTREE_STATIC_KEYS, MYNAME); - for (i = 0; osm_icon_mappings[i].value; i++) - avltree_insert(icons, osm_icon_mappings[i].icon, (const void *)&osm_icon_mappings[i]); + for (i = 0; osm_icon_mappings[i].value; i++) { + avltree_insert(icons, osm_icon_mappings[i].icon, (const void *)&osm_icon_mappings[i]); + } } static void osm_write_tag(const char *key, const char *value) { - if (value && *value) { - char *str = xml_entitize(value); - gbfprintf(fout, " \n", key, str); - xfree(str); - } + if (value && *value) { + char *str = xml_entitize(value); + gbfprintf(fout, " \n", key, str); + xfree(str); + } } static void osm_disp_feature(const waypoint *wpt) { - osm_icon_mapping_t *map; - - if (avltree_find(icons, wpt->icon_descr, (void *) &map)) - osm_write_tag(osm_features[map->key], map->value); + osm_icon_mapping_t *map; + + if (avltree_find(icons, wpt->icon_descr, (void *) &map)) { + osm_write_tag(osm_features[map->key], map->value); + } } static void osm_write_opt_tag(const char *atag) { - char *tag, *cin, *ce; - - if (!atag) return; - - tag = cin = xstrdup(atag); - ce = cin + strlen(cin); - - while (cin < ce) { - char *sc, *dp; - - if ((sc = strchr(cin, ';'))) *sc = '\0'; - - if ((dp = strchr(cin, ':'))) { - *dp++ = '\0'; - osm_write_tag(cin, dp); - } - cin += strlen(cin) + 1; - } - - xfree(tag); + char *tag, *cin, *ce; + + if (!atag) { + return; + } + + tag = cin = xstrdup(atag); + ce = cin + strlen(cin); + + while (cin < ce) { + char *sc, *dp; + + if ((sc = strchr(cin, ';'))) { + *sc = '\0'; + } + + if ((dp = strchr(cin, ':'))) { + *dp++ = '\0'; + osm_write_tag(cin, dp); + } + cin += strlen(cin) + 1; + } + + xfree(tag); } static void osm_release_ids(const waypoint *wpt) { - if (wpt && wpt->extra_data) { - waypoint *tmp = (waypoint *)wpt; - xfree(tmp->extra_data); - tmp->extra_data = NULL; - } + if (wpt && wpt->extra_data) { + waypoint *tmp = (waypoint *)wpt; + xfree(tmp->extra_data); + tmp->extra_data = NULL; + } } static void osm_waypt_disp(const waypoint *wpt) { - char *buff; - - xasprintf(&buff, "%s\01%f\01%f", (wpt->shortname) ? wpt->shortname : "", - wpt->latitude, wpt->longitude); - - if (avltree_insert(waypoints, buff, (const void *) wpt)) { - int *id; - - id = xmalloc(sizeof(*id)); - *id = --node_id; - ((waypoint *)(wpt))->extra_data = id; - - gbfprintf(fout, " latitude, wpt->longitude); - if (wpt->creation_time) { - char time_string[64]; - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); - gbfprintf(fout, " timestamp='%s'", time_string); - } - gbfprintf(fout, ">\n"); - - if (wpt->hdop) { - gbfprintf(fout, " \n", wpt->hdop); - } - if (wpt->vdop) { - gbfprintf(fout, " \n", wpt->vdop); - } - if (wpt->pdop) { - gbfprintf(fout, " \n", wpt->pdop); - } - if (wpt->sat > 0) { - gbfprintf(fout, " \n", wpt->sat); - } - - switch (wpt->fix) { - case fix_2d: - gbfprintf(fout, " \n"); - break; - case fix_3d: - gbfprintf(fout, " \n"); - break; - case fix_dgps: - gbfprintf(fout, " \n"); - break; - case fix_pps: - gbfprintf(fout, " \n"); - break; - case fix_none: - gbfprintf(fout, " \n"); - break; - case fix_unknown: - default: - break; - } - - if (strlen(created_by) !=0) { - gbfprintf(fout, " \n"); - } - - osm_write_tag("name", wpt->shortname); - osm_write_tag("note", (wpt->notes) ? wpt->notes : wpt->description); - if (wpt->icon_descr) - osm_disp_feature(wpt); - - osm_write_opt_tag(opt_tagnd); - - gbfprintf(fout, " \n"); - } - - xfree(buff); + char *buff; + + xasprintf(&buff, "%s\01%f\01%f", (wpt->shortname) ? wpt->shortname : "", + wpt->latitude, wpt->longitude); + + if (avltree_insert(waypoints, buff, (const void *) wpt)) { + int *id; + + id = xmalloc(sizeof(*id)); + *id = --node_id; + ((waypoint *)(wpt))->extra_data = id; + + gbfprintf(fout, " latitude, wpt->longitude); + if (wpt->creation_time) { + char time_string[64]; + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + gbfprintf(fout, " timestamp='%s'", time_string); + } + gbfprintf(fout, ">\n"); + + if (wpt->hdop) { + gbfprintf(fout, " \n", wpt->hdop); + } + if (wpt->vdop) { + gbfprintf(fout, " \n", wpt->vdop); + } + if (wpt->pdop) { + gbfprintf(fout, " \n", wpt->pdop); + } + if (wpt->sat > 0) { + gbfprintf(fout, " \n", wpt->sat); + } + + switch (wpt->fix) { + case fix_2d: + gbfprintf(fout, " \n"); + break; + case fix_3d: + gbfprintf(fout, " \n"); + break; + case fix_dgps: + gbfprintf(fout, " \n"); + break; + case fix_pps: + gbfprintf(fout, " \n"); + break; + case fix_none: + gbfprintf(fout, " \n"); + break; + case fix_unknown: + default: + break; + } + + if (strlen(created_by) !=0) { + gbfprintf(fout, " \n"); + } + + osm_write_tag("name", wpt->shortname); + osm_write_tag("note", (wpt->notes) ? wpt->notes : wpt->description); + if (wpt->icon_descr) { + osm_disp_feature(wpt); + } + + osm_write_opt_tag(opt_tagnd); + + gbfprintf(fout, " \n"); + } + + xfree(buff); } static void osm_rte_disp_head(const route_head *rte) { - skip_rte = (rte->rte_waypt_ct <= 0); - - if (skip_rte) return; + skip_rte = (rte->rte_waypt_ct <= 0); + + if (skip_rte) { + return; + } - gbfprintf(fout, " \n", --node_id); + gbfprintf(fout, " \n", --node_id); } static void osm_rtept_disp(const waypoint *wpt_ref) { - char *buff; - waypoint *wpt; - - if (skip_rte) return; - - xasprintf(&buff, "%s\01%f\01%f", (wpt_ref->shortname) ? wpt_ref->shortname : "", - wpt_ref->latitude, wpt_ref->longitude); - - if (avltree_find(waypoints, buff, (void *) &wpt)) { - int *id = wpt->extra_data; - gbfprintf(fout, " \n", *id); - } - - xfree(buff); -} + char *buff; + waypoint *wpt; -static void -osm_rte_disp_trail(const route_head *rte) -{ - if (skip_rte) return; + if (skip_rte) { + return; + } - if (strlen(created_by) !=0) { - gbfprintf(fout, " \n"); - } + xasprintf(&buff, "%s\01%f\01%f", (wpt_ref->shortname) ? wpt_ref->shortname : "", + wpt_ref->latitude, wpt_ref->longitude); - osm_write_tag("name", rte->rte_name); - osm_write_tag("note", rte->rte_desc); + if (avltree_find(waypoints, buff, (void *) &wpt)) { + int *id = wpt->extra_data; + gbfprintf(fout, " \n", *id); + } - if (opt_tag && (case_ignore_strncmp(opt_tag, "tagnd", 5) != 0)) - osm_write_opt_tag(opt_tag); + xfree(buff); +} - gbfprintf(fout, " \n"); +static void +osm_rte_disp_trail(const route_head *rte) +{ + if (skip_rte) { + return; + } + + if (strlen(created_by) !=0) { + gbfprintf(fout, " \n"); + } + + osm_write_tag("name", rte->rte_name); + osm_write_tag("note", rte->rte_desc); + + if (opt_tag && (case_ignore_strncmp(opt_tag, "tagnd", 5) != 0)) { + osm_write_opt_tag(opt_tag); + } + + gbfprintf(fout, " \n"); } /*-----------------------------------------------------------------------------*/ -static void +static void osm_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); - osm_init_icons(); - waypoints = avltree_init(0, MYNAME); - node_id = 0; + osm_init_icons(); + waypoints = avltree_init(0, MYNAME); + node_id = 0; } -static void +static void osm_write(void) { - gbfprintf(fout, "\n"); - gbfprintf(fout, "\n"); - - waypt_disp_all(osm_waypt_disp); - route_disp_all(NULL, NULL, osm_waypt_disp); - track_disp_all(NULL, NULL, osm_waypt_disp); - - route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); - track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); - - gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + gbfprintf(fout, "\n"); + + waypt_disp_all(osm_waypt_disp); + route_disp_all(NULL, NULL, osm_waypt_disp); + track_disp_all(NULL, NULL, osm_waypt_disp); + + route_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + track_disp_all(osm_rte_disp_head, osm_rte_disp_trail, osm_rtept_disp); + + gbfprintf(fout, "\n"); } -static void +static void osm_wr_deinit(void) { - gbfclose(fout); - - waypt_disp_all(osm_release_ids); - route_disp_all(NULL, NULL, osm_release_ids); - track_disp_all(NULL, NULL, osm_release_ids); + gbfclose(fout); + + waypt_disp_all(osm_release_ids); + route_disp_all(NULL, NULL, osm_release_ids); + track_disp_all(NULL, NULL, osm_release_ids); - avltree_done(waypoints); + avltree_done(waypoints); } static void osm_exit(void) { - if (keys) - avltree_done(keys); - if (values) - avltree_done(values); - if (icons) - avltree_done(icons); + if (keys) { + avltree_done(keys); + } + if (values) { + avltree_done(values); + } + if (icons) { + avltree_done(icons); + } } /*-----------------------------------------------------------------------------*/ ff_vecs_t osm_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_write /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - osm_rd_init, - osm_wr_init, - osm_rd_deinit, - osm_wr_deinit, - osm_read, - osm_write, - osm_exit, - osm_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_write /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + osm_rd_init, + osm_wr_init, + osm_rd_deinit, + osm_wr_deinit, + osm_read, + osm_write, + osm_exit, + osm_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/overlay.c b/gpsbabel/overlay.c index 20b92674c..6432c6a1b 100644 --- a/gpsbabel/overlay.c +++ b/gpsbabel/overlay.c @@ -77,49 +77,69 @@ static char *govl_txttrans_s = NULL; static char *govl_file_s = NULL; static arglist_t ovl_args[] = { - { "col", &govl_col_s, "color index [1-9] for routes", - NULL, ARGTYPE_INT, "1", "9" }, - { "size", &govl_size_s, "size index [101-] for routes", - NULL, ARGTYPE_INT, "101", NULL }, - { "mapname", &govl_mapname, "name of map", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", - NULL, ARGTYPE_INT, ARG_NOMINMAX }, - { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", - NULL, ARGTYPE_INT, "1", "9" }, - { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", - NULL, ARGTYPE_INT, "101", NULL }, - { "font", &govl_font_s, "font index [1-] for waypoint names", - NULL, ARGTYPE_INT, "1", NULL }, - { "txttrans", &govl_txttrans_s, "set text background to transparent", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", - NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "col", &govl_col_s, "color index [1-9] for routes", + NULL, ARGTYPE_INT, "1", "9" + }, + { + "size", &govl_size_s, "size index [101-] for routes", + NULL, ARGTYPE_INT, "101", NULL + }, + { + "mapname", &govl_mapname, "name of map", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "zoomfc", &govl_zoomfc_s, "zoom factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %", + NULL, ARGTYPE_INT, ARG_NOMINMAX + }, + { + "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names", + NULL, ARGTYPE_INT, "1", "9" + }, + { + "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names", + NULL, ARGTYPE_INT, "101", NULL + }, + { + "font", &govl_font_s, "font index [1-] for waypoint names", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "txttrans", &govl_txttrans_s, "set text background to transparent", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static char *Keywords[]={ - "Typ", - "Group", - "Col", - "Zoom", - "Size", - "Art", - "Punkte", - "Path", - "Dir", - "Font", - "Area", - "Text", - "Width", - "Height", - "Trans", - "TransByte", - NULL - }; +static char *Keywords[]= { + "Typ", + "Group", + "Col", + "Zoom", + "Size", + "Art", + "Punkte", + "Path", + "Dir", + "Font", + "Area", + "Text", + "Width", + "Height", + "Trans", + "TransByte", + NULL +}; #define KEY_TYP 0 #define KEY_GROUP 1 @@ -143,7 +163,9 @@ static int isKeyword(char *str,char **keys) int i; i = 0; - while(keys[i]!=NULL && strcmp(str,keys[i])) i++; + while (keys[i]!=NULL && strcmp(str,keys[i])) { + i++; + } return(keys[i]==NULL ? -1 : i); } @@ -163,9 +185,9 @@ void ovl_rd_init(char const *fname) #define MAXLINE 512 static struct _group { - int group; - char *name; - } *groups; + int group; + char *name; +} *groups; static int groups_cnt; static void ovl_add_group(int aktgrp,char *akttxt) @@ -173,9 +195,10 @@ static void ovl_add_group(int aktgrp,char *akttxt) int i; i = 0; - while (irte_name); i = 0; - while (irte_name = (char *) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char)); @@ -238,160 +260,151 @@ static void ovl_read(void) aktPath = NULL; sym_cnt = 0; isSection = SECTION_NONE; - while ((line = gbfgetstr(fpin))) - { - if ((lineno == 0) && fpin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + while ((line = gbfgetstr(fpin))) { + if ((lineno == 0) && fpin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } lineno++; line = lrtrim(line); - if( (pstr = strstr(line,"[Symbol "))!= NULL) - { + if ((pstr = strstr(line,"[Symbol "))!= NULL) { sym_cnt++; isSection = SECTION_SYMBOL; - } - else if( (pstr = strstr(line,"[Overlay]"))!= NULL) - { + } else if ((pstr = strstr(line,"[Overlay]"))!= NULL) { isSection = SECTION_OVERLAY; - } - else if (isSection==SECTION_SYMBOL) - { + } else if (isSection==SECTION_SYMBOL) { pstr = strtok(line,"="); - if (pstr!=NULL) - { + if (pstr!=NULL) { keyw = isKeyword(pstr,Keywords); pstr = strtok(NULL,"\n"); - if (pstr!=NULL) - { - switch(keyw) - { - case KEY_TYP : - aktTyp = atoi(pstr); - break; - case KEY_GROUP : - aktGroup = atoi(pstr); - ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */ - switch(aktTyp) - { - case 3: // Linie - route_head = route_head_alloc(); - route_head->rte_num = sym_cnt; - route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */ - route_add_head(route_head); - break; - } - break; - case KEY_COL : - aktCol = atoi(pstr); - break; - case KEY_ZOOM : - break; - case KEY_SIZE : - aktSize = atoi(pstr); - break; - case KEY_ART : - aktArt = atoi(pstr); - break; - case KEY_AREA : - aktArea = atoi(pstr); - if (aktTyp==5 || aktTyp==5 || aktTyp==7) isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck - break; - case KEY_PUNKTE : - isSection = SECTION_PUNKTE; // Linie, Fläche + if (pstr!=NULL) { + switch (keyw) { + case KEY_TYP : + aktTyp = atoi(pstr); + break; + case KEY_GROUP : + aktGroup = atoi(pstr); + ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */ + switch (aktTyp) { + case 3: // Linie + route_head = route_head_alloc(); + route_head->rte_num = sym_cnt; + route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */ + route_add_head(route_head); break; + } + break; + case KEY_COL : + aktCol = atoi(pstr); + break; + case KEY_ZOOM : + break; + case KEY_SIZE : + aktSize = atoi(pstr); + break; + case KEY_ART : + aktArt = atoi(pstr); + break; + case KEY_AREA : + aktArea = atoi(pstr); + if (aktTyp==5 || aktTyp==5 || aktTyp==7) { + isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck + } + break; + case KEY_PUNKTE : + isSection = SECTION_PUNKTE; // Linie, Fläche + break; #ifdef WITH_BITMAP - case KEY_PATH : - aktPath = xstrdup(pstr); - isSection = SECTION_PUNKTE; // Bitmap - break; - case KEY_TRANS : - aktTrans = atoi(pstr); - break; - case KEY_TRANSBYTE : - aktTransByte = atoi(pstr); - break; + case KEY_PATH : + aktPath = xstrdup(pstr); + isSection = SECTION_PUNKTE; // Bitmap + break; + case KEY_TRANS : + aktTrans = atoi(pstr); + break; + case KEY_TRANSBYTE : + aktTransByte = atoi(pstr); + break; #endif - case KEY_TEXT : - aktText = xstrdup(pstr); - /* The last 'Text'-symbol wins as a information block for - waypoint/route description. - Infos from previous symbols get overwrited. - */ - ovl_add_group(aktGroup,aktText); - break; - case KEY_WIDTH : - aktWidth = atoi(pstr); - break; - case KEY_HEIGHT : - aktHeight = atoi(pstr); - break; - case KEY_DIR : - aktDir = atoi(pstr); - if (aktTyp==2) isSection = SECTION_PUNKTE; // Text - break; + case KEY_TEXT : + aktText = xstrdup(pstr); + /* The last 'Text'-symbol wins as a information block for + waypoint/route description. + Infos from previous symbols get overwrited. + */ + ovl_add_group(aktGroup,aktText); + break; + case KEY_WIDTH : + aktWidth = atoi(pstr); + break; + case KEY_HEIGHT : + aktHeight = atoi(pstr); + break; + case KEY_DIR : + aktDir = atoi(pstr); + if (aktTyp==2) { + isSection = SECTION_PUNKTE; // Text + } + break; } } } - } - else if (isSection==SECTION_PUNKTE) - { + } else if (isSection==SECTION_PUNKTE) { pstr = strtok(line,"="); - if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) - { - if ((pstr = strtok(NULL,"\n"))!=NULL) - { + if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL) { + if ((pstr = strtok(NULL,"\n"))!=NULL) { rwert = atof(pstr); - if (line[0]=='X') - { + if (line[0]=='X') { aktX = rwert; - } - else if (line[0]=='Y') - { + } else if (line[0]=='Y') { aktY = rwert; - switch(aktTyp) - { + switch (aktTyp) { #ifdef WITH_BITMAP - case 1: // Bitmap - wpt = waypt_new(); - wpt->latitude = aktY; - wpt->longitude = aktX; - wpt->altitude = 0.0; - wpt->shortname = strdup(aktPath); - waypt_add(wpt); - break; + case 1: // Bitmap + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + wpt->shortname = strdup(aktPath); + waypt_add(wpt); + break; #endif - case 2: // Text - isSection = SECTION_SYMBOL; - break; - case 3: // Linie - wpt = waypt_new(); - wpt->latitude = aktY; - wpt->longitude = aktX; - wpt->altitude = 0.0; - route_add_wpt(route_head, wpt); - break; - case 4: // Fläche - break; - case 5: // Rechteck - break; - case 6: // Kreis - break; - case 7: // Dreieck - break; + case 2: // Text + isSection = SECTION_SYMBOL; + break; + case 3: // Linie + wpt = waypt_new(); + wpt->latitude = aktY; + wpt->longitude = aktX; + wpt->altitude = 0.0; + route_add_wpt(route_head, wpt); + break; + case 4: // Fläche + break; + case 5: // Rechteck + break; + case 6: // Kreis + break; + case 7: // Dreieck + break; } } } } - } - else if (isSection==SECTION_OVERLAY) - { + } else if (isSection==SECTION_OVERLAY) { isSection = SECTION_NONE; } } route_disp_all(route_add_name,NULL,NULL); - if (aktText!=NULL) xfree(aktText); - if (aktPath!=NULL) xfree(aktPath); - for (i=0;iargstring!=NULL) - { - if (strcmp(pstr,p->argstring)==0) - { + if (pstr!=NULL) { + while (p->argstring!=NULL) { + if (strcmp(pstr,p->argstring)==0) { pstr = strtok(NULL,"\n"); - if (p->argtype==ARGTYPE_BOOL) - { + if (p->argtype==ARGTYPE_BOOL) { *(p->argval) = atoi(pstr) ? xstrdup(pstr) : NULL; - } - else - { + } else { *(p->argval) = xstrdup(pstr); } break; @@ -456,40 +460,31 @@ static void ovl_wr_init(const char *fname) ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE); - if (govl_col_s!=NULL) - { + if (govl_col_s!=NULL) { govl_col = atoi(govl_col_s); } - if (govl_size_s!=NULL) - { + if (govl_size_s!=NULL) { govl_size = atoi(govl_size_s); } - if (govl_mapname==NULL) - { + if (govl_mapname==NULL) { govl_mapname = xstrdup(MAPNAME); } - if (govl_zoomfc_s!=NULL) - { + if (govl_zoomfc_s!=NULL) { govl_zoomfc = atoi(govl_zoomfc_s); } - if (govl_dimmfc_s!=NULL) - { + if (govl_dimmfc_s!=NULL) { govl_dimmfc = atoi(govl_dimmfc_s); } - if (govl_txtcol_s!=NULL) - { + if (govl_txtcol_s!=NULL) { govl_txtcol = atoi(govl_txtcol_s); } - if (govl_txtsize_s!=NULL) - { + if (govl_txtsize_s!=NULL) { govl_txtsize = atoi(govl_txtsize_s); } - if (govl_font_s!=NULL) - { + if (govl_font_s!=NULL) { govl_font = atoi(govl_font_s); } - if (govl_txttrans_s!=NULL) - { + if (govl_txttrans_s!=NULL) { govl_txttrans = 1; } } @@ -502,13 +497,10 @@ static void ovl_wr_deinit(void) gbfprintf(fpout,"MapName=%s\n",govl_mapname); gbfprintf(fpout,"DimmFc=%d\n",govl_dimmfc); gbfprintf(fpout,"ZoomFc=%d\n",govl_zoomfc); - if (govl_symbol_cnt) - { + if (govl_symbol_cnt) { gbfprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm gbfprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt); - } - else - { + } else { gbfprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger Löwe, Mittelpunkt der Welt :-) gbfprintf(fpout,"CenterLat=52.26474445\n"); } @@ -561,10 +553,10 @@ static void symbol_point(const waypoint *wpt) govl_sum_e += east; govl_sum_n += north; govl_sumcnt += 1.0; -/* - govl_last_east = east; - govl_last_north = north; -*/ + /* + govl_last_east = east; + govl_last_north = north; + */ } @@ -581,18 +573,14 @@ static void symbol_deinit(const route_head *hd) lats = lons = late = lone = 0.0; dist = 0.0; i = 0; - QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) - { + QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp) { waypointp = (waypoint *) elem; lat2 = RAD(waypointp->latitude); lon2 = RAD(waypointp->longitude); - if (i) - { - d = gcdist(lat1, lon1, lat2, lon2 ); + if (i) { + d = gcdist(lat1, lon1, lat2, lon2); dist += d; - } - else - { + } else { lats = lat2; // start point lons = lon2; } @@ -605,14 +593,12 @@ static void symbol_deinit(const route_head *hd) dd = 0; i = 0; elem = QUEUE_FIRST(&(hd->waypoint_list)); - while (elem!=&(hd->waypoint_list) && ddwaypoint_list) && ddlatitude); lon2 = RAD(waypointp->longitude); - if (i) - { - d = gcdist(lat1, lon1, lat2, lon2 ); + if (i) { + d = gcdist(lat1, lon1, lat2, lon2); dd += d; } lat1 = lat2; @@ -623,8 +609,10 @@ static void symbol_deinit(const route_head *hd) d = gcdist(lats,lons,late,lone); // d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) ); - dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) ); - if (loneshortname; } oname = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, odesc) : - waypointp->shortname; + mkshort(mkshort_handle, odesc) : + waypointp->shortname; gbfprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1); gbfprintf(fpout,"Typ=1\n"); @@ -680,28 +668,28 @@ static void ovl_write(void) waypt_disp_all(overlay_waypt_pr); track_disp_all(symbol_init, symbol_deinit, symbol_point); route_disp_all(symbol_init, symbol_deinit, symbol_point); -/* - switch(global_opts.objective) - { - case wptdata: - break; - case trkdata: - break; - } -*/ + /* + switch(global_opts.objective) + { + case wptdata: + break; + case trkdata: + break; + } + */ } ff_vecs_t overlay_vecs = { - ff_type_internal, - FF_CAP_RW_ALL, - ovl_rd_init, - ovl_wr_init, - ovl_rd_deinit, - ovl_wr_deinit, - ovl_read, - ovl_write, - NULL, - ovl_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_internal, + FF_CAP_RW_ALL, + ovl_rd_init, + ovl_wr_init, + ovl_rd_deinit, + ovl_wr_deinit, + ovl_read, + ovl_write, + NULL, + ovl_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/ozi.c b/gpsbabel/ozi.c index 2e8fc68b3..0aee09616 100644 --- a/gpsbabel/ozi.c +++ b/gpsbabel/ozi.c @@ -1,6 +1,6 @@ /* OziExplorer Waypoints/Tracks/Routes - Comma Delimited + Comma Delimited As described in OziExplorer Help File @@ -33,9 +33,9 @@ #define DAYS_SINCE_1990 25569 typedef struct { - format_specific_data fs; - int fgcolor; - int bgcolor; + format_specific_data fs; + int fgcolor; + int bgcolor; } ozi_fsdata; @@ -68,27 +68,47 @@ static double prox_scale; static arglist_t ozi_args[] = { - {"pack", &pack_opt, "Write all tracks into one file", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snlen", &snlenopt, "Max synthesized shortname length", - "32", ARGTYPE_INT, "1", NULL}, - {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snupper", &snupperopt, "UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snunique", &snuniqueopt, "Make synth. shortnames unique", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"wptfgcolor", &wptfgcolor, "Waypoint foreground color", - "black", ARGTYPE_STRING, ARG_NOMINMAX}, - {"wptbgcolor", &wptbgcolor, "Waypoint background color", - "yellow", ARGTYPE_STRING, ARG_NOMINMAX}, - {"proximity", &proximityarg, "Proximity distance", - "0", ARGTYPE_STRING, ARG_NOMINMAX}, - {"altunit", &altunit_opt, "Unit used in altitude values", - "feet", ARGTYPE_STRING, ARG_NOMINMAX}, - {"proxunit", &proxunit_opt, "Unit used in proximity values", - "miles", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "pack", &pack_opt, "Write all tracks into one file", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snlen", &snlenopt, "Max synthesized shortname length", + "32", ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "wptfgcolor", &wptfgcolor, "Waypoint foreground color", + "black", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "wptbgcolor", &wptbgcolor, "Waypoint background color", + "yellow", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "proximity", &proximityarg, "Proximity distance", + "0", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "altunit", &altunit_opt, "Unit used in altitude values", + "feet", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "proxunit", &proxunit_opt, "Unit used in proximity values", + "miles", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static gpsdata_type ozi_objective; @@ -96,169 +116,177 @@ static gpsdata_type ozi_objective; static char *ozi_ofname = NULL; static void -ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) +ozi_copy_fsdata(ozi_fsdata **dest, ozi_fsdata *src) { - /* No strings to mess with. Straight forward copy. */ - *dest = (void *)xmalloc(sizeof(*src)); - **dest = *src; - (*dest)->fs.next = NULL; + /* No strings to mess with. Straight forward copy. */ + *dest = (void *)xmalloc(sizeof(*src)); + **dest = *src; + (*dest)->fs.next = NULL; } static void ozi_free_fsdata(void *fsdata) { - xfree(fsdata); + xfree(fsdata); } static ozi_fsdata * -ozi_alloc_fsdata(void) +ozi_alloc_fsdata(void) { - ozi_fsdata *fsdata = xcalloc(sizeof(*fsdata), 1); - fsdata->fs.type = FS_OZI; - fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; - fsdata->fs.destroy = ozi_free_fsdata; - fsdata->fs.convert = NULL; + ozi_fsdata *fsdata = xcalloc(sizeof(*fsdata), 1); + fsdata->fs.type = FS_OZI; + fsdata->fs.copy = (fs_copy) ozi_copy_fsdata; + fsdata->fs.destroy = ozi_free_fsdata; + fsdata->fs.convert = NULL; - /* Provide defaults via command line defaults */ - fsdata->fgcolor = color_to_bbggrr(wptfgcolor); - fsdata->bgcolor = color_to_bbggrr(wptbgcolor); + /* Provide defaults via command line defaults */ + fsdata->fgcolor = color_to_bbggrr(wptfgcolor); + fsdata->bgcolor = color_to_bbggrr(wptbgcolor); - return fsdata; + return fsdata; } void ozi_get_time_str(const waypoint *waypointp, char *buff, gbsize_t buffsz) { - if (waypointp->creation_time) { - double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; - snprintf(buff, buffsz, "%.7f", time); - } - else *buff = '\0'; + if (waypointp->creation_time) { + double time = (waypt_time(waypointp) / SECONDS_PER_DAY) + DAYS_SINCE_1990; + snprintf(buff, buffsz, "%.7f", time); + } else { + *buff = '\0'; + } } void ozi_set_time_str(const char *str, waypoint *waypointp) { - double ozi_time; - char *dot; - int len; - - ozi_time = atof(str); - waypointp->creation_time = (ozi_time - DAYS_SINCE_1990) * SECONDS_PER_DAY; - - dot = strchr(str, '.'); - /* get number of characters after dot */ - len = (dot) ? strlen(str) - (dot - str) - 1 : 0; - if (len >= 7) { - /* with default ozi time precision (%.7f) we can only handle tenths of second */ - ozi_time -= ((double)waypointp->creation_time / SECONDS_PER_DAY ) + DAYS_SINCE_1990; - ozi_time *= SECONDS_PER_DAY; - waypointp->microseconds = (ozi_time * 10) + 0.5; - if (waypointp->microseconds == 10) { - waypointp->creation_time++; - waypointp->microseconds = 0; - } - waypointp->microseconds *= 100000; - } + double ozi_time; + char *dot; + int len; + + ozi_time = atof(str); + waypointp->creation_time = (ozi_time - DAYS_SINCE_1990) * SECONDS_PER_DAY; + + dot = strchr(str, '.'); + /* get number of characters after dot */ + len = (dot) ? strlen(str) - (dot - str) - 1 : 0; + if (len >= 7) { + /* with default ozi time precision (%.7f) we can only handle tenths of second */ + ozi_time -= ((double)waypointp->creation_time / SECONDS_PER_DAY) + DAYS_SINCE_1990; + ozi_time *= SECONDS_PER_DAY; + waypointp->microseconds = (ozi_time * 10) + 0.5; + if (waypointp->microseconds == 10) { + waypointp->creation_time++; + waypointp->microseconds = 0; + } + waypointp->microseconds *= 100000; + } } static void ozi_convert_datum(waypoint *wpt) { - if (datum != DATUM_WGS84) { - double lat, lon, alt; - GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, - &lat, &lon, &alt, datum); - wpt->latitude = lat; - wpt->longitude = lon; - } + if (datum != DATUM_WGS84) { + double lat, lon, alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, 0.0, + &lat, &lon, &alt, datum); + wpt->latitude = lat; + wpt->longitude = lon; + } } static void -ozi_openfile(char *fname) { - char *c, *cx, *tmpname; - char *ozi_extensions[] = {0, "plt", "wpt", "rte"}; - char buff[32]; - - /* if we're doing multi-track output, sequence the filenames like: - * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. - */ - - if (0 == strcmp(fname, "-")) { - if (! file_out) { - file_out = gbfopen(fname, "wb", MYNAME); - } - return; - } +ozi_openfile(char *fname) +{ + char *c, *cx, *tmpname; + char *ozi_extensions[] = {0, "plt", "wpt", "rte"}; + char buff[32]; - if ((track_out_count) && (ozi_objective == trkdata)) { - sprintf(buff, "-%d", track_out_count); - } else { - buff[0] = '\0'; - } + /* if we're doing multi-track output, sequence the filenames like: + * mytrack.plt, mytrack-1.plt...unless we're writing to stdout. + */ - /* remove extension and add buff + ozi's extension */ - c = strrchr(fname, '.'); - if (c && (cx = strrchr(fname, '/')) && (cx > c)) c = NULL; - if (c && (cx = strrchr(fname, '\\')) && (cx > c)) c = NULL; - if (c == NULL) c = fname + strlen(fname); - xasprintf(&tmpname, "%*.*s%s.%s", c - fname, c - fname, fname, buff, ozi_extensions[ozi_objective]); - - /* re-open file_out with the new filename */ - if (file_out) { - gbfclose(file_out); - file_out = NULL; + if (0 == strcmp(fname, "-")) { + if (! file_out) { + file_out = gbfopen(fname, "wb", MYNAME); } + return; + } + + if ((track_out_count) && (ozi_objective == trkdata)) { + sprintf(buff, "-%d", track_out_count); + } else { + buff[0] = '\0'; + } + + /* remove extension and add buff + ozi's extension */ + c = strrchr(fname, '.'); + if (c && (cx = strrchr(fname, '/')) && (cx > c)) { + c = NULL; + } + if (c && (cx = strrchr(fname, '\\')) && (cx > c)) { + c = NULL; + } + if (c == NULL) { + c = fname + strlen(fname); + } + xasprintf(&tmpname, "%*.*s%s.%s", c - fname, c - fname, fname, buff, ozi_extensions[ozi_objective]); + + /* re-open file_out with the new filename */ + if (file_out) { + gbfclose(file_out); + file_out = NULL; + } - file_out = gbfopen(tmpname, "wb", MYNAME); + file_out = gbfopen(tmpname, "wb", MYNAME); - xfree(tmpname); + xfree(tmpname); - return; + return; } -static void +static void ozi_track_hdr(const route_head * rte) { - static char *ozi_trk_header = - "OziExplorer Track Point File Version 2.1\r\n" - "WGS 84\r\n" - "Altitude is in %s\r\n" - "Reserved 3\r\n" - "0,2,255,%s,0,0,2,8421376\r\n" - "0\r\n"; - - if ((! pack_opt) || (track_out_count == 0)) { - ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_trk_header, - altunit == 'f' ? "Feet" : "Meters", - rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); - } - - track_out_count++; - new_track = 1; + static char *ozi_trk_header = + "OziExplorer Track Point File Version 2.1\r\n" + "WGS 84\r\n" + "Altitude is in %s\r\n" + "Reserved 3\r\n" + "0,2,255,%s,0,0,2,8421376\r\n" + "0\r\n"; + + if ((! pack_opt) || (track_out_count == 0)) { + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_trk_header, + altunit == 'f' ? "Feet" : "Meters", + rte->rte_name ? rte->rte_name : "ComplimentsOfGPSBabel"); + } + + track_out_count++; + new_track = 1; } -static void +static void ozi_track_disp(const waypoint * waypointp) { - double alt; - char ozi_time[16]; + double alt; + char ozi_time[16]; - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); - if (waypointp->altitude == unknown_alt) { - alt = -777; - } else { - alt = waypointp->altitude * alt_scale; - } + if (waypointp->altitude == unknown_alt) { + alt = -777; + } else { + alt = waypointp->altitude * alt_scale; + } - gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", - waypointp->latitude, waypointp->longitude, new_track, - alt, ozi_time); + gbfprintf(file_out, "%.6f,%.6f,%d,%.0f,%s,,\r\n", + waypointp->latitude, waypointp->longitude, new_track, + alt, ozi_time); - new_track = 0; + new_track = 0; } static void @@ -266,86 +294,86 @@ ozi_track_tlr(const route_head * rte) { } -static void +static void ozi_track_pr() { - track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); + track_disp_all(ozi_track_hdr, ozi_track_tlr, ozi_track_disp); } static void ozi_route_hdr(const route_head * rte) { - static char *ozi_route_header = - "OziExplorer Route File Version 1.0\r\n" - "WGS 84\r\n" - "Reserved 1\r\n" - "Reserved 2\r\n"; - - /* prologue on 1st pass only */ - if (route_out_count == 0) { - gbfprintf(file_out, ozi_route_header); - } - - route_out_count++; - route_wpt_count = 0; - - /* - * Route Record - * Field 1 : R - indicating route details - * Field 2 : Number - this is the location in the array, must be unique, usually start at 0 for Garmins 1 for other and increment. - * Field 3 : Name - the waypoint name, use the correct length name to suit the GPS type. - * Field 4 : Description. - * Field 5 : Route Color as displayed on map (RGB). - * - * R, 0,R0 ,,255 - * R, 1, ICP GALHETA,, 16711680 - */ - - gbfprintf(file_out, "R,%d,%s,%s,\r\n", - route_out_count, - rte->rte_name ? rte->rte_name : "", - rte->rte_desc ? rte->rte_desc : ""); + static char *ozi_route_header = + "OziExplorer Route File Version 1.0\r\n" + "WGS 84\r\n" + "Reserved 1\r\n" + "Reserved 2\r\n"; + + /* prologue on 1st pass only */ + if (route_out_count == 0) { + gbfprintf(file_out, ozi_route_header); + } + + route_out_count++; + route_wpt_count = 0; + + /* + * Route Record + * Field 1 : R - indicating route details + * Field 2 : Number - this is the location in the array, must be unique, usually start at 0 for Garmins 1 for other and increment. + * Field 3 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 4 : Description. + * Field 5 : Route Color as displayed on map (RGB). + * + * R, 0,R0 ,,255 + * R, 1, ICP GALHETA,, 16711680 + */ + + gbfprintf(file_out, "R,%d,%s,%s,\r\n", + route_out_count, + rte->rte_name ? rte->rte_name : "", + rte->rte_desc ? rte->rte_desc : ""); } static void ozi_route_disp(const waypoint * waypointp) { - double alt; - char ozi_time[16]; - - route_wpt_count++; - - ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); - - if (waypointp->altitude == unknown_alt) { - alt = -777; - } else { - alt = waypointp->altitude * alt_scale; - } - -/* - * Field 1 : W - indicating route waypoint details. - * Field 2 : Route Number - location in array of routes - * Field 3 : Number - this is the location in the array of route waypoints, this field is now ignored. - * Field 4 : Wp Number - this is the number of the waypoint (the Wp number within the GPS for lowrances) - * Field 5 : Name - the waypoint name, use the correct length name to suit the GPS type. - * Field 6 : Latitude - decimal degrees. - * Field 7 : Longitude - decimal degrees. - * Field 8 : Date - see Date Format below, if blank a preset date will be used - * Field 9 : Symbol - 0 to number of symbols in GPS - * Field 10 : Status - always set to 1 - * Field 11 : Map Display Format - * Field 12 : Foreground Color (RGB value) - * Field 13 : Background Color (RGB value) - * Field 14 : Description (max 40), no commas - * Field 15 : Pointer Direction - * Field 16 : Garmin Display Format - * - * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 - */ - - gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", + double alt; + char ozi_time[16]; + + route_wpt_count++; + + ozi_get_time_str(waypointp, ozi_time, sizeof(ozi_time)); + + if (waypointp->altitude == unknown_alt) { + alt = -777; + } else { + alt = waypointp->altitude * alt_scale; + } + + /* + * Field 1 : W - indicating route waypoint details. + * Field 2 : Route Number - location in array of routes + * Field 3 : Number - this is the location in the array of route waypoints, this field is now ignored. + * Field 4 : Wp Number - this is the number of the waypoint (the Wp number within the GPS for lowrances) + * Field 5 : Name - the waypoint name, use the correct length name to suit the GPS type. + * Field 6 : Latitude - decimal degrees. + * Field 7 : Longitude - decimal degrees. + * Field 8 : Date - see Date Format below, if blank a preset date will be used + * Field 9 : Symbol - 0 to number of symbols in GPS + * Field 10 : Status - always set to 1 + * Field 11 : Map Display Format + * Field 12 : Foreground Color (RGB value) + * Field 13 : Background Color (RGB value) + * Field 14 : Description (max 40), no commas + * Field 15 : Pointer Direction + * Field 16 : Garmin Display Format + * + * W,1,7,7,007,-25.581670,-48.316660,36564.54196,10,1,4,0,65535,TR ILHA GALHETA,0,0 + */ + + gbfprintf(file_out, "W,%d,%d,,%s,%.6f,%.6f,%s,0,1,3,0,65535,%s,0,0\r\n", route_out_count, route_wpt_count, waypointp->shortname ? waypointp->shortname : "", @@ -361,577 +389,602 @@ ozi_route_tlr(const route_head * rte) { } -static void +static void ozi_route_pr() { - route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); + route_disp_all(ozi_route_hdr, ozi_route_tlr, ozi_route_disp); } static void ozi_init_units(const int direction) /* 0 = in; 1 = out */ { - altunit = tolower(*altunit_opt); - switch(altunit) { - case 'm': /* meters, okay */ alt_scale = 1.0; break; - case 'f': /* feet, okay */ alt_scale = FEET_TO_METERS(1.0); break; - default: - fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt); - } - if (direction != 0) alt_scale = 1 / alt_scale; - - proxunit = tolower(*proxunit_opt); - switch(proxunit) { - case 'm': /* miles, okay */ prox_scale = MILES_TO_METERS(1.0); break; - case 'n': /* nautical miles, okay */ prox_scale = NMILES_TO_METERS(1.0); break; - case 'k': /* kilometers, okay */ prox_scale = 1000.0; break; - default: - fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt); - } - if (direction != 0) prox_scale = 1 / prox_scale; + altunit = tolower(*altunit_opt); + switch (altunit) { + case 'm': /* meters, okay */ + alt_scale = 1.0; + break; + case 'f': /* feet, okay */ + alt_scale = FEET_TO_METERS(1.0); + break; + default: + fatal(MYNAME ": Unknown value (%s) for option 'altunit'!\n", altunit_opt); + } + if (direction != 0) { + alt_scale = 1 / alt_scale; + } + + proxunit = tolower(*proxunit_opt); + switch (proxunit) { + case 'm': /* miles, okay */ + prox_scale = MILES_TO_METERS(1.0); + break; + case 'n': /* nautical miles, okay */ + prox_scale = NMILES_TO_METERS(1.0); + break; + case 'k': /* kilometers, okay */ + prox_scale = 1000.0; + break; + default: + fatal(MYNAME ": Unknown value (%s) for option 'proxunit'!\n", proxunit_opt); + } + if (direction != 0) { + prox_scale = 1 / prox_scale; + } } static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); - mkshort_handle = mkshort_new_handle(); - ozi_init_units(0); + mkshort_handle = mkshort_new_handle(); + ozi_init_units(0); } static void rd_deinit(void) { - gbfclose(file_in); - file_in = NULL; - mkshort_del_handle(&mkshort_handle); + gbfclose(file_in); + file_in = NULL; + mkshort_del_handle(&mkshort_handle); } static void wr_init(const char *fname) { - - /* At this point, we have no idea whether we'll be writing waypoint, - * route, or tracks. So we'll hold off opening any files until - * we're actually ready to write. - */ - ozi_ofname = (char *)fname; + /* At this point, we have no idea whether we'll be writing waypoint, + * route, or tracks. So we'll hold off opening any files until + * we're actually ready to write. + */ - mkshort_handle = mkshort_new_handle(); + ozi_ofname = (char *)fname; - /* set mkshort options from the command line if applicable */ - if (global_opts.synthesize_shortnames) { + mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, atoi(snlenopt)); + /* set mkshort options from the command line if applicable */ + if (global_opts.synthesize_shortnames) { - if (snwhiteopt) - setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + setshort_length(mkshort_handle, atoi(snlenopt)); - if (snupperopt) - setshort_mustupper(mkshort_handle, atoi(snupperopt)); + if (snwhiteopt) { + setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt)); + } - if (snuniqueopt) - setshort_mustuniq(mkshort_handle, atoi(snuniqueopt)); + if (snupperopt) { + setshort_mustupper(mkshort_handle, atoi(snupperopt)); + } - setshort_badchars(mkshort_handle, "\","); + if (snuniqueopt) { + setshort_mustuniq(mkshort_handle, atoi(snuniqueopt)); } - ozi_init_units(1); - parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME); + setshort_badchars(mkshort_handle, "\","); + } - file_out = NULL; + ozi_init_units(1); + parse_distance(proximityarg, &proximity, 1 / prox_scale, MYNAME); + + file_out = NULL; } static void wr_deinit(void) { - if (file_out != NULL) { - - gbfclose(file_out); - file_out = NULL; - } - ozi_ofname = NULL; + if (file_out != NULL) { + + gbfclose(file_out); + file_out = NULL; + } + ozi_ofname = NULL; - mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle); } static void ozi_parse_waypt(int field, char *str, waypoint * wpt_tmp, ozi_fsdata *fsdata) { - double alt; - - if (*str == '\0') return; + double alt; - switch (field) { - case 0: - /* sequence # */ - break; - case 1: - /* waypoint name */ - wpt_tmp->shortname = csv_stringtrim(str, "", 0); - break; - case 2: - /* degrees latitude */ - wpt_tmp->latitude = atof(str); - break; - case 3: - /* degrees longitude */ - wpt_tmp->longitude = atof(str); - break; - case 4: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - case 5: - /* icons 0-xx. Ozi seems to use some kind of internal tables to - pick numbers for icons based on GPS type. We don't know what those - tables are, so we read just the numbers. This converts badly to - other types, but it at least maintains fidelity for an ozi->ozi - operation. */ - if (str && isdigit(str[0])) { - wpt_tmp->icon_descr = xstrdup(str); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - } - break; - case 6: - /* unknown - always 1 */ - break; - case 7: - /* display format options 0-8 */ - break; - case 8: - /* foreground color (0=black) */ - fsdata->fgcolor = atoi(str); - break; - case 9: - /* background color (65535=yellow) */ - fsdata->bgcolor = atoi(str); - break; - case 10: - /* Description */ - wpt_tmp->description = csv_stringtrim(str, "", 0); - break; - case 11: - /* pointer direction 0,1,2,3 bottom,top,left,right */ - break; - case 12: - /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ - break; - case 13: - /* proximity distance - meters */ - WAYPT_SET(wpt_tmp, proximity, atof(str) * prox_scale); - break; - case 14: - /* altitude */ - alt = atof(str); - if (alt == -777) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = alt * alt_scale; - } - break; - case 15: - /* waypoint text name size */ - break; - case 16: - /* bold checkbox (1=bold, default 0) */ - break; - case 17: - /* symbol size - 17 default */ - break; - /* - * Fields 18-23 were added around version 3.90.4g of - * Ozi, but aren't documented. We silently ignore - * these or any additional fields we don't need. - */ - default: - break; + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* sequence # */ + break; + case 1: + /* waypoint name */ + wpt_tmp->shortname = csv_stringtrim(str, "", 0); + break; + case 2: + /* degrees latitude */ + wpt_tmp->latitude = atof(str); + break; + case 3: + /* degrees longitude */ + wpt_tmp->longitude = atof(str); + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 5: + /* icons 0-xx. Ozi seems to use some kind of internal tables to + pick numbers for icons based on GPS type. We don't know what those + tables are, so we read just the numbers. This converts badly to + other types, but it at least maintains fidelity for an ozi->ozi + operation. */ + if (str && isdigit(str[0])) { + wpt_tmp->icon_descr = xstrdup(str); + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + } + break; + case 6: + /* unknown - always 1 */ + break; + case 7: + /* display format options 0-8 */ + break; + case 8: + /* foreground color (0=black) */ + fsdata->fgcolor = atoi(str); + break; + case 9: + /* background color (65535=yellow) */ + fsdata->bgcolor = atoi(str); + break; + case 10: + /* Description */ + wpt_tmp->description = csv_stringtrim(str, "", 0); + break; + case 11: + /* pointer direction 0,1,2,3 bottom,top,left,right */ + break; + case 12: + /* garmin gps display flags (0-name w/sym, 1-sym only, 2-comment w/symbol */ + break; + case 13: + /* proximity distance - meters */ + WAYPT_SET(wpt_tmp, proximity, atof(str) * prox_scale); + break; + case 14: + /* altitude */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = alt * alt_scale; } + break; + case 15: + /* waypoint text name size */ + break; + case 16: + /* bold checkbox (1=bold, default 0) */ + break; + case 17: + /* symbol size - 17 default */ + break; + /* + * Fields 18-23 were added around version 3.90.4g of + * Ozi, but aren't documented. We silently ignore + * these or any additional fields we don't need. + */ + default: + break; + } } static void ozi_parse_track(int field, char *str, waypoint * wpt_tmp, char *trk_name) { - double alt; - - if (*str == '\0') return; - - switch (field) { - case 0: - /* latitude */ - wpt_tmp->latitude = atof(str); - break; - case 1: - /* longitude */ - wpt_tmp->longitude = atof(str); - break; - case 2: - /* new track flag */ - if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - if (trk_name) - trk_head->rte_name = trk_name; - } - break; - case 3: - /* altitude */ - alt = atof(str); - if (alt == -777) { - wpt_tmp->altitude = unknown_alt; - } else { - wpt_tmp->altitude = alt * alt_scale; - } - break; - case 4: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - default: - break; + double alt; + + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 1: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 2: + /* new track flag */ + if ((atoi(str) == 1) && (trk_head->rte_waypt_ct > 0)) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + if (trk_name) { + trk_head->rte_name = trk_name; + } + } + break; + case 3: + /* altitude */ + alt = atof(str); + if (alt == -777) { + wpt_tmp->altitude = unknown_alt; + } else { + wpt_tmp->altitude = alt * alt_scale; } + break; + case 4: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + default: + break; + } } static void ozi_parse_routepoint(int field, char *str, waypoint * wpt_tmp) { - if (*str == '\0') return; - - switch (field) { - case 0: - /* W */ - break; - case 1: - /* route # */ - break; - case 2: - /* waypoint # -- ignored by ozi */ - break; - case 3: - /* waypoint # */ - break; - case 4: - /* waypoint name */ - wpt_tmp->shortname = csv_stringclean(str, ","); - break; - case 5: - /* latitude */ - wpt_tmp->latitude = atof(str); - break; - case 6: - /* longitude */ - wpt_tmp->longitude = atof(str); - break; - case 7: - /* DAYS since 1900 00:00:00 in days.days (5.5) */ - ozi_set_time_str(str, wpt_tmp); - break; - case 8: - /* symbol */ - break; - case 9: - /* status */ - break; - case 10: - /* map display format */ - break; - case 11: - /* foreground color (RGB) */ - break; - case 12: - /* background color (RGB) */ - break; - case 13: - /* description */ - wpt_tmp->description = csv_stringclean(str, ","); - break; - default: - break; - } + if (*str == '\0') { + return; + } + + switch (field) { + case 0: + /* W */ + break; + case 1: + /* route # */ + break; + case 2: + /* waypoint # -- ignored by ozi */ + break; + case 3: + /* waypoint # */ + break; + case 4: + /* waypoint name */ + wpt_tmp->shortname = csv_stringclean(str, ","); + break; + case 5: + /* latitude */ + wpt_tmp->latitude = atof(str); + break; + case 6: + /* longitude */ + wpt_tmp->longitude = atof(str); + break; + case 7: + /* DAYS since 1900 00:00:00 in days.days (5.5) */ + ozi_set_time_str(str, wpt_tmp); + break; + case 8: + /* symbol */ + break; + case 9: + /* status */ + break; + case 10: + /* map display format */ + break; + case 11: + /* foreground color (RGB) */ + break; + case 12: + /* background color (RGB) */ + break; + case 13: + /* description */ + wpt_tmp->description = csv_stringclean(str, ","); + break; + default: + break; + } } static void ozi_parse_routeheader(int field, char *str, waypoint * wpt_tmp) { - switch (field) { - case 0: - /* R */ - rte_head = route_head_alloc(); - route_add_head(rte_head); - break; - case 1: - /* route # */ - rte_head->rte_num = atoi(str); - break; - case 2: - /* route name */ - rte_head->rte_name = csv_stringclean(str, ","); - break; - case 3: - /* route description */ - rte_head->rte_desc = csv_stringclean(str, ","); - break; - case 4: - /* route color */ - break; - default: - break; - } + switch (field) { + case 0: + /* R */ + rte_head = route_head_alloc(); + route_add_head(rte_head); + break; + case 1: + /* route # */ + rte_head->rte_num = atoi(str); + break; + case 2: + /* route name */ + rte_head->rte_name = csv_stringclean(str, ","); + break; + case 3: + /* route description */ + rte_head->rte_desc = csv_stringclean(str, ","); + break; + case 4: + /* route color */ + break; + default: + break; + } } static void data_read(void) { - char *buff; - char *s = NULL; - char *trk_name = NULL; - waypoint *wpt_tmp; - int i; - int linecount = 0; - - while ((buff = gbfgetstr(file_in))) { - - if ((linecount++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - /* - * this is particularly nasty. use the first line of the file - * to attempt to divine the data type we are parsing - */ - if (linecount == 1) { - if (strstr(buff, "Track Point") != NULL) { - trk_head = route_head_alloc(); - track_add_head(trk_head); - ozi_objective = trkdata; - } else - if (strstr(buff, "Route File") != NULL) { - ozi_objective = rtedata; - } else { - ozi_objective = wptdata; - } + char *buff; + char *s = NULL; + char *trk_name = NULL; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + while ((buff = gbfgetstr(file_in))) { + + if ((linecount++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + /* + * this is particularly nasty. use the first line of the file + * to attempt to divine the data type we are parsing + */ + if (linecount == 1) { + if (strstr(buff, "Track Point") != NULL) { + trk_head = route_head_alloc(); + track_add_head(trk_head); + ozi_objective = trkdata; + } else if (strstr(buff, "Route File") != NULL) { + ozi_objective = rtedata; + } else { + ozi_objective = wptdata; + } + } else if (linecount == 2) { + datum = GPS_Lookup_Datum_Index(buff); + if (datum < 0) { + fatal(MYNAME ": Unsupported datum '%s'.\n", buff); + } + } else if (linecount == 3) { + if (case_ignore_strncmp(buff, "Altitude is in ", 15) == 0) { + char *unit = &buff[15]; + if (case_ignore_strncmp(unit, "Feet", 4) == 0) { + altunit = 'f'; + alt_scale = FEET_TO_METERS(1.0); + } else if (case_ignore_strncmp(unit, "Meter", 5) == 0) { + altunit = 'm'; + alt_scale = 1.0; + } else { + fatal(MYNAME ": Unknown unit (%s) used by altitude values!\n", unit); } - else if (linecount == 2) { - datum = GPS_Lookup_Datum_Index(buff); - if (datum < 0) { - fatal(MYNAME ": Unsupported datum '%s'.\n", buff); - } - } - else if (linecount == 3) { - if (case_ignore_strncmp(buff, "Altitude is in ", 15) == 0) { - char *unit = &buff[15]; - if (case_ignore_strncmp(unit, "Feet", 4) == 0) { - altunit = 'f'; - alt_scale = FEET_TO_METERS(1.0); - } - else if (case_ignore_strncmp(unit, "Meter", 5) == 0) { - altunit = 'm'; - alt_scale = 1.0; - } - else fatal(MYNAME ": Unknown unit (%s) used by altitude values!\n", unit); - } - } else if ((linecount == 5) && (ozi_objective == trkdata)) { - int field = 0; - s = csv_lineparse(buff, ",", "", linecount); - while (s) { - field ++; - if (field == 4) { - trk_head->rte_name = xstrdup(lrtrim(s)); - } - s = csv_lineparse(NULL, ",", "", linecount); - } - } - - if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { - ozi_fsdata *fsdata = ozi_alloc_fsdata(); - wpt_tmp = waypt_new(); - - /* data delimited by commas, possibly enclosed in quotes. */ - s = buff; - s = csv_lineparse(s, ",", "", linecount); - - i = 0; - while (s) { - switch (ozi_objective) { - case trkdata: - ozi_parse_track(i, s, wpt_tmp, trk_name); - break; - case rtedata: - if (buff[0] == 'R') { - ozi_parse_routeheader(i, s, wpt_tmp); - } else { - ozi_parse_routepoint(i, s, wpt_tmp); - } - - break; - case wptdata: - ozi_parse_waypt(i, s, wpt_tmp, fsdata); - break; - case posndata: - fatal(MYNAME ": realtime positioning not supported.\n"); - break; - } - i++; - s = csv_lineparse(NULL, ",", "", linecount); - } - - switch (ozi_objective) { - case trkdata: - if (linecount > 6) {/* skipping over file header */ - ozi_convert_datum(wpt_tmp); - track_add_wpt(trk_head, wpt_tmp); - } - else - waypt_free(wpt_tmp); - break; - case rtedata: - if (linecount > 5) {/* skipping over file header */ - ozi_convert_datum(wpt_tmp); - route_add_wpt(rte_head, wpt_tmp); - } - else - waypt_free(wpt_tmp); - break; - case wptdata: - if (linecount > 4) { /* skipping over file header */ - fs_chain_add(&(wpt_tmp->fs), - (format_specific_data *) fsdata); - ozi_convert_datum(wpt_tmp); - waypt_add(wpt_tmp); - } else { - waypt_free(wpt_tmp); - } - break; - case posndata: - fatal(MYNAME ": realtime positioning not supported.\n"); - break; - } + } + } else if ((linecount == 5) && (ozi_objective == trkdata)) { + int field = 0; + s = csv_lineparse(buff, ",", "", linecount); + while (s) { + field ++; + if (field == 4) { + trk_head->rte_name = xstrdup(lrtrim(s)); + } + s = csv_lineparse(NULL, ",", "", linecount); + } + } + if ((strlen(buff)) && (strstr(buff, ",") != NULL)) { + ozi_fsdata *fsdata = ozi_alloc_fsdata(); + wpt_tmp = waypt_new(); + + /* data delimited by commas, possibly enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, ",", "", linecount); + + i = 0; + while (s) { + switch (ozi_objective) { + case trkdata: + ozi_parse_track(i, s, wpt_tmp, trk_name); + break; + case rtedata: + if (buff[0] == 'R') { + ozi_parse_routeheader(i, s, wpt_tmp); + } else { + ozi_parse_routepoint(i, s, wpt_tmp); + } + + break; + case wptdata: + ozi_parse_waypt(i, s, wpt_tmp, fsdata); + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + switch (ozi_objective) { + case trkdata: + if (linecount > 6) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + track_add_wpt(trk_head, wpt_tmp); } else { - /* empty line */ + waypt_free(wpt_tmp); } + break; + case rtedata: + if (linecount > 5) {/* skipping over file header */ + ozi_convert_datum(wpt_tmp); + route_add_wpt(rte_head, wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + break; + case wptdata: + if (linecount > 4) { /* skipping over file header */ + fs_chain_add(&(wpt_tmp->fs), + (format_specific_data *) fsdata); + ozi_convert_datum(wpt_tmp); + waypt_add(wpt_tmp); + } else { + waypt_free(wpt_tmp); + } + break; + case posndata: + fatal(MYNAME ": realtime positioning not supported.\n"); + break; + } + } else { + /* empty line */ } + + } } static void ozi_waypt_pr(const waypoint * wpt) { - static int index = 0; - double alt; - char ozi_time[16]; - char *description; - char *shortname; - int faked_fsdata = 0; - ozi_fsdata *fs = NULL; - int icon = 0; - - fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); - - if (!fs) { - fs = ozi_alloc_fsdata(); - faked_fsdata = 1; - } - - ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); - - if (wpt->altitude == unknown_alt) { - alt = -777; - } else { - alt = wpt->altitude * alt_scale; - } - - if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = csv_stringclean(wpt->description, BADCHARS); - } else { - /* no description available */ - shortname = xstrdup(""); - } + static int index = 0; + double alt; + char ozi_time[16]; + char *description; + char *shortname; + int faked_fsdata = 0; + ozi_fsdata *fs = NULL; + int icon = 0; + + fs = (ozi_fsdata *) fs_chain_find(wpt->fs, FS_OZI); + + if (!fs) { + fs = ozi_alloc_fsdata(); + faked_fsdata = 1; + } + + ozi_get_time_str(wpt, ozi_time, sizeof(ozi_time)); + + if (wpt->altitude == unknown_alt) { + alt = -777; + } else { + alt = wpt->altitude * alt_scale; + } + + if ((!wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = csv_stringclean(wpt->description, BADCHARS); + } } else { - shortname = csv_stringclean(wpt->shortname, BADCHARS); + /* no description available */ + shortname = xstrdup(""); } + } else { + shortname = csv_stringclean(wpt->shortname, BADCHARS); + } - if (!wpt->description) { - if (shortname) { - description = csv_stringclean(shortname, BADCHARS); - } else { - description = xstrdup(""); - } + if (!wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, BADCHARS); } else { - description = csv_stringclean(wpt->description, BADCHARS); + description = xstrdup(""); } + } else { + description = csv_stringclean(wpt->description, BADCHARS); + } - index++; + index++; - if(wpt->icon_descr && isdigit(wpt->icon_descr[0])) { - icon = atoi(wpt->icon_descr); - } + if (wpt->icon_descr && isdigit(wpt->icon_descr[0])) { + icon = atoi(wpt->icon_descr); + } - gbfprintf(file_out, + gbfprintf(file_out, "%d,%s,%.6f,%.6f,%s,%d,%d,%d,%d,%d,%s,%d,%d,", index, shortname, wpt->latitude, wpt->longitude, ozi_time, icon, 1, 3, fs->fgcolor, fs->bgcolor, description, 0, 0); - if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) - gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale); - else if (proximity > 0) - gbfprintf(file_out,"%.1f,", proximity * prox_scale); - else - gbfprintf(file_out,"%d,", 0); - gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17); - - xfree(description); - xfree(shortname); - - if (faked_fsdata) { - xfree(fs); - } + if (WAYPT_HAS(wpt, proximity) && (wpt->proximity > 0)) { + gbfprintf(file_out, "%.1f,", wpt->proximity * prox_scale); + } else if (proximity > 0) { + gbfprintf(file_out,"%.1f,", proximity * prox_scale); + } else { + gbfprintf(file_out,"%d,", 0); + } + gbfprintf(file_out, "%.0f,%d,%d,%d\r\n", alt, 6, 0, 17); + + xfree(description); + xfree(shortname); + + if (faked_fsdata) { + xfree(fs); + } } static void data_write(void) { - static char *ozi_wpt_header = - "OziExplorer Waypoint File Version 1.1\r\n" - "WGS 84\r\n" - "Reserved 2\r\n" - "Reserved 3\r\n"; - - track_out_count = route_out_count = 0; - - if (waypt_count()) { - ozi_objective = wptdata; - ozi_openfile(ozi_ofname); - gbfprintf(file_out, ozi_wpt_header); - waypt_disp_all(ozi_waypt_pr); - } - - if (track_count()) { - ozi_objective = trkdata; - ozi_track_pr(); /* ozi_track_hdr handles filenames / file_out */ - } - - if (route_count()) { - ozi_objective = rtedata; - ozi_openfile(ozi_ofname); /* ozi routes go in one big file */ - ozi_route_pr(); - } + static char *ozi_wpt_header = + "OziExplorer Waypoint File Version 1.1\r\n" + "WGS 84\r\n" + "Reserved 2\r\n" + "Reserved 3\r\n"; + + track_out_count = route_out_count = 0; + + if (waypt_count()) { + ozi_objective = wptdata; + ozi_openfile(ozi_ofname); + gbfprintf(file_out, ozi_wpt_header); + waypt_disp_all(ozi_waypt_pr); + } + + if (track_count()) { + ozi_objective = trkdata; + ozi_track_pr(); /* ozi_track_hdr handles filenames / file_out */ + } + + if (route_count()) { + ozi_objective = rtedata; + ozi_openfile(ozi_ofname); /* ozi routes go in one big file */ + ozi_route_pr(); + } } ff_vecs_t ozi_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - ozi_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + ozi_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/palmdoc.c b/gpsbabel/palmdoc.c index e8c083a12..3b3ff654f 100644 --- a/gpsbabel/palmdoc.c +++ b/gpsbabel/palmdoc.c @@ -56,543 +56,561 @@ static char *palm_encrypt; #define UNCOMPRESSED 1 struct buffer { - unsigned char *data; - unsigned len; + unsigned char *data; + unsigned len; }; #define NEW_BUFFER(b) (b)->data = (unsigned char *)xmalloc( ((b)->len = 0,BUFFER_SIZE) ) static arglist_t palmdoc_args[] = { - { "nosep", &suppresssep, - "No separator lines between waypoints", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, - {"encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "bookmarks_short", &bmid, "Include short name in bookmarks", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "nosep", &suppresssep, + "No separator lines between waypoints", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX }, + { + "encrypt", &palm_encrypt, "Encrypt hints with ROT13", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "bookmarks_short", &bmid, "Include short name in bookmarks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static struct buffer buf; -struct doc_record0 /* 16 bytes total */ -{ - gbuint16 version; /* 1 = plain text, 2 = compressed */ - gbuint16 reserved1; - gbuint32 doc_size; /* in bytes, when uncompressed */ - gbuint16 num_records; /* PDB header numRecords - 1 */ - gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ - gbuint32 reserved2; - gbuint16 recsizes[1]; +struct doc_record0 { /* 16 bytes total */ + gbuint16 version; /* 1 = plain text, 2 = compressed */ + gbuint16 reserved1; + gbuint32 doc_size; /* in bytes, when uncompressed */ + gbuint16 num_records; /* PDB header numRecords - 1 */ + gbuint16 rec_size; /* usually RECORD_SIZE_MAX */ + gbuint32 reserved2; + gbuint16 recsizes[1]; }; static struct recordsize { - int size; - struct recordsize *next; + int size; + struct recordsize *next; } *recordsize_tail; static struct bookmark { - int offset; - char *text; - struct bookmark *next; + int offset; + char *text; + struct bookmark *next; } *bookmark_tail; struct bookmark_record { - char text[16]; - gbuint32 offset; + char text[16]; + gbuint32 offset; }; static void put_byte(struct buffer *b, unsigned char c, int *space) { - if ( *space ) { - *space = 0; - /* - ** There is an outstanding space char: see if we can squeeze it - ** in with an ASCII char. - */ - if ( c >= 0x40 && c <= 0x7F ) { - b->data[ b->len++ ] = c ^ 0x80; - return; - } - b->data[ b->len++ ] = ' '; /* couldn't squeeze it in */ - } else if ( c == ' ' ) { - *space = 1; - return; - } - - if ( (c >= 1 && c <= 8) || c >= 0x80 ) - b->data[ b->len++ ] = '\1'; - - b->data[ b->len++ ] = c; + if (*space) { + *space = 0; + /* + ** There is an outstanding space char: see if we can squeeze it + ** in with an ASCII char. + */ + if (c >= 0x40 && c <= 0x7F) { + b->data[ b->len++ ] = c ^ 0x80; + return; + } + b->data[ b->len++ ] = ' '; /* couldn't squeeze it in */ + } else if (c == ' ') { + *space = 1; + return; + } + + if ((c >= 1 && c <= 8) || c >= 0x80) { + b->data[ b->len++ ] = '\1'; + } + + b->data[ b->len++ ] = c; } static unsigned char * mem_find(unsigned char *t, int t_len, unsigned char *m, int m_len) { - register int i; - for ( i = t_len - m_len + 1; i > 0; --i, ++t ) - if ( *t == *m && !memcmp( t, m, m_len ) ) - return t; - return 0; + register int i; + for (i = t_len - m_len + 1; i > 0; --i, ++t) + if (*t == *m && !memcmp(t, m, m_len)) { + return t; + } + return 0; } -static void pd_compress( struct buffer *b ) +static void pd_compress(struct buffer *b) { - unsigned i, j; - int space = 0; - - unsigned char *buf_orig; - unsigned char *p; /* walking test hit; works up on successive matches */ - unsigned char *p_prev; - unsigned char *head; /* current test string */ - unsigned char *tail; /* 1 past the current test buffer */ - unsigned char *end; /* 1 past the end of the input buffer */ - - p = p_prev = head = buf_orig = b->data; - tail = head + 1; - end = b->data + b->len; - - NEW_BUFFER( b ); - b->len = 0; - - /* loop, absorbing one more char from the input buffer on each pass */ - while ( head != end ) { - /* establish where the scan can begin */ - if ( head - p_prev > (( 1 << DISP_BITS )-1) ) - p_prev = head - (( 1 << DISP_BITS )-1); - - /* scan in the previous data for a match */ - p = mem_find( p_prev, tail - p_prev, head, tail - head ); - - /* on a mismatch or end of buffer, issued codes */ - if ( !p || p == head || tail - head > ( 1 << COUNT_BITS ) + 2 - || tail == end - ) { - /* issued the codes */ - /* first, check for short runs */ - if ( tail - head < 4 ) { - put_byte( b, *head++, &space ); - } - else { - unsigned dist = head - p_prev; - unsigned compound = (dist << COUNT_BITS) - + tail - head - 4; - - /* for longer runs, issue a run-code */ - /* issue space char if required */ - if ( space ) { - b->data[ b->len++ ] = ' '; - space = 0; - } - - b->data[ b->len++ ] = 0x80 + ( compound >> 8 ); - b->data[ b->len++ ] = compound & 0xFF; - head = tail - 1;/* and start again */ - } - p_prev = buf_orig; /* start search again */ - } else - p_prev = p; /* got a match */ - - /* when we get to the end of the buffer, don't inc past the */ - /* end; this forces the residue chars out one at a time */ - if ( tail != end ) - ++tail; - } - xfree( buf_orig ); - - if ( space ) - b->data[ b->len++ ] = ' '; /* add left-over space */ - - /* final scan to merge consecutive high chars together */ - for ( i = j = 0; i < b->len; ++i, ++j ) { - b->data[ j ] = b->data[ i ]; - - /* skip run-length codes */ - if ( b->data[ j ] >= 0x80 && b->data[ j ] < 0xC0 ) - b->data[ ++j ] = b->data[ ++i ]; - - /* if we hit a high char marker, look ahead for another */ - else if ( b->data[ j ] == '\1' ) { - b->data[ j + 1 ] = b->data[ i + 1 ]; - while ( i + 2 < b->len && - b->data[ i + 2 ] == 1 && b->data[ j ] < 8 - ) { - b->data[ j ]++; - b->data[ j + b->data[ j ] ] = b->data[ i + 3 ]; - i += 2; - } - j += b->data[ j ]; - ++i; - } - } - b->len = j; + unsigned i, j; + int space = 0; + + unsigned char *buf_orig; + unsigned char *p; /* walking test hit; works up on successive matches */ + unsigned char *p_prev; + unsigned char *head; /* current test string */ + unsigned char *tail; /* 1 past the current test buffer */ + unsigned char *end; /* 1 past the end of the input buffer */ + + p = p_prev = head = buf_orig = b->data; + tail = head + 1; + end = b->data + b->len; + + NEW_BUFFER(b); + b->len = 0; + + /* loop, absorbing one more char from the input buffer on each pass */ + while (head != end) { + /* establish where the scan can begin */ + if (head - p_prev > ((1 << DISP_BITS)-1)) { + p_prev = head - ((1 << DISP_BITS)-1); + } + + /* scan in the previous data for a match */ + p = mem_find(p_prev, tail - p_prev, head, tail - head); + + /* on a mismatch or end of buffer, issued codes */ + if (!p || p == head || tail - head > (1 << COUNT_BITS) + 2 + || tail == end + ) { + /* issued the codes */ + /* first, check for short runs */ + if (tail - head < 4) { + put_byte(b, *head++, &space); + } else { + unsigned dist = head - p_prev; + unsigned compound = (dist << COUNT_BITS) + + tail - head - 4; + + /* for longer runs, issue a run-code */ + /* issue space char if required */ + if (space) { + b->data[ b->len++ ] = ' '; + space = 0; + } + + b->data[ b->len++ ] = 0x80 + (compound >> 8); + b->data[ b->len++ ] = compound & 0xFF; + head = tail - 1;/* and start again */ + } + p_prev = buf_orig; /* start search again */ + } else { + p_prev = p; /* got a match */ + } + + /* when we get to the end of the buffer, don't inc past the */ + /* end; this forces the residue chars out one at a time */ + if (tail != end) { + ++tail; + } + } + xfree(buf_orig); + + if (space) { + b->data[ b->len++ ] = ' '; /* add left-over space */ + } + + /* final scan to merge consecutive high chars together */ + for (i = j = 0; i < b->len; ++i, ++j) { + b->data[ j ] = b->data[ i ]; + + /* skip run-length codes */ + if (b->data[ j ] >= 0x80 && b->data[ j ] < 0xC0) { + b->data[ ++j ] = b->data[ ++i ]; + } + + /* if we hit a high char marker, look ahead for another */ + else if (b->data[ j ] == '\1') { + b->data[ j + 1 ] = b->data[ i + 1 ]; + while (i + 2 < b->len && + b->data[ i + 2 ] == 1 && b->data[ j ] < 8 + ) { + b->data[ j ]++; + b->data[ j + b->data[ j ] ] = b->data[ i + 3 ]; + i += 2; + } + j += b->data[ j ]; + ++i; + } + } + b->len = j; } -static void write_header( void ) { - - int recs = ct-1; - struct doc_record0 *rec0; - --ct; - - rec0 = xcalloc( 1, sizeof(struct doc_record0)+(ct-1)*sizeof(short)); - be_write16( &rec0->version, COMPRESSED ); - be_write16( &rec0->reserved1, 0 ); - be_write32( &rec0->doc_size, offset ); - be_write16( &rec0->num_records, ct ); - be_write16( &rec0->rec_size, 4096 ); - be_write32( &rec0->reserved2, 0 ); - while ( recs ) { - struct recordsize *oldrec = recordsize_tail; - be_write16( &rec0->recsizes[recs], oldrec->size ); - recordsize_tail = oldrec->next; - xfree( oldrec ); - --recs; - } - - pdb_write_rec(file_out, 0, 0, 0, (void *)rec0, sizeof(struct doc_record0) + sizeof(short)*(ct-1)); - - xfree(rec0); +static void write_header(void) +{ + + int recs = ct-1; + struct doc_record0 *rec0; + --ct; + + rec0 = xcalloc(1, sizeof(struct doc_record0)+(ct-1)*sizeof(short)); + be_write16(&rec0->version, COMPRESSED); + be_write16(&rec0->reserved1, 0); + be_write32(&rec0->doc_size, offset); + be_write16(&rec0->num_records, ct); + be_write16(&rec0->rec_size, 4096); + be_write32(&rec0->reserved2, 0); + while (recs) { + struct recordsize *oldrec = recordsize_tail; + be_write16(&rec0->recsizes[recs], oldrec->size); + recordsize_tail = oldrec->next; + xfree(oldrec); + --recs; + } + + pdb_write_rec(file_out, 0, 0, 0, (void *)rec0, sizeof(struct doc_record0) + sizeof(short)*(ct-1)); + + xfree(rec0); } -static void write_bookmarks( void ) { - struct bookmark *oldmark = NULL; - struct bookmark_record rec; - - struct bookmark *newtail = NULL; - - /* reverse the bookmark list */ - while ( bookmark_tail ) { - oldmark = bookmark_tail; - bookmark_tail = oldmark->next; - oldmark->next = newtail; - newtail = oldmark; - } - bookmark_tail = newtail; - - ct++; - while ( bookmark_tail ) { - oldmark = bookmark_tail; - bookmark_tail = oldmark->next; - - be_write32( &rec.offset, oldmark->offset ); - memset( rec.text, 0, 16 ); - strncpy( rec.text, oldmark->text, 16 ); - - pdb_write_rec(file_out, 0, 0, ct++, (void *)&rec, sizeof(struct bookmark_record)); - - xfree( oldmark ); - } +static void write_bookmarks(void) +{ + struct bookmark *oldmark = NULL; + struct bookmark_record rec; + + struct bookmark *newtail = NULL; + + /* reverse the bookmark list */ + while (bookmark_tail) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + oldmark->next = newtail; + newtail = oldmark; + } + bookmark_tail = newtail; + + ct++; + while (bookmark_tail) { + oldmark = bookmark_tail; + bookmark_tail = oldmark->next; + + be_write32(&rec.offset, oldmark->offset); + memset(rec.text, 0, 16); + strncpy(rec.text, oldmark->text, 16); + + pdb_write_rec(file_out, 0, 0, ct++, (void *)&rec, sizeof(struct bookmark_record)); + + xfree(oldmark); + } } -static void commit_buffer( void ) { +static void commit_buffer(void) +{ + + struct recordsize *newrec = xcalloc(1, sizeof(struct recordsize)); + newrec->next = recordsize_tail; + newrec->size = buf.len; + recordsize_tail = newrec; - struct recordsize *newrec = xcalloc( 1, sizeof(struct recordsize)); - newrec->next = recordsize_tail; - newrec->size = buf.len; - recordsize_tail = newrec; + pd_compress(&buf); - pd_compress( &buf ); - - pdb_write_rec(file_out, 0, 0, ct++, (void *)buf.data, buf.len); + pdb_write_rec(file_out, 0, 0, ct++, (void *)buf.data, buf.len); } -static void create_bookmark( char *bmtext ) { - struct bookmark *newmark = (struct bookmark *) xcalloc( 1, sizeof(struct bookmark)); - newmark->next = bookmark_tail; - newmark->offset = offset; - newmark->text = bmtext; - bookmark_tail = newmark; -} - -static void docprintf( int maxlen, const char *format, ... ) { - - char *txt = NULL; - char *txt2 = NULL; - va_list list; - int newlen; - int partlen; - - txt = (char *) xmalloc( maxlen ); - - va_start( list, format ); - newlen = vsprintf( txt, format, list ); - - txt2 = txt; - offset += newlen; - while (txt2 && *txt2 ) { - /* append to buffer what we can */ - partlen = BUFFER_SIZE-1-buf.len; - if ( buf.len + newlen + 1 > BUFFER_SIZE ) - { - strncpy( (char *) buf.data+buf.len, txt2, partlen ); - buf.data[BUFFER_SIZE-1] = '\0'; - txt2 += partlen; - newlen -= partlen; - buf.len = BUFFER_SIZE-1; - commit_buffer(); - NEW_BUFFER( &buf ); - } - else { - strcpy( (char *) buf.data+buf.len, txt2 ); - buf.len += newlen; - txt2 = NULL; - } +static void create_bookmark(char *bmtext) +{ + struct bookmark *newmark = (struct bookmark *) xcalloc(1, sizeof(struct bookmark)); + newmark->next = bookmark_tail; + newmark->offset = offset; + newmark->text = bmtext; + bookmark_tail = newmark; +} + +static void docprintf(int maxlen, const char *format, ...) +{ + + char *txt = NULL; + char *txt2 = NULL; + va_list list; + int newlen; + int partlen; + + txt = (char *) xmalloc(maxlen); + + va_start(list, format); + newlen = vsprintf(txt, format, list); + + txt2 = txt; + offset += newlen; + while (txt2 && *txt2) { + /* append to buffer what we can */ + partlen = BUFFER_SIZE-1-buf.len; + if (buf.len + newlen + 1 > BUFFER_SIZE) { + strncpy((char *) buf.data+buf.len, txt2, partlen); + buf.data[BUFFER_SIZE-1] = '\0'; + txt2 += partlen; + newlen -= partlen; + buf.len = BUFFER_SIZE-1; + commit_buffer(); + NEW_BUFFER(&buf); + } else { + strcpy((char *) buf.data+buf.len, txt2); + buf.len += newlen; + txt2 = NULL; } - - xfree( txt ); + } + + xfree(txt); } -static void docfinish() { - commit_buffer(); - write_header(); - write_bookmarks(); +static void docfinish() +{ + commit_buffer(); + write_header(); + write_bookmarks(); } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - out_fname = fname; - - mkshort_handle = mkshort_new_handle(); - mkshort_bookmark_handle = mkshort_new_handle(); - ct = 1; - offset = 1; - recordsize_tail = NULL; - bookmark_tail = NULL; - NEW_BUFFER( &buf ); + file_out = pdb_create(fname, MYNAME); + out_fname = fname; + + mkshort_handle = mkshort_new_handle(); + mkshort_bookmark_handle = mkshort_new_handle(); + ct = 1; + offset = 1; + recordsize_tail = NULL; + bookmark_tail = NULL; + NEW_BUFFER(&buf); } static void wr_deinit(void) { - pdb_close(file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&mkshort_bookmark_handle); - - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_bookmark_handle); + + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void palmdoc_disp(const waypoint *wpt) { - int latint, lonint; - char tbuf[1024]; - time_t tm = wpt->creation_time; - int32 utmz; - double utme, utmn; - char utmzc; - char *bm; - fs_xml *fs_gpx = NULL; - - char bookmarktext[17]; - - if ( bmid ) { - char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); - sprintf( bookmarktext, "%6s:%9s", - wpt->shortname?wpt->shortname:"",s); - xfree(s); - } - else { - char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); - sprintf( bookmarktext, "%16s", s); - xfree(s); - } - - bm = xstrdup(bookmarktext); - create_bookmark(bm); - - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); - - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - - if (tm == 0) - tm = time(NULL); - strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - - docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", - (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, - wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), - wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), - utmz, utmzc, utme, utmn); - if (wpt->altitude != unknown_alt) - docprintf (100, " alt: %1.1f", wpt->altitude); - docprintf (10, "\n"); - if (strcmp(wpt->description, wpt->shortname)) { - docprintf(10+strlen(wpt->description), "%s\n", wpt->description); - } - if (wpt->gc_data->terr) { - - docprintf (100, "%s/%s\n", gs_get_cachetype(wpt->gc_data->type), - gs_get_container(wpt->gc_data->container)); - - if (wpt->gc_data->desc_short.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_short); - docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->desc_long.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_long); - docprintf (10+strlen(stripped_html), "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->hint) { - char *hint = NULL; - if ( palm_encrypt ) - hint = rot13( wpt->gc_data->hint ); - else - hint = xstrdup( wpt->gc_data->hint ); - docprintf (10+strlen(hint), "\nHint: %s\n", hint); - xfree( hint ); - } - } - else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - docprintf (10+strlen(wpt->notes), "%s\n", wpt->notes); - } - - fs_gpx = NULL; - if ( includelogs ) { - fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); - } - - if ( fs_gpx && fs_gpx->tag ) { - xml_tag *root = fs_gpx->tag; - xml_tag *curlog = NULL; - xml_tag *logpart = NULL; - curlog = xml_findfirst( root, "groundspeak:log" ); - while ( curlog ) { - time_t logtime = 0; - struct tm *logtm = NULL; - docprintf( 10, "\n" ); - - logpart = xml_findfirst( curlog, "groundspeak:type" ); - if ( logpart ) { - docprintf( 10+strlen(logpart->cdata), "%s by ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:finder" ); - if ( logpart ) { - docprintf( 10+strlen(logpart->cdata), "%s on ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:date" ); - if ( logpart ) { - logtime = xml_parse_time( logpart->cdata, NULL); - logtm = localtime( &logtime ); - if ( logtm ) { - docprintf( 15, - "%2.2d/%2.2d/%4.4d\n", - logtm->tm_mon+1, - logtm->tm_mday, - logtm->tm_year+1900 - ); - } - } - - logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); - if ( logpart ) { - char *coordstr = NULL; - float lat = 0; - int latdeg = 0; - float lon = 0; - int londeg = 0; - coordstr = xml_attribute( logpart, "lat" ); - if ( coordstr ) { - lat = atof( coordstr ); - } - coordstr = xml_attribute( logpart, "lon" ); - if ( coordstr ) { - lon = atof( coordstr ); - } - latdeg = abs(lat); - londeg = abs(lon); - - docprintf( 30, - "%c %d\xb0 %.3f' %c %d\xb0 %.3f'\n", - - lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), - lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) - ); - } - - logpart = xml_findfirst( curlog, "groundspeak:text" ); - if ( logpart ) { - char *encstr = NULL; - char *s = NULL; - int encoded = 0; - encstr = xml_attribute( logpart, "encoded" ); - encoded = (encstr[0] != 'F'); - - if ( palm_encrypt && encoded ) { - s = rot13( logpart->cdata ); - } - else { - s = xstrdup( logpart->cdata ); - } - - docprintf( 5+strlen(s), "%s", s ); - xfree( s ); - } - - docprintf( 10, "\n" ); - curlog = xml_findnext( root, curlog, "groundspeak:log" ); - } - } - if (! suppresssep) - docprintf(50, "---------------------------\n"); - else - docprintf(10, "\n"); + int latint, lonint; + char tbuf[1024]; + time_t tm = wpt->creation_time; + int32 utmz; + double utme, utmn; + char utmzc; + char *bm; + fs_xml *fs_gpx = NULL; + + char bookmarktext[17]; + + if (bmid) { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf(bookmarktext, "%6s:%9s", + wpt->shortname?wpt->shortname:"",s); + xfree(s); + } else { + char * s = mkshort_from_wpt(mkshort_bookmark_handle, wpt); + sprintf(bookmarktext, "%16s", s); + xfree(s); + } + + bm = xstrdup(bookmarktext); + create_bookmark(bm); + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) { + tm = time(NULL); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + docprintf(300, "%-16s %c%d %06.3f %c%d %06.3f (%d%c %6.0f %7.0f)", + (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, + wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), + wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint), + utmz, utmzc, utme, utmn); + if (wpt->altitude != unknown_alt) { + docprintf(100, " alt: %1.1f", wpt->altitude); + } + docprintf(10, "\n"); + if (strcmp(wpt->description, wpt->shortname)) { + docprintf(10+strlen(wpt->description), "%s\n", wpt->description); + } + if (wpt->gc_data->terr) { + + docprintf(100, "%s/%s\n", gs_get_cachetype(wpt->gc_data->type), + gs_get_container(wpt->gc_data->container)); + + if (wpt->gc_data->desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_short); + docprintf(10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_long); + docprintf(10+strlen(stripped_html), "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->hint) { + char *hint = NULL; + if (palm_encrypt) { + hint = rot13(wpt->gc_data->hint); + } else { + hint = xstrdup(wpt->gc_data->hint); + } + docprintf(10+strlen(hint), "\nHint: %s\n", hint); + xfree(hint); + } + } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + docprintf(10+strlen(wpt->notes), "%s\n", wpt->notes); + } + + fs_gpx = NULL; + if (includelogs) { + fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX); + } + + if (fs_gpx && fs_gpx->tag) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm *logtm = NULL; + docprintf(10, "\n"); + + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + docprintf(10+strlen(logpart->cdata), "%s by ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + docprintf(10+strlen(logpart->cdata), "%s on ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + docprintf(15, + "%2.2d/%2.2d/%4.4d\n", + logtm->tm_mon+1, + logtm->tm_mday, + logtm->tm_year+1900 + ); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + if (logpart) { + char *coordstr = NULL; + float lat = 0; + int latdeg = 0; + float lon = 0; + int londeg = 0; + coordstr = xml_attribute(logpart, "lat"); + if (coordstr) { + lat = atof(coordstr); + } + coordstr = xml_attribute(logpart, "lon"); + if (coordstr) { + lon = atof(coordstr); + } + latdeg = abs(lat); + londeg = abs(lon); + + docprintf(30, + "%c %d\xb0 %.3f' %c %d\xb0 %.3f'\n", + + lat < 0 ? 'S' : 'N', latdeg, 60.0 * (fabs(lat) - latdeg), + lon < 0 ? 'W' : 'E', londeg, 60.0 * (fabs(lon) - londeg) + ); + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char *encstr = NULL; + char *s = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (encstr[0] != 'F'); + + if (palm_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + docprintf(5+strlen(s), "%s", s); + xfree(s); + } + + docprintf(10, "\n"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + } + if (! suppresssep) { + docprintf(50, "---------------------------\n"); + } else { + docprintf(10, "\n"); + } } static void data_write(void) { - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, out_fname, PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = DOC_TYPE; - file_out->creator = DOC_CREATOR; - file_out->version = 1; - - if (! suppresssep) - docprintf(50, "---------------------------\n"); - setshort_length(mkshort_handle, 20 ); - setshort_length(mkshort_bookmark_handle, 16-(bmid?7:0)); - setshort_whitespace_ok( mkshort_bookmark_handle, 0 ); - waypt_disp_all(palmdoc_disp); - - docfinish(); + if (dbname) { + strncpy(file_out->name, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, out_fname, PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = DOC_TYPE; + file_out->creator = DOC_CREATOR; + file_out->version = 1; + + if (! suppresssep) { + docprintf(50, "---------------------------\n"); + } + setshort_length(mkshort_handle, 20); + setshort_length(mkshort_bookmark_handle, 16-(bmid?7:0)); + setshort_whitespace_ok(mkshort_bookmark_handle, 0); + waypt_disp_all(palmdoc_disp); + + docfinish(); } ff_vecs_t palmdoc_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none}, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - palmdoc_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + palmdoc_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/parse.c b/gpsbabel/parse.c index 9b49b8b32..46807a4f3 100644 --- a/gpsbabel/parse.c +++ b/gpsbabel/parse.c @@ -42,36 +42,49 @@ int parse_distance(const char *str, double *val, double scale, const char *module) { - char *unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - *val = strtod(str, &unit); - if (unit == NULL) - fatal("%s: Unconvertable numeric value (%s)!\n", module, str); - - if (fabs(*val) + 1 >= 1.0e25) { - return 0; /* not only Garmin uses this as 'unknown value' */ - } - - while (isspace(*unit)) unit++; - - if (*unit == '\0') { - *val *= scale; - return 1; - } - - if (case_ignore_strcmp(unit, "m") == 0) /* do nothing, that's our standard */; - else if (case_ignore_strcmp(unit, "ft") == 0) *val = FEET_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "feet") == 0) *val = FEET_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "k") == 0) *val *= 1000.0; - else if (case_ignore_strcmp(unit, "km") == 0) *val *= 1000.0; - else if (case_ignore_strcmp(unit, "nm") == 0) *val = NMILES_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "mi") == 0) *val = MILES_TO_METERS(*val); - else if (case_ignore_strcmp(unit, "fa") == 0) *val = FATHOMS_TO_METERS(*val); - else - fatal("%s: Unsupported distance unit in item '%s'!\n", module, str); - return 2; + char *unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + *val = strtod(str, &unit); + if (unit == NULL) { + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + } + + if (fabs(*val) + 1 >= 1.0e25) { + return 0; /* not only Garmin uses this as 'unknown value' */ + } + + while (isspace(*unit)) { + unit++; + } + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m") == 0) /* do nothing, that's our standard */; + else if (case_ignore_strcmp(unit, "ft") == 0) { + *val = FEET_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "feet") == 0) { + *val = FEET_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "k") == 0) { + *val *= 1000.0; + } else if (case_ignore_strcmp(unit, "km") == 0) { + *val *= 1000.0; + } else if (case_ignore_strcmp(unit, "nm") == 0) { + *val = NMILES_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "mi") == 0) { + *val = MILES_TO_METERS(*val); + } else if (case_ignore_strcmp(unit, "fa") == 0) { + *val = FATHOMS_TO_METERS(*val); + } else { + fatal("%s: Unsupported distance unit in item '%s'!\n", module, str); + } + return 2; } /* @@ -85,38 +98,52 @@ parse_distance(const char *str, double *val, double scale, const char *module) int parse_speed(const char *str, double *val, const double scale, const char *module) { - char *unit; - - if ((str == NULL) || (*str == '\0')) return 0; - - *val = strtod(str, &unit); - if (unit == NULL) - fatal("%s: Unconvertable numeric value (%s)!\n", module, str); - - while (isspace(*unit)) unit++; - - if (*unit == '\0') { - *val *= scale; - return 1; - } - - if (case_ignore_strcmp(unit, "m/s") == 0) ; - else if (case_ignore_strcmp(unit, "mps") == 0) ; - else if (case_ignore_strcmp(unit, "kph") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "km/h") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "kmh") == 0) *val = KPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "kt") == 0) *val = KNOTS_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "knot") == 0) *val = KNOTS_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mph") == 0) *val = MPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mi/h") == 0) *val = MPH_TO_MPS(*val); - else if (case_ignore_strcmp(unit, "mih") == 0) *val = MPH_TO_MPS(*val); - else - fatal("%s: Unsupported speed unit '%s' in item '%s'!\n", module, unit, str); - - return 2; + char *unit; + + if ((str == NULL) || (*str == '\0')) { + return 0; + } + + *val = strtod(str, &unit); + if (unit == NULL) { + fatal("%s: Unconvertable numeric value (%s)!\n", module, str); + } + + while (isspace(*unit)) { + unit++; + } + + if (*unit == '\0') { + *val *= scale; + return 1; + } + + if (case_ignore_strcmp(unit, "m/s") == 0) ; + else if (case_ignore_strcmp(unit, "mps") == 0) ; + else if (case_ignore_strcmp(unit, "kph") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "km/h") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "kmh") == 0) { + *val = KPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "kt") == 0) { + *val = KNOTS_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "knot") == 0) { + *val = KNOTS_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mph") == 0) { + *val = MPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mi/h") == 0) { + *val = MPH_TO_MPS(*val); + } else if (case_ignore_strcmp(unit, "mih") == 0) { + *val = MPH_TO_MPS(*val); + } else { + fatal("%s: Unsupported speed unit '%s' in item '%s'!\n", module, unit, str); + } + + return 2; } -/* +/* * Convert string 'str' into geodetic latitide & longitude values. The format * will be interpreted depending on 'grid' parameter. * @@ -124,168 +151,179 @@ parse_speed(const char *str, double *val, const double scale, const char *module */ int -parse_coordinates(const char *str, int datum, const grid_type grid, - double *latitude, double *longitude, const char *module) +parse_coordinates(const char *str, int datum, const grid_type grid, + double *latitude, double *longitude, const char *module) { - double lat, lon; - unsigned char lathemi, lonhemi; - int deg_lat, deg_lon, min_lat, min_lon; - char map[3]; - int utmz; - double utme, utmn; - char utmc; - int valid, result, ct; - double lx, ly; - const char *format; - - valid = 1; - - switch(grid) { - - case grid_lat_lon_ddd: - format = "%c%lf %c%lf%n"; - ct = sscanf(str, format, - &lathemi, &lat, &lonhemi, &lon, &result); - valid = (ct == 4); - break; - - case grid_lat_lon_dmm: - format = "%c%d %lf %c%d %lf%n"; - ct = sscanf(str, format, - &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon, &result); - valid = (ct == 6); - if (valid) { - lat = (double)deg_lat + (lat / (double)60); - lon = (double)deg_lon + (lon / (double)60); - } - break; - - case grid_lat_lon_dms: - format = "%c%d %d %lf %c%d %d %lf%n"; - ct = sscanf(str, format, - &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon, - &result); - valid = (ct == 8); - if (valid) { - lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); - lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); - } - break; - - case grid_bng: - datum = DATUM_WGS84; /* fix */ - format = "%2s %lf %lf%n"; - ct = sscanf(str, format, - map, &lx, &ly, - &result); - valid = (ct == 3); - if (valid) { - if (! GPS_Math_UKOSMap_To_WGS84_M(map, lx, ly, &lat, &lon)) - fatal("%s: Unable to convert BNG coordinates (%s)!\n", - module, str); - } - lathemi = lonhemi = '\0'; - break; - - case grid_utm: - format = "%d %c %lf %lf%n"; - ct = sscanf(str, format, - &utmz, &utmc, &utme, &utmn, - &result); - valid = (ct == 4); - if (valid) { - if (! GPS_Math_UTM_EN_To_Known_Datum(&lat, &lon, utme, utmn, utmz, utmc, datum)) - fatal("%s: Unable to convert UTM coordinates (%s)!\n", - module, str); - } - lathemi = lonhemi = '\0'; - break; - - case grid_swiss: { - double east, north; - - datum = DATUM_WGS84; /* fix */ - format = "%lf %lf%n"; - ct = sscanf(str, format, - &east, &north, &result); - valid = (ct == 2); - GPS_Math_Swiss_EN_To_WGS84(east, north, &lat, &lon); - break; - } - default: - /* this should never happen in a release version */ - fatal("%s/util: Unknown grid in parse_coordinates (%d)!\n", - module, (int)grid); - } - - if (! valid) { - warning("%s: sscanf error using format \"%s\"!\n", module, format); - warning("%s: parsing has stopped at parameter number %d.\n", module, ct); - fatal("%s: could not convert coordinates \"%s\"!\n", module, str); - } - - if (lathemi == 'S') lat = -lat; - if (lonhemi == 'W') lon = -lon; - - if (datum != DATUM_WGS84) { - double alt; - GPS_Math_Known_Datum_To_WGS84_M(lat, lon, (double) 0.0, - &lat, &lon, &alt, datum); - } - - if (latitude) *latitude = lat; - if (longitude) *longitude = lon; - - return result; + double lat, lon; + unsigned char lathemi, lonhemi; + int deg_lat, deg_lon, min_lat, min_lon; + char map[3]; + int utmz; + double utme, utmn; + char utmc; + int valid, result, ct; + double lx, ly; + const char *format; + + valid = 1; + + switch (grid) { + + case grid_lat_lon_ddd: + format = "%c%lf %c%lf%n"; + ct = sscanf(str, format, + &lathemi, &lat, &lonhemi, &lon, &result); + valid = (ct == 4); + break; + + case grid_lat_lon_dmm: + format = "%c%d %lf %c%d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &lat, &lonhemi, °_lon, &lon, &result); + valid = (ct == 6); + if (valid) { + lat = (double)deg_lat + (lat / (double)60); + lon = (double)deg_lon + (lon / (double)60); + } + break; + + case grid_lat_lon_dms: + format = "%c%d %d %lf %c%d %d %lf%n"; + ct = sscanf(str, format, + &lathemi, °_lat, &min_lat, &lat, &lonhemi, °_lon, &min_lon, &lon, + &result); + valid = (ct == 8); + if (valid) { + lat = (double)deg_lat + ((double)min_lat / (double)60) + (lat / (double)3600.0); + lon = (double)deg_lon + ((double)min_lon / (double)60) + (lon / (double)3600.0); + } + break; + + case grid_bng: + datum = DATUM_WGS84; /* fix */ + format = "%2s %lf %lf%n"; + ct = sscanf(str, format, + map, &lx, &ly, + &result); + valid = (ct == 3); + if (valid) { + if (! GPS_Math_UKOSMap_To_WGS84_M(map, lx, ly, &lat, &lon)) + fatal("%s: Unable to convert BNG coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_utm: + format = "%d %c %lf %lf%n"; + ct = sscanf(str, format, + &utmz, &utmc, &utme, &utmn, + &result); + valid = (ct == 4); + if (valid) { + if (! GPS_Math_UTM_EN_To_Known_Datum(&lat, &lon, utme, utmn, utmz, utmc, datum)) + fatal("%s: Unable to convert UTM coordinates (%s)!\n", + module, str); + } + lathemi = lonhemi = '\0'; + break; + + case grid_swiss: { + double east, north; + + datum = DATUM_WGS84; /* fix */ + format = "%lf %lf%n"; + ct = sscanf(str, format, + &east, &north, &result); + valid = (ct == 2); + GPS_Math_Swiss_EN_To_WGS84(east, north, &lat, &lon); + break; + } + default: + /* this should never happen in a release version */ + fatal("%s/util: Unknown grid in parse_coordinates (%d)!\n", + module, (int)grid); + } + + if (! valid) { + warning("%s: sscanf error using format \"%s\"!\n", module, format); + warning("%s: parsing has stopped at parameter number %d.\n", module, ct); + fatal("%s: could not convert coordinates \"%s\"!\n", module, str); + } + + if (lathemi == 'S') { + lat = -lat; + } + if (lonhemi == 'W') { + lon = -lon; + } + + if (datum != DATUM_WGS84) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(lat, lon, (double) 0.0, + &lat, &lon, &alt, datum); + } + + if (latitude) { + *latitude = lat; + } + if (longitude) { + *longitude = lon; + } + + return result; } time_t parse_date(const char *str, const char *format, const char *module) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - if (format) { - char *cx = strptime(str, format, &tm); - if ((cx != NULL) && (*cx != '\0')) - fatal("%s: Could not parse date string (%s).\n", module, str); - } - else { - int p1, p2, p3, ct; - char sep[2]; - - ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d", &p1, sep, &p2, sep, &p3); - if (ct != 5) - fatal("%s: Could not parse date string (%s).\n", module, str); - - if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ - tm.tm_year = p1; - tm.tm_mon = p2; - tm.tm_mday = p3; - } - else if (sep[0] == '.') { /* Germany and any other countries */ - tm.tm_mday = p1; /* have a fixed D.M.Y format */ - tm.tm_mon = p2; - tm.tm_year = p3; - } - else { - tm.tm_mday = p2; - tm.tm_mon = p1; - tm.tm_year = p3; - } - if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { - if (tm.tm_year < 70) tm.tm_year += 2000; - else tm.tm_year += 1900; - } - /* some low-level checks */ - if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) - fatal("%s: Could not parse date string (%s).\n", module, str); - - tm.tm_year -= 1900; - tm.tm_mon -= 1; - } - - return mkgmtime(&tm); + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + if (format) { + char *cx = strptime(str, format, &tm); + if ((cx != NULL) && (*cx != '\0')) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + } else { + int p1, p2, p3, ct; + char sep[2]; + + ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d", &p1, sep, &p2, sep, &p3); + if (ct != 5) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + + if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ + tm.tm_year = p1; + tm.tm_mon = p2; + tm.tm_mday = p3; + } else if (sep[0] == '.') { /* Germany and any other countries */ + tm.tm_mday = p1; /* have a fixed D.M.Y format */ + tm.tm_mon = p2; + tm.tm_year = p3; + } else { + tm.tm_mday = p2; + tm.tm_mon = p1; + tm.tm_year = p3; + } + if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { + if (tm.tm_year < 70) { + tm.tm_year += 2000; + } else { + tm.tm_year += 1900; + } + } + /* some low-level checks */ + if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) { + fatal("%s: Could not parse date string (%s).\n", module, str); + } + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + } + + return mkgmtime(&tm); } diff --git a/gpsbabel/pathaway.c b/gpsbabel/pathaway.c index 288314f3d..061e9e32e 100644 --- a/gpsbabel/pathaway.c +++ b/gpsbabel/pathaway.c @@ -1,5 +1,5 @@ -/* - Support for PathAway Palm Database, +/* + Support for PathAway Palm Database, Copyright (C) 2005-2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -18,21 +18,21 @@ */ -/* +/* remarks: - + The german release 3.0 of PathAway violates the PathAway standards: * N.. .... O.. .... instead of N.. .... E.. .... * date is formatted in DDMMYYYY instead of YYYYMMDD Release 4.x store only numeric coordinates and uses a six-number date. - + Modified by by Andrei Boros 2008-11-07 - * added information about database vehicle icon - * Pathaway 4.x can handle invalid date/time and date format apparently - has changed slightly between revisions : + * added information about database vehicle icon + * Pathaway 4.x can handle invalid date/time and date format apparently + has changed slightly between revisions : 131502.29 26102008 = HHMMSS.MS DDMMYYYY - * work around errors reading date/time information + * work around errors reading date/time information (real life data collected by Pathaway sometimes has the date/time field contain some missing/invalid data. This information can be safely ignored most of the time. So far gpsbabel stopped processing files @@ -42,10 +42,10 @@ - date/time field may contain invalid characters -> ignore - invalid or missing date/time -> ignore - only time may be present (some older versions of Pathaway 4) - + (this is still incomplete, but solved most of my problems when converting pathaway .pdb files) - + */ #include @@ -72,33 +72,31 @@ static char *datefmt; static int ct; static int warn_ = 0; -typedef struct ppdb_appdata -{ - unsigned char reservedA[274]; /* all 0 */ - unsigned char dirtyFlag; - unsigned char dataBaseSubType; /* 0 = Track, 1 = Route */ - short int dbAttributes; /* 0 */ - char vehicleStr[VEHICLE_LEN]; - unsigned char reservedB[100]; /* all 0 */ +typedef struct ppdb_appdata { + unsigned char reservedA[274]; /* all 0 */ + unsigned char dirtyFlag; + unsigned char dataBaseSubType; /* 0 = Track, 1 = Route */ + short int dbAttributes; /* 0 */ + char vehicleStr[VEHICLE_LEN]; + unsigned char reservedB[100]; /* all 0 */ } ppdb_appdata_t; #define PPDB_APPINFO_SIZE sizeof(struct ppdb_appdata) static ppdb_appdata_t *appinfo; static char *opt_dbname = NULL; -static char *opt_dbicon = NULL; +static char *opt_dbicon = NULL; static char *opt_deficon = NULL; static char *opt_snlen = NULL; static char *opt_date = NULL; -static arglist_t ppdb_args[] = -{ - {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"dbicon", &opt_dbicon, "Database vehicle icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t ppdb_args[] = { + {"date", &opt_date, "Read/Write date format (i.e. DDMMYYYY)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbname", &opt_dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"dbicon", &opt_dbicon, "Database vehicle icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"deficon", &opt_deficon, "Default icon name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + {"snlen", &opt_snlen, "Length of generated shortnames", "10", ARGTYPE_INT, "1", NULL }, + ARG_TERMINATOR }; /*#undef PPDB_DEBUG*/ @@ -108,18 +106,18 @@ static arglist_t ppdb_args[] = static void internal_debug1(const char *filename, int fileline) { - static int ct=1; - printf("DBG(%d): file %s, line %d: ", ct++, filename, fileline); + static int ct=1; + printf("DBG(%d): file %s, line %d: ", ct++, filename, fileline); } static void -internal_debug2(const char *format, ... ) +internal_debug2(const char *format, ...) { - va_list args; + va_list args; - va_start(args, format); - vprintf(format, args); - puts(""); - va_end(args); + va_start(args, format); + vprintf(format, args); + puts(""); + va_end(args); } #define DBG(args) internal_debug1(__FILE__, __LINE__);internal_debug2 args #else @@ -136,27 +134,29 @@ internal_debug2(const char *format, ... ) static char *ppdb_strcat(char *dest, char *src, char *def, int *size) { - int len; - char *res, *tmp; - - tmp = src; - if (tmp == NULL) - { - tmp = def; - if (tmp == NULL) return dest; - } - if (*tmp == '\0') return dest; - - len = strlen(dest) + strlen(tmp) + 1; - if (len > *size) - { - *size = len; - res = xrealloc(dest, *size); - } - else - res = dest; - strcat(res, tmp); - return res; + int len; + char *res, *tmp; + + tmp = src; + if (tmp == NULL) { + tmp = def; + if (tmp == NULL) { + return dest; + } + } + if (*tmp == '\0') { + return dest; + } + + len = strlen(dest) + strlen(tmp) + 1; + if (len > *size) { + *size = len; + res = xrealloc(dest, *size); + } else { + res = dest; + } + strcat(res, tmp); + return res; } #define STR_POOL_SIZE 16 /* !!! any power of 2 !!! */ @@ -168,368 +168,341 @@ static int str_poolp = -1; static void str_pool_init(void) { - int i; - for (i = 0; i < STR_POOL_SIZE; i++) - { - str_pool[i] = NULL; - str_pool_s[i] = 0; - } + int i; + for (i = 0; i < STR_POOL_SIZE; i++) { + str_pool[i] = NULL; + str_pool_s[i] = 0; + } } static void str_pool_deinit(void) { - int i; - - for (i = 0; i < STR_POOL_SIZE; i++) - if ( str_pool_s[i] != 0 ) - { - xfree(str_pool[i]); - str_pool[i] = NULL; - str_pool_s[i] = 0; - } + int i; + + for (i = 0; i < STR_POOL_SIZE; i++) + if (str_pool_s[i] != 0) { + xfree(str_pool[i]); + str_pool[i] = NULL; + str_pool_s[i] = 0; + } } static char *str_pool_get(size_t size) { - char *tmp; - - str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1)); - tmp = str_pool[str_poolp]; - - if (str_pool_s[str_poolp] == 0) - tmp = xmalloc(size); - else if (str_pool_s[str_poolp] < size) - tmp = xrealloc(tmp, size); - else - return tmp; - - str_pool[str_poolp] = tmp; - str_pool_s[str_poolp] = size; - - return tmp; + char *tmp; + + str_poolp = ((str_poolp + 1) & (STR_POOL_SIZE - 1)); + tmp = str_pool[str_poolp]; + + if (str_pool_s[str_poolp] == 0) { + tmp = xmalloc(size); + } else if (str_pool_s[str_poolp] < size) { + tmp = xrealloc(tmp, size); + } else { + return tmp; + } + + str_pool[str_poolp] = tmp; + str_pool_s[str_poolp] = size; + + return tmp; } static char *str_pool_getcpy(const char *src, char *def) { - char *res; - - if (src == NULL) - { - src = def; - if (src == NULL) src = ""; - } - res = str_pool_get(strlen(src) + 1); - strcpy(res, src); - - return res; + char *res; + + if (src == NULL) { + src = def; + if (src == NULL) { + src = ""; + } + } + res = str_pool_get(strlen(src) + 1); + strcpy(res, src); + + return res; } /* * decoding/formatting functions */ - + static char *ppdb_fmt_float(const double val) { - char *str = str_pool_get(32); - char *c; - snprintf(str, 32, "%.8f", val); - c = str + strlen(str) - 1; - while ((c > str) && (*c == '0')) - { - *c = '\0'; - c--; - if (*c == '.') - { - c++; - *c = '0'; - break; - } - } - return str; + char *str = str_pool_get(32); + char *c; + snprintf(str, 32, "%.8f", val); + c = str + strlen(str) - 1; + while ((c > str) && (*c == '0')) { + *c = '\0'; + c--; + if (*c == '.') { + c++; + *c = '0'; + break; + } + } + return str; } static char *ppdb_fmt_degrees(char dir, double val) { - char *str = str_pool_get(32); - int deg = fabs(val); - double min = 60.0 * (fabs(val) - deg); - char *tmp; - - snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); - - tmp = str + strlen(str) - 1; /* trim trailing nulls */ - while ((tmp > str) && (*tmp == '0')) - { - *tmp = '\0'; - tmp--; - if (*tmp == '.') - { - tmp++; - *tmp = '0'; - break; - } - } - return str; + char *str = str_pool_get(32); + int deg = fabs(val); + double min = 60.0 * (fabs(val) - deg); + char *tmp; + + snprintf(str, 31, "%c%0*d %.8f", dir, (deg > 99) ? 3 : 2, deg, min); + + tmp = str + strlen(str) - 1; /* trim trailing nulls */ + while ((tmp > str) && (*tmp == '0')) { + *tmp = '\0'; + tmp--; + if (*tmp == '.') { + tmp++; + *tmp = '0'; + break; + } + } + return str; } static double ppdb_decode_coord(const char *str) { - double val; - int deg; - char dir; - - if (*str < 'A') /* only numeric */ - { - CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1) DD.dddd", str); - return val; - } - else - { - char *tmp; - - if (*str == 'O') german_release = 1; - - tmp = strchr(str, ' '); - if ((tmp) && (tmp - str < 5)) - { - CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2) DD MM.mmm", str); - val = deg + (val / 60.0); - } - else - { - CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3) DD.dddd", str); - } - if ((dir == 'S') || (dir == 'W')) - val = -val; - } - return val; + double val; + int deg; + char dir; + + if (*str < 'A') { /* only numeric */ + CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1) DD.dddd", str); + return val; + } else { + char *tmp; + + if (*str == 'O') { + german_release = 1; + } + + tmp = strchr(str, ' '); + if ((tmp) && (tmp - str < 5)) { + CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, °, &val), "decode_coord(2) DD MM.mmm", str); + val = deg + (val / 60.0); + } else { + CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3) DD.dddd", str); + } + if ((dir == 'S') || (dir == 'W')) { + val = -val; + } + } + return val; } static int ppdb_decode_tm(char *str, struct tm *tm) { - int msec, d1, d2, d3, d4; - int year; - int temp=0; - char *cx; - - str = lrtrim(str); /* time field may start/end with spaces, drop them */ - - if (*str == '\0') - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Time value missing, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty time field */ - } - - if (strchr(str, '.')) /* time in hhmmss.ms */ - { - CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), - "decode_tm(1) hhmmss.ss", str); - } - else if (sscanf(str,"%06d",&temp)==1) - /* WORKAROUND read time info only if a valid 6 digit string found */ - { - CHECK_INP(3, sscanf(str, "%02d%02d%02d", - &tm->tm_hour, &tm->tm_min, &tm->tm_sec), - "decode_tm(2) hhmmss", str); - } - else - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Invalid time value, reseting to 0\n"); - warn_ = 1; - } - return 0; /* WORKAROUND maybe invalid time, just ignore it and continue */ - } - cx = strchr(str, ' '); - - if (cx == NULL) - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Date value missing, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty date field */ - } - - cx = lrtrim(cx); - if (*cx == '\0') - { - if (global_opts.debug_level > 0) - { - warning(MYNAME ": Date value missing, found only spaces, reseting to 0\n"); - warn_ = 1; - } - return 0; /* empty date field */ - } - - if (datefmt) - { - struct tm tm2; - - if (NULL == strptime(cx, datefmt, &tm2)) - { - fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); - } - - tm->tm_year = tm2.tm_year + 1900; - tm->tm_mon = tm2.tm_mon + 1; - tm->tm_mday = tm2.tm_mday; - } - else - { - time_t tnow; - struct tm now; - - - tnow = current_time(); - now = *localtime(&tnow); - now.tm_year += 1900; - now.tm_mon++; - - if (strlen(cx) == 8) - { - CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3) invalid date (YYYYMMDD)", cx); - - year = (d1 * 100) + d2; - /* the coordinates comes before date and time in - the dataset, so the flag "german_release" is set yet. */ - - /* next code works for most, except for 19. and 20. of month */ - - if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYYY ????? */ - { - tm->tm_year = (d3 * 100) + d4; - tm->tm_mon = d2; - tm->tm_mday = d1; - } - else - { - tm->tm_year = (d1 * 100) + d2; - tm->tm_mon = d3; - tm->tm_mday = d4; - } - } else if (strlen(cx) == 6) - { - CHECK_INP(3, sscanf(cx, "%02d%02d%02d", &d1, &d2, &d3), "decode_tm(3) invalid date (DDMMYY)", cx); - if (d3 < 1970) /* Usual Y2K interpretation */ - year = d3 + 2000; - else - year = d3 + 1900; - -/* I don't know how a german release handles this - * so for now I will assume only DDMMYY if date has 6 digits - */ - tm->tm_year = year; - tm->tm_mon = d2; - tm->tm_mday = d1; - } else /* date string is neither 8 nor 6 digits */ - { - printf(MYNAME ": Date from first record is %s.\n", cx); - printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); - fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); - } - } - return 1; + int msec, d1, d2, d3, d4; + int year; + int temp=0; + char *cx; + + str = lrtrim(str); /* time field may start/end with spaces, drop them */ + + if (*str == '\0') { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Time value missing, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty time field */ + } + + if (strchr(str, '.')) { /* time in hhmmss.ms */ + CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec), + "decode_tm(1) hhmmss.ss", str); + } else if (sscanf(str,"%06d",&temp)==1) + /* WORKAROUND read time info only if a valid 6 digit string found */ + { + CHECK_INP(3, sscanf(str, "%02d%02d%02d", + &tm->tm_hour, &tm->tm_min, &tm->tm_sec), + "decode_tm(2) hhmmss", str); + } else { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Invalid time value, reseting to 0\n"); + warn_ = 1; + } + return 0; /* WORKAROUND maybe invalid time, just ignore it and continue */ + } + cx = strchr(str, ' '); + + if (cx == NULL) { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Date value missing, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty date field */ + } + + cx = lrtrim(cx); + if (*cx == '\0') { + if (global_opts.debug_level > 0) { + warning(MYNAME ": Date value missing, found only spaces, reseting to 0\n"); + warn_ = 1; + } + return 0; /* empty date field */ + } + + if (datefmt) { + struct tm tm2; + + if (NULL == strptime(cx, datefmt, &tm2)) { + fatal(MYNAME ": Unable to convert date '%s' using format '%s' (%s)!\n", cx, datefmt, opt_date); + } + + tm->tm_year = tm2.tm_year + 1900; + tm->tm_mon = tm2.tm_mon + 1; + tm->tm_mday = tm2.tm_mday; + } else { + time_t tnow; + struct tm now; + + + tnow = current_time(); + now = *localtime(&tnow); + now.tm_year += 1900; + now.tm_mon++; + + if (strlen(cx) == 8) { + CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3) invalid date (YYYYMMDD)", cx); + + year = (d1 * 100) + d2; + /* the coordinates comes before date and time in + the dataset, so the flag "german_release" is set yet. */ + + /* next code works for most, except for 19. and 20. of month */ + + if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) { /* YYYYMMDD or DDMMYYYY ????? */ + tm->tm_year = (d3 * 100) + d4; + tm->tm_mon = d2; + tm->tm_mday = d1; + } else { + tm->tm_year = (d1 * 100) + d2; + tm->tm_mon = d3; + tm->tm_mday = d4; + } + } else if (strlen(cx) == 6) { + CHECK_INP(3, sscanf(cx, "%02d%02d%02d", &d1, &d2, &d3), "decode_tm(3) invalid date (DDMMYY)", cx); + if (d3 < 1970) { /* Usual Y2K interpretation */ + year = d3 + 2000; + } else { + year = d3 + 1900; + } + + /* I don't know how a german release handles this + * so for now I will assume only DDMMYY if date has 6 digits + */ + tm->tm_year = year; + tm->tm_mon = d2; + tm->tm_mday = d1; + } else { /* date string is neither 8 nor 6 digits */ + printf(MYNAME ": Date from first record is %s.\n", cx); + printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n"); + fatal(MYNAME ": (... -i pathaway,date=DDMMYY ...)\n"); + } + } + return 1; } -static +static int ppdb_read_wpt(route_head *head, int isRoute) { - char *data, *str; - double altfeet; - struct tm tm; - - while (pdb_read_rec(file_in, NULL, NULL, NULL, (void *)&data) >= 0) { - waypoint *wpt_tmp = waypt_new(); - int line = 0; - char *tmp = data; - -/* Print the whole input record. All input records are printed before processing. */ - if (global_opts.debug_level >= 5) - { - DBG(("\n\ + char *data, *str; + double altfeet; + struct tm tm; + + while (pdb_read_rec(file_in, NULL, NULL, NULL, (void *)&data) >= 0) { + waypoint *wpt_tmp = waypt_new(); + int line = 0; + char *tmp = data; + + /* Print the whole input record. All input records are printed before processing. */ + if (global_opts.debug_level >= 5) { + DBG(("\n\ --- BEGIN Input data record -----------------------------------------------\n\ %s\n\ --- END Input data record -------------------------------------------------\n",data)); - } - - while ((str = csv_lineparse(tmp, ",", "\"", line++))) { - tmp = NULL; - switch(line) - { - case 1: /* latitude */ - wpt_tmp->latitude = ppdb_decode_coord(str); - break; - case 2: /* longitude */ - wpt_tmp->longitude = ppdb_decode_coord(str); - break; - case 3: /* altitude */ - if (*str != '\0') - { - CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude", str); - if (altfeet != -9999) - wpt_tmp->altitude = FEET_TO_METERS(altfeet); - } - break; - case 4: /* time and date (optional) */ - memset(&tm, 0, sizeof(tm)); - if (ppdb_decode_tm(str, &tm)) - { - tm.tm_year -= 1900; - tm.tm_mon--; - wpt_tmp->creation_time = mkgmtime(&tm); - } - break; - case 5: /* name */ - if (*str != '\0') - wpt_tmp->shortname = xstrdup(str); - break; - case 6: /* icon */ - if (*str != '\0') - wpt_tmp->icon_descr = xstrdup(str); - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - break; - case 7: /* notes */ - if (*str != '\0') - wpt_tmp->notes = xstrdup(str); - break; - - } - } - -/* Print the whole input record, should a warning be triggered. - * Use warning() here instead of DBG() to print the data record - * right after the warning is issued. - */ - if (warn_ && (global_opts.debug_level > 1) && (global_opts.debug_level < 5)) - { - warning("Faulty input data record : %s\n",data); - warn_ = 0; - } - - if (head && isRoute ) - route_add_wpt(head, wpt_tmp); - else if (head) - track_add_wpt(head, wpt_tmp); - else - waypt_add(wpt_tmp); - - } - return 0; + } + + while ((str = csv_lineparse(tmp, ",", "\"", line++))) { + tmp = NULL; + switch (line) { + case 1: /* latitude */ + wpt_tmp->latitude = ppdb_decode_coord(str); + break; + case 2: /* longitude */ + wpt_tmp->longitude = ppdb_decode_coord(str); + break; + case 3: /* altitude */ + if (*str != '\0') { + CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude", str); + if (altfeet != -9999) { + wpt_tmp->altitude = FEET_TO_METERS(altfeet); + } + } + break; + case 4: /* time and date (optional) */ + memset(&tm, 0, sizeof(tm)); + if (ppdb_decode_tm(str, &tm)) { + tm.tm_year -= 1900; + tm.tm_mon--; + wpt_tmp->creation_time = mkgmtime(&tm); + } + break; + case 5: /* name */ + if (*str != '\0') { + wpt_tmp->shortname = xstrdup(str); + } + break; + case 6: /* icon */ + if (*str != '\0') { + wpt_tmp->icon_descr = xstrdup(str); + } + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + break; + case 7: /* notes */ + if (*str != '\0') { + wpt_tmp->notes = xstrdup(str); + } + break; + + } + } + + /* Print the whole input record, should a warning be triggered. + * Use warning() here instead of DBG() to print the data record + * right after the warning is issued. + */ + if (warn_ && (global_opts.debug_level > 1) && (global_opts.debug_level < 5)) { + warning("Faulty input data record : %s\n",data); + warn_ = 0; + } + + if (head && isRoute) { + route_add_wpt(head, wpt_tmp); + } else if (head) { + track_add_wpt(head, wpt_tmp); + } else { + waypt_add(wpt_tmp); + } + + } + return 0; } /* ============================================================================================ @@ -538,89 +511,89 @@ int ppdb_read_wpt(route_head *head, int isRoute) static void ppdb_rd_init(const char *fname) { - str_pool_init(); - file_in = pdb_open(fname, MYNAME); - ct = 0; - - if (opt_date) - datefmt = convert_human_date_format(opt_date); - else - datefmt = NULL; + str_pool_init(); + file_in = pdb_open(fname, MYNAME); + ct = 0; + + if (opt_date) { + datefmt = convert_human_date_format(opt_date); + } else { + datefmt = NULL; + } } static void ppdb_rd_deinit(void) { - pdb_close(file_in); - str_pool_deinit(); - if (datefmt) xfree(datefmt); + pdb_close(file_in); + str_pool_deinit(); + if (datefmt) { + xfree(datefmt); + } } static void ppdb_read(void) { - ppdb_appdata_t *info = NULL; - route_head *track_head, *route_head; - const char *descr = NULL; - - if (file_in->creator != PPDB_MAGIC) /* identify the database */ - fatal(MYNAME ": Not a PathAway pdb file.\n"); - - if (file_in->version != 3) /* Currently we support only version 3 */ - fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", file_in->version); - - if ((file_in->appinfo_len > 0) && (file_in->appinfo != NULL)) - { - info = (ppdb_appdata_t *) file_in->appinfo; - descr = info->vehicleStr; - } - switch(file_in->type) - { - case PPDB_MAGIC_TRK: - ppdb_type = trkdata; /* as default */ - if (info != NULL) - { - switch(info->dataBaseSubType) - { - case 0: - ppdb_type = trkdata; - break; - case 1: - ppdb_type = rtedata; - break; - default: - fatal(MYNAME": Invalid database subtype.\n"); - } - } - break; - - case PPDB_MAGIC_WPT: - ppdb_type = wptdata; - break; - - default: - fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n"); - } - - switch(ppdb_type) - { - case trkdata: - track_head = route_head_alloc(); - track_add_head(track_head); - track_head->rte_name = xstrdup(file_in->name); - ppdb_read_wpt(track_head, 0); - break; - case rtedata: - route_head = route_head_alloc(); - route_add_head(route_head); - route_head->rte_name = xstrdup(file_in->name); - ppdb_read_wpt(route_head, 1); - break; - case wptdata: - ppdb_read_wpt(NULL, 0); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + ppdb_appdata_t *info = NULL; + route_head *track_head, *route_head; + const char *descr = NULL; + + if (file_in->creator != PPDB_MAGIC) { /* identify the database */ + fatal(MYNAME ": Not a PathAway pdb file.\n"); + } + + if (file_in->version != 3) { /* Currently we support only version 3 */ + fatal(MYNAME ": This file is from an untested version (%d) of PathAway and is unsupported.\n", file_in->version); + } + + if ((file_in->appinfo_len > 0) && (file_in->appinfo != NULL)) { + info = (ppdb_appdata_t *) file_in->appinfo; + descr = info->vehicleStr; + } + switch (file_in->type) { + case PPDB_MAGIC_TRK: + ppdb_type = trkdata; /* as default */ + if (info != NULL) { + switch (info->dataBaseSubType) { + case 0: + ppdb_type = trkdata; + break; + case 1: + ppdb_type = rtedata; + break; + default: + fatal(MYNAME": Invalid database subtype.\n"); + } + } + break; + + case PPDB_MAGIC_WPT: + ppdb_type = wptdata; + break; + + default: + fatal(MYNAME ": It looks like a PathAway pdb, but has no gps magic.\n"); + } + + switch (ppdb_type) { + case trkdata: + track_head = route_head_alloc(); + track_add_head(track_head); + track_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(track_head, 0); + break; + case rtedata: + route_head = route_head_alloc(); + route_add_head(route_head); + route_head->rte_name = xstrdup(file_in->name); + ppdb_read_wpt(route_head, 1); + break; + case wptdata: + ppdb_read_wpt(NULL, 0); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } /* ============================================================================================ @@ -629,199 +602,207 @@ static void ppdb_read(void) static void ppdb_wr_init(const char *fname) { - int len; - - fname_out = xstrdup(fname); - str_pool_init(); - file_out = pdb_create(fname, MYNAME); - mkshort_handle = mkshort_new_handle(); - ct = 0; - appinfo = NULL; - - if (global_opts.synthesize_shortnames != 0) - { - len = atoi(opt_snlen); - setshort_length(mkshort_handle, len); - setshort_mustupper(mkshort_handle, 1); - setshort_badchars(mkshort_handle, ","); - setshort_whitespace_ok(mkshort_handle, 0); - } - if (opt_date) - { - char *c = convert_human_date_format(opt_date); - xasprintf(&datefmt, "%s %s", "%H%M%S", c); - xfree(c); - } - else - datefmt = xstrdup("%H%M%S %Y%m%d"); + int len; + + fname_out = xstrdup(fname); + str_pool_init(); + file_out = pdb_create(fname, MYNAME); + mkshort_handle = mkshort_new_handle(); + ct = 0; + appinfo = NULL; + + if (global_opts.synthesize_shortnames != 0) { + len = atoi(opt_snlen); + setshort_length(mkshort_handle, len); + setshort_mustupper(mkshort_handle, 1); + setshort_badchars(mkshort_handle, ","); + setshort_whitespace_ok(mkshort_handle, 0); + } + if (opt_date) { + char *c = convert_human_date_format(opt_date); + xasprintf(&datefmt, "%s %s", "%H%M%S", c); + xfree(c); + } else { + datefmt = xstrdup("%H%M%S %Y%m%d"); + } } static void ppdb_wr_deinit(void) { - mkshort_del_handle(&mkshort_handle); - pdb_close(file_out); - str_pool_deinit(); - xfree(fname_out); - if (datefmt) xfree(datefmt); - if (appinfo) xfree(appinfo); + mkshort_del_handle(&mkshort_handle); + pdb_close(file_out); + str_pool_deinit(); + xfree(fname_out); + if (datefmt) { + xfree(datefmt); + } + if (appinfo) { + xfree(appinfo); + } } /* * ppdb_write_wpt: callback for waypoint output - */ - + */ + #define REC_SIZE 128 static void ppdb_write_wpt(const waypoint *wpt) { - char *buff, *tmp; - char latdir, longdir; - int len; - struct tm tm; - - buff = xcalloc(REC_SIZE, 1); - - if (wpt->latitude < 0) - latdir = 'S'; - else - latdir = 'N'; - if (wpt->longitude < 0) - longdir = 'W'; - else - longdir = 'E'; - /* 1 latitude, - 2 longitude */ - - snprintf(buff, REC_SIZE, "%s,%s,", - ppdb_fmt_degrees(latdir, wpt->latitude), - ppdb_fmt_degrees(longdir, wpt->longitude) - ); - - len = REC_SIZE; /* we have coordinates in buff, now optional stuff */ - /* 3 altitude */ - - if (fabs(wpt->altitude) < 9999.0) - { - tmp = str_pool_get(32); - snprintf(tmp, 32, "%s", ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); - buff = ppdb_strcat(buff, tmp, NULL, &len); - } - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 4 time, date */ - - if ( wpt->creation_time != 0) - { - tmp = str_pool_get(20); - tm = *gmtime(&wpt->creation_time); - strftime(tmp, 20, datefmt, &tm); - buff = ppdb_strcat(buff, tmp, NULL, &len); - } - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 5 name */ - - if (global_opts.synthesize_shortnames != 0) - { - tmp = mkshort_from_wpt(mkshort_handle, wpt); - DBG(("shortname %s from %s", tmp, wpt->shortname)); - } - else - { - tmp = str_pool_getcpy(wpt->shortname, ""); - while (strchr(tmp, ',') != NULL) - *strchr(tmp, ',') = '.'; - } - buff = ppdb_strcat(buff, tmp, "", &len); - - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 6 icon */ - - tmp = str_pool_getcpy(wpt->icon_descr, opt_deficon); /* point icon or deficon from options */ - buff = ppdb_strcat(buff, tmp, NULL, &len); - buff = ppdb_strcat(buff, ",", NULL, &len); - /* 7 description */ - - tmp = str_pool_getcpy(wpt->description, ""); - if (strchr(tmp, ',') != NULL ) - { - buff = ppdb_strcat(buff, "\"", NULL, &len); - while (strchr(tmp, '"') != NULL) - *strchr(tmp, '"') = '\''; - buff = ppdb_strcat(buff, tmp, NULL, &len); - buff = ppdb_strcat(buff, "\"", NULL, &len); - } - else - buff = ppdb_strcat(buff, tmp, "", &len); - - len = strlen(buff) + 1; - pdb_write_rec(file_out, 0, 0, ct++, buff, len); - - xfree(buff); + char *buff, *tmp; + char latdir, longdir; + int len; + struct tm tm; + + buff = xcalloc(REC_SIZE, 1); + + if (wpt->latitude < 0) { + latdir = 'S'; + } else { + latdir = 'N'; + } + if (wpt->longitude < 0) { + longdir = 'W'; + } else { + longdir = 'E'; + } + /* 1 latitude, + 2 longitude */ + + snprintf(buff, REC_SIZE, "%s,%s,", + ppdb_fmt_degrees(latdir, wpt->latitude), + ppdb_fmt_degrees(longdir, wpt->longitude) + ); + + len = REC_SIZE; /* we have coordinates in buff, now optional stuff */ + /* 3 altitude */ + + if (fabs(wpt->altitude) < 9999.0) { + tmp = str_pool_get(32); + snprintf(tmp, 32, "%s", ppdb_fmt_float(METERS_TO_FEET(wpt->altitude))); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 4 time, date */ + + if (wpt->creation_time != 0) { + tmp = str_pool_get(20); + tm = *gmtime(&wpt->creation_time); + strftime(tmp, 20, datefmt, &tm); + buff = ppdb_strcat(buff, tmp, NULL, &len); + } + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 5 name */ + + if (global_opts.synthesize_shortnames != 0) { + tmp = mkshort_from_wpt(mkshort_handle, wpt); + DBG(("shortname %s from %s", tmp, wpt->shortname)); + } else { + tmp = str_pool_getcpy(wpt->shortname, ""); + while (strchr(tmp, ',') != NULL) { + *strchr(tmp, ',') = '.'; + } + } + buff = ppdb_strcat(buff, tmp, "", &len); + + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 6 icon */ + + tmp = str_pool_getcpy(wpt->icon_descr, opt_deficon); /* point icon or deficon from options */ + buff = ppdb_strcat(buff, tmp, NULL, &len); + buff = ppdb_strcat(buff, ",", NULL, &len); + /* 7 description */ + + tmp = str_pool_getcpy(wpt->description, ""); + if (strchr(tmp, ',') != NULL) { + buff = ppdb_strcat(buff, "\"", NULL, &len); + while (strchr(tmp, '"') != NULL) { + *strchr(tmp, '"') = '\''; + } + buff = ppdb_strcat(buff, tmp, NULL, &len); + buff = ppdb_strcat(buff, "\"", NULL, &len); + } else { + buff = ppdb_strcat(buff, tmp, "", &len); + } + + len = strlen(buff) + 1; + pdb_write_rec(file_out, 0, 0, ct++, buff, len); + + xfree(buff); } /* * track and route write callbacks */ - + static void ppdb_write(void) { - - if (opt_dbname) - strncpy(file_out->name, opt_dbname, PDB_DBNAMELEN); - - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->creator = PPDB_MAGIC; - file_out->version = 3; - -/* Waypoint target does use vehicleStr from appinfo block - * Actually, all 3 types have vehicle information. - * if (global_opts.objective != wptdata) / * Waypoint target do not need appinfo block * / - * { - */ - appinfo = xcalloc(1, sizeof(*appinfo)); - file_out->appinfo = (void *)appinfo; - file_out->appinfo_len = PPDB_APPINFO_SIZE; -/* } - */ - if (opt_dbicon != NULL) strncpy(appinfo->vehicleStr, opt_dbicon, VEHICLE_LEN); - - switch(global_opts.objective) /* Only one target is possible */ - { - case wptdata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Waypoints", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_WPT; - waypt_disp_all(ppdb_write_wpt); - break; - case trkdata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Track", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_TRK; - appinfo->dataBaseSubType = 0; - track_disp_all(NULL, NULL, ppdb_write_wpt); - break; - case rtedata: - if (opt_dbname == NULL) strncpy(file_out->name, "PathAway Route", PDB_DBNAMELEN); - file_out->type = PPDB_MAGIC_TRK; - appinfo->dataBaseSubType = 1; - route_disp_all(NULL, NULL, ppdb_write_wpt); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + + if (opt_dbname) { + strncpy(file_out->name, opt_dbname, PDB_DBNAMELEN); + } + + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->creator = PPDB_MAGIC; + file_out->version = 3; + + /* Waypoint target does use vehicleStr from appinfo block + * Actually, all 3 types have vehicle information. + * if (global_opts.objective != wptdata) / * Waypoint target do not need appinfo block * / + * { + */ + appinfo = xcalloc(1, sizeof(*appinfo)); + file_out->appinfo = (void *)appinfo; + file_out->appinfo_len = PPDB_APPINFO_SIZE; + /* } + */ + if (opt_dbicon != NULL) { + strncpy(appinfo->vehicleStr, opt_dbicon, VEHICLE_LEN); + } + + switch (global_opts.objective) { /* Only one target is possible */ + case wptdata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Waypoints", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_WPT; + waypt_disp_all(ppdb_write_wpt); + break; + case trkdata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Track", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 0; + track_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case rtedata: + if (opt_dbname == NULL) { + strncpy(file_out->name, "PathAway Route", PDB_DBNAMELEN); + } + file_out->type = PPDB_MAGIC_TRK; + appinfo->dataBaseSubType = 1; + route_disp_all(NULL, NULL, ppdb_write_wpt); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } ff_vecs_t ppdb_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - ppdb_rd_init, - ppdb_wr_init, - ppdb_rd_deinit, - ppdb_wr_deinit, - ppdb_read, - ppdb_write, - NULL, - ppdb_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + ppdb_rd_init, + ppdb_wr_init, + ppdb_rd_deinit, + ppdb_wr_deinit, + ppdb_read, + ppdb_write, + NULL, + ppdb_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif diff --git a/gpsbabel/pcx.c b/gpsbabel/pcx.c index 6a4437b97..c30ce305e 100644 --- a/gpsbabel/pcx.c +++ b/gpsbabel/pcx.c @@ -42,416 +42,430 @@ static int lon_col; static arglist_t pcx_args[] = { - {"deficon", &deficon, "Default icon name", "Waypoint", - ARGTYPE_STRING, ARG_NOMINMAX }, - {"cartoexploreur", &cartoexploreur, - "Write tracks compatible with Carto Exploreur", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "deficon", &deficon, "Default icon name", "Waypoint", + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "cartoexploreur", &cartoexploreur, + "Write tracks compatible with Carto Exploreur", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); - mkshort_handle2 = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); + mkshort_handle2 = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); - mkshort_del_handle(&mkshort_handle2); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle2); } static void data_read(void) { - char name[7], desc[41]; - double lat = 0, lon = 0; - long alt; - int symnum; - char date[10]; - char time[9]; - char month[4]; - waypoint *wpt_tmp; - char *buff; - struct tm tm; - route_head *track = NULL; - route_head *route = NULL; - int n; - char lathemi, lonhemi; - char tbuf[20]; - char nbuf[20]; - int points; - int line = 0; - - read_as_degrees = 0; - points = 0; - - while ((buff = gbfgetstr(file_in))) - { - char *ibuf = lrtrim(buff); - char *cp; - - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - switch (ibuf[0]) { - case 'W': - time[0] = 0; - date[0] = 0; - desc[0] = 0; - alt = -9999; - sscanf(ibuf, "W %6c %s %s %s %s %ld", - name, tbuf, nbuf, date, time, &alt); - if (alt == -9999) { - alt = unknown_alt; - } - - if (comment_col) { - strncpy(desc, &ibuf[comment_col], sizeof(desc)-1); - } else { - desc[0] = 0; - } - - - symnum = 18; - if (sym_col) { - symnum = atoi(&ibuf[sym_col]); - } - - // If we have explicit columns for lat and lon, - // copy those entire words (warning: no spaces) - // into the respective coord buffers. - if (lat_col) { - sscanf(tbuf, "%s", ibuf + lat_col); - } - if (lon_col) { - sscanf(nbuf, "%s", ibuf + lon_col); - } - - name[sizeof(name)-1] = '\0'; - desc[sizeof(desc)-1] = '\0'; - - wpt_tmp = waypt_new(); - wpt_tmp->altitude = alt; - cp = lrtrim(name); - if (*cp != '\0') { - wpt_tmp->shortname = xstrdup(cp); - } - cp = lrtrim(desc); - if (*cp != '\0') { - wpt_tmp->description = xstrdup(cp); - } - wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); - - if (read_as_degrees || read_gpsu) { - human_to_dec(tbuf, &lat, &lon, 1); - human_to_dec(nbuf, &lat, &lon, 2); - - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - } else { - lat = atof(&tbuf[1]); - lon = atof(&nbuf[1]); - if (tbuf[0] == 'S') lat = -lat; - if (nbuf[0] == 'W') lon = -lon; - wpt_tmp->longitude = ddmm2degrees(lon); - wpt_tmp->latitude = ddmm2degrees(lat); - } - if (route != NULL) - route_add_wpt(route, waypt_dupe(wpt_tmp)); - waypt_add(wpt_tmp); - points++; - break; - case 'H': - /* Garmap2 has headers - "H(2 spaces)LATITUDE(some spaces)LONGTITUDE(etc... followed by);track - everything else is - H(2 chars)TN(tracknane\0) - */ - if (points > 0) { - track = NULL; - points = 0; - } - if (track == NULL) { - if (ibuf[3] == 'L' && ibuf[4] == 'A') { - track = route_head_alloc(); - track->rte_name = xstrdup("track"); - track_add_head(track); - } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { - track = route_head_alloc(); - track->rte_name = xstrdup(&ibuf[6]); - track_add_head(track); - } - } - break; - case 'R': - n = 1; - while (ibuf[n] == ' ') n++; - route = route_head_alloc(); - route->rte_name = xstrdup(&ibuf[n]); - route_add_head(route); - break; - case 'T': - n = sscanf(ibuf, "T %lf %lf %s %s %ld", - &lat, &lon, date, time, &alt); - - if (n == 0) { - /* Attempt alternate PCX format used by - * www.radroutenplaner.nrw.de */ - n = sscanf(ibuf, "T %c%lf %c%lf %s %s %ld", - &lathemi, &lat, &lonhemi, &lon, date, - time, &alt); - if (lathemi == 'S') lat = -lat; - if (lonhemi == 'W') lon = -lon; - } else if (n == 0) { - fatal(MYNAME ":Unrecognized track line '%s'\n", - ibuf); - } - - memset(&tm, 0, sizeof(tm)); - tm.tm_hour = atoi(time); - tm.tm_min = atoi(time+3); - tm.tm_sec = atoi(time+6); - tm.tm_mday = atoi(date); - strncpy(month, date+3, 3); - month[3] = 0; - tm.tm_mon = month_lookup(month); - tm.tm_year = atoi(date + 7); - if (tm.tm_year < 70) tm.tm_year += 100; - wpt_tmp = waypt_new(); - wpt_tmp->creation_time = mkgmtime(&tm); - if (read_as_degrees) { - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - } else { - wpt_tmp->longitude = ddmm2degrees(lon); - wpt_tmp->latitude = ddmm2degrees(lat); - } - wpt_tmp->altitude = alt; - /* Did we get a track point before a track header? */ - if (track == NULL) { - track = route_head_alloc(); - track->rte_name = xstrdup("Default"); - track_add_head(track); - } - track_add_wpt(track, wpt_tmp); - points++; - break; - case 'U': - read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); - if (strstr(ibuf, "UTM")) { - fatal (MYNAME ": UTM is not supported.\n"); - } - break; - // GPSU is apparently PCX but with a different definition - // of "LAT LON DM" - unlike the other, it actually IS decimal - // minutes. - case 'I': - read_gpsu = ! (strstr(ibuf, "GPSU") == NULL) ; - break; - // This is a format specifier. Use this line to figure out - // where our other columns start. - case 'F': { - int col; - char *i = ibuf; - sym_col = 0; - - for (col = 0, i = ibuf; *i; col++, i++) { - if (0 == case_ignore_strncmp(i, "comment", 7)) { - comment_col = col; - } - if (0 == case_ignore_strncmp(i, "symbol", 6)) { - sym_col = col; - } - if (0 == case_ignore_strncmp(i, "latitude", 8)) { - lat_col = col; - } - if (0 == case_ignore_strncmp(i, "longitude", 9)) { - lon_col = col; - } - } - } - break; - default: - break; - ; - - } - } + char name[7], desc[41]; + double lat = 0, lon = 0; + long alt; + int symnum; + char date[10]; + char time[9]; + char month[4]; + waypoint *wpt_tmp; + char *buff; + struct tm tm; + route_head *track = NULL; + route_head *route = NULL; + int n; + char lathemi, lonhemi; + char tbuf[20]; + char nbuf[20]; + int points; + int line = 0; + + read_as_degrees = 0; + points = 0; + + while ((buff = gbfgetstr(file_in))) { + char *ibuf = lrtrim(buff); + char *cp; + + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + switch (ibuf[0]) { + case 'W': + time[0] = 0; + date[0] = 0; + desc[0] = 0; + alt = -9999; + sscanf(ibuf, "W %6c %s %s %s %s %ld", + name, tbuf, nbuf, date, time, &alt); + if (alt == -9999) { + alt = unknown_alt; + } + + if (comment_col) { + strncpy(desc, &ibuf[comment_col], sizeof(desc)-1); + } else { + desc[0] = 0; + } + + + symnum = 18; + if (sym_col) { + symnum = atoi(&ibuf[sym_col]); + } + + // If we have explicit columns for lat and lon, + // copy those entire words (warning: no spaces) + // into the respective coord buffers. + if (lat_col) { + sscanf(tbuf, "%s", ibuf + lat_col); + } + if (lon_col) { + sscanf(nbuf, "%s", ibuf + lon_col); + } + + name[sizeof(name)-1] = '\0'; + desc[sizeof(desc)-1] = '\0'; + + wpt_tmp = waypt_new(); + wpt_tmp->altitude = alt; + cp = lrtrim(name); + if (*cp != '\0') { + wpt_tmp->shortname = xstrdup(cp); + } + cp = lrtrim(desc); + if (*cp != '\0') { + wpt_tmp->description = xstrdup(cp); + } + wpt_tmp->icon_descr = gt_find_desc_from_icon_number(symnum, PCX, NULL); + + if (read_as_degrees || read_gpsu) { + human_to_dec(tbuf, &lat, &lon, 1); + human_to_dec(nbuf, &lat, &lon, 2); + + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + lat = atof(&tbuf[1]); + lon = atof(&nbuf[1]); + if (tbuf[0] == 'S') { + lat = -lat; + } + if (nbuf[0] == 'W') { + lon = -lon; + } + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + if (route != NULL) { + route_add_wpt(route, waypt_dupe(wpt_tmp)); + } + waypt_add(wpt_tmp); + points++; + break; + case 'H': + /* Garmap2 has headers + "H(2 spaces)LATITUDE(some spaces)LONGTITUDE(etc... followed by);track + everything else is + H(2 chars)TN(tracknane\0) + */ + if (points > 0) { + track = NULL; + points = 0; + } + if (track == NULL) { + if (ibuf[3] == 'L' && ibuf[4] == 'A') { + track = route_head_alloc(); + track->rte_name = xstrdup("track"); + track_add_head(track); + } else if (ibuf[3] == 'T' && ibuf[4] == 'N') { + track = route_head_alloc(); + track->rte_name = xstrdup(&ibuf[6]); + track_add_head(track); + } + } + break; + case 'R': + n = 1; + while (ibuf[n] == ' ') { + n++; + } + route = route_head_alloc(); + route->rte_name = xstrdup(&ibuf[n]); + route_add_head(route); + break; + case 'T': + n = sscanf(ibuf, "T %lf %lf %s %s %ld", + &lat, &lon, date, time, &alt); + + if (n == 0) { + /* Attempt alternate PCX format used by + * www.radroutenplaner.nrw.de */ + n = sscanf(ibuf, "T %c%lf %c%lf %s %s %ld", + &lathemi, &lat, &lonhemi, &lon, date, + time, &alt); + if (lathemi == 'S') { + lat = -lat; + } + if (lonhemi == 'W') { + lon = -lon; + } + } else if (n == 0) { + fatal(MYNAME ":Unrecognized track line '%s'\n", + ibuf); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_hour = atoi(time); + tm.tm_min = atoi(time+3); + tm.tm_sec = atoi(time+6); + tm.tm_mday = atoi(date); + strncpy(month, date+3, 3); + month[3] = 0; + tm.tm_mon = month_lookup(month); + tm.tm_year = atoi(date + 7); + if (tm.tm_year < 70) { + tm.tm_year += 100; + } + wpt_tmp = waypt_new(); + wpt_tmp->creation_time = mkgmtime(&tm); + if (read_as_degrees) { + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + } else { + wpt_tmp->longitude = ddmm2degrees(lon); + wpt_tmp->latitude = ddmm2degrees(lat); + } + wpt_tmp->altitude = alt; + /* Did we get a track point before a track header? */ + if (track == NULL) { + track = route_head_alloc(); + track->rte_name = xstrdup("Default"); + track_add_head(track); + } + track_add_wpt(track, wpt_tmp); + points++; + break; + case 'U': + read_as_degrees = ! strncmp("LAT LON DEG", ibuf + 3, 11); + if (strstr(ibuf, "UTM")) { + fatal(MYNAME ": UTM is not supported.\n"); + } + break; + // GPSU is apparently PCX but with a different definition + // of "LAT LON DM" - unlike the other, it actually IS decimal + // minutes. + case 'I': + read_gpsu = !(strstr(ibuf, "GPSU") == NULL) ; + break; + // This is a format specifier. Use this line to figure out + // where our other columns start. + case 'F': { + int col; + char *i = ibuf; + sym_col = 0; + + for (col = 0, i = ibuf; *i; col++, i++) { + if (0 == case_ignore_strncmp(i, "comment", 7)) { + comment_col = col; + } + if (0 == case_ignore_strncmp(i, "symbol", 6)) { + sym_col = col; + } + if (0 == case_ignore_strncmp(i, "latitude", 8)) { + lat_col = col; + } + if (0 == case_ignore_strncmp(i, "longitude", 9)) { + lon_col = col; + } + } + } + break; + default: + break; + ; + + } + } } static void gpsutil_disp(const waypoint *wpt) { - double lon,lat; - int icon_token = 0; - char tbuf[1024]; - time_t tm = wpt->creation_time; - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - if (tm == 0) - tm = current_time(); - strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); - strupper(tbuf); - - if (deficon) { - icon_token = atoi(deficon); - } else { - icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - if (get_cache_icon(wpt)) { - icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } - } - - - gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5.f %-40.40s %5e %d\n", - global_opts.synthesize_shortnames ? - mkshort_from_wpt(mkshort_handle, wpt) : - wpt->shortname, - lat < 0.0 ? 'S' : 'N', - fabs(lat), - lon < 0.0 ? 'W' : 'E', - fabs(lon), - tbuf, - (wpt->altitude == unknown_alt) ? -9999 : wpt->altitude, - (wpt->description != NULL) ? wpt->description : "", - 0.0, - icon_token); + double lon,lat; + int icon_token = 0; + char tbuf[1024]; + time_t tm = wpt->creation_time; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + if (tm == 0) { + tm = current_time(); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %I:%M:%S", localtime(&tm)); + strupper(tbuf); + + if (deficon) { + icon_token = atoi(deficon); + } else { + icon_token = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + if (get_cache_icon(wpt)) { + icon_token = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + } + + + gbfprintf(file_out, "W %-6.6s %c%08.5f %c%011.5f %s %5.f %-40.40s %5e %d\n", + global_opts.synthesize_shortnames ? + mkshort_from_wpt(mkshort_handle, wpt) : + wpt->shortname, + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, + (wpt->altitude == unknown_alt) ? -9999 : wpt->altitude, + (wpt->description != NULL) ? wpt->description : "", + 0.0, + icon_token); } static void pcx_track_hdr(const route_head *trk) { - char *name; - char buff[20]; - - route_ctr++; - snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); - - name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); - /* Carto Exploreur (popular in France) chokes on trackname headers, - * so provide option to supppress these. - */ - if (!cartoexploreur) { - gbfprintf(file_out, "\n\nH TN %s\n", name); - } - xfree(name); - gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Trk%03d", route_ctr); + + name = mkshort(mkshort_handle2, (trk->rte_name != NULL) ? trk->rte_name : buff); + /* Carto Exploreur (popular in France) chokes on trackname headers, + * so provide option to supppress these. + */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nH TN %s\n", name); + } + xfree(name); + gbfprintf(file_out, "H LATITUDE LONGITUDE DATE TIME ALT ;track\n"); } static void pcx_route_hdr(const route_head *rte) { - char *name; - char buff[20]; - - route_ctr++; - snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); - - name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); - - /* see pcx_track_hdr */ - if (!cartoexploreur) { - gbfprintf(file_out, "\n\nR %s\n", name); - } - gbfprintf(file_out, "\n" -"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + char *name; + char buff[20]; + + route_ctr++; + snprintf(buff, sizeof(buff)-1, "Rte%03d", route_ctr); + + name = mkshort(mkshort_handle2, (rte->rte_name != NULL) ? rte->rte_name : buff); + + /* see pcx_track_hdr */ + if (!cartoexploreur) { + gbfprintf(file_out, "\n\nR %s\n", name); + } + gbfprintf(file_out, "\n" + "H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); } void pcx_track_disp(const waypoint *wpt) { - double lon,lat; - char tbuf[100]; - struct tm *tm; - char *tp; - - lon = degrees2ddmm(wpt->longitude); - lat = degrees2ddmm(wpt->latitude); - - tm = gmtime(&wpt->creation_time); - - strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ - for (tp = tbuf; *tp; tp++) { - *tp = toupper(*tp); - } - gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", - lat < 0.0 ? 'S' : 'N', - fabs(lat), - lon < 0.0 ? 'W' : 'E', - fabs(lon), - tbuf, wpt->altitude); + double lon,lat; + char tbuf[100]; + struct tm *tm; + char *tp; + + lon = degrees2ddmm(wpt->longitude); + lat = degrees2ddmm(wpt->latitude); + + tm = gmtime(&wpt->creation_time); + + strftime(tbuf, sizeof(tbuf), "%d-%b-%y %H:%M:%S", tm); /* currently ...%T does nothing under Windows */ + for (tp = tbuf; *tp; tp++) { + *tp = toupper(*tp); + } + gbfprintf(file_out, "T %c%08.5f %c%011.5f %s %.f\n", + lat < 0.0 ? 'S' : 'N', + fabs(lat), + lon < 0.0 ? 'W' : 'E', + fabs(lon), + tbuf, wpt->altitude); } static void data_write(void) { -gbfprintf(file_out, -"H SOFTWARE NAME & VERSION\n" -"I PCX5 2.09\n" -"\n" -"H R DATUM IDX DA DF DX DY DZ\n" -"M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" -"\n" -"H COORDINATE SYSTEM\n" -"U LAT LON DM\n"); - - setshort_length(mkshort_handle, 6); - - setshort_length(mkshort_handle2, 20); /* for track and route names */ - setshort_whitespace_ok(mkshort_handle2, 0); - setshort_mustuniq(mkshort_handle2, 0); - - if (global_opts.objective == wptdata) - { - gbfprintf(file_out, -"\n" -"H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); - - waypt_disp_all(gpsutil_disp); - } - else if (global_opts.objective == trkdata) - { - route_ctr = 0; - track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); - } - else if (global_opts.objective == rtedata) - { - route_ctr = 0; - route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); - } + gbfprintf(file_out, + "H SOFTWARE NAME & VERSION\n" + "I PCX5 2.09\n" + "\n" + "H R DATUM IDX DA DF DX DY DZ\n" + "M G WGS 84 121 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00 +0.000000e+00\n" + "\n" + "H COORDINATE SYSTEM\n" + "U LAT LON DM\n"); + + setshort_length(mkshort_handle, 6); + + setshort_length(mkshort_handle2, 20); /* for track and route names */ + setshort_whitespace_ok(mkshort_handle2, 0); + setshort_mustuniq(mkshort_handle2, 0); + + if (global_opts.objective == wptdata) { + gbfprintf(file_out, + "\n" + "H IDNT LATITUDE LONGITUDE DATE TIME ALT DESCRIPTION PROXIMITY SYMBOL ;waypts\n"); + + waypt_disp_all(gpsutil_disp); + } else if (global_opts.objective == trkdata) { + route_ctr = 0; + track_disp_all(pcx_track_hdr, NULL, pcx_track_disp); + } else if (global_opts.objective == rtedata) { + route_ctr = 0; + route_disp_all(pcx_route_hdr, NULL, gpsutil_disp); + } } ff_vecs_t pcx_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - pcx_args, - CET_CHARSET_ASCII, 1 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + pcx_args, + CET_CHARSET_ASCII, 1 /* CET-REVIEW */ }; diff --git a/gpsbabel/pdbfile.c b/gpsbabel/pdbfile.c index 8c852d42e..78205fe4d 100644 --- a/gpsbabel/pdbfile.c +++ b/gpsbabel/pdbfile.c @@ -4,7 +4,7 @@ Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org Written after study the Coldsync project - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -36,15 +36,15 @@ static void pdb_invalid_file(const pdbfile *pdb_in, const char *fmt, ...) { - char buff[128]; - va_list args; - - va_start(args, fmt); - vsnprintf(buff, sizeof(buff), fmt, args); - buff[sizeof(buff)-1] = '0'; - - warning(MYNAME ": %s\n", buff); - fatal(MYNAME ": Invalid or unsupported file (%s).\n", pdb_in->file->name); + char buff[128]; + va_list args; + + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + buff[sizeof(buff)-1] = '0'; + + warning(MYNAME ": %s\n", buff); + fatal(MYNAME ": Invalid or unsupported file (%s).\n", pdb_in->file->name); } /* try to read to EOF (avoid determining file-size) */ @@ -52,250 +52,279 @@ pdb_invalid_file(const pdbfile *pdb_in, const char *fmt, ...) static void * pdb_read_tail(gbfile *fin, gbuint32 *size) { - int count; - char buff[256]; - char *res = NULL; - int bytes = 0; - - while ((count = gbfread(buff, 1, sizeof(buff), fin))) { - - if (!res) { - res = (char *) xmalloc(count); - memcpy(res, buff, count); - } - else { - res = xrealloc(res, bytes + count); - memcpy(&res[bytes], buff, count); - } - bytes += count; - } - if (res) res = xrealloc(res, bytes + 1); - else res = xmalloc(1); - res[bytes] = '\0'; - - if (size) *size = bytes; - return (void *)res; + int count; + char buff[256]; + char *res = NULL; + int bytes = 0; + + while ((count = gbfread(buff, 1, sizeof(buff), fin))) { + + if (!res) { + res = (char *) xmalloc(count); + memcpy(res, buff, count); + } else { + res = xrealloc(res, bytes + count); + memcpy(&res[bytes], buff, count); + } + bytes += count; + } + if (res) { + res = xrealloc(res, bytes + 1); + } else { + res = xmalloc(1); + } + res[bytes] = '\0'; + + if (size) { + *size = bytes; + } + return (void *)res; } static void pdb_load_data(pdbfile *fin) { - gbuint16 i, ct; - pdbrec_t *last_rec; - gbuint32 offs; - pdbrec_t *rec; - - /* load the header */ - gbfread(fin->name, 1, PDB_DBNAMELEN, fin->file); - fin->name[PDB_DBNAMELEN] = '\0'; - - fin->attr = gbfgetuint16(fin->file); - fin->version = gbfgetuint16(fin->file); - fin->ctime = gbfgetuint32(fin->file); - fin->mtime = gbfgetuint32(fin->file); - fin->btime = gbfgetuint32(fin->file); - fin->revision = gbfgetuint32(fin->file); - fin->appinfo_offs = gbfgetint32(fin->file); - fin->index_offs = gbfgetuint32(fin->file); - fin->type = gbfgetuint32(fin->file); - fin->creator = gbfgetuint32(fin->file); - fin->uid = gbfgetuint32(fin->file); - - if (fin->appinfo_offs < 0) - pdb_invalid_file(fin, "Invalid application data offset (%0xh)", fin->appinfo_offs); - if (fin->index_offs < 0) - pdb_invalid_file(fin, "Invalid index offset (%0xh)", fin->index_offs); - + gbuint16 i, ct; + pdbrec_t *last_rec; + gbuint32 offs; + pdbrec_t *rec; + + /* load the header */ + gbfread(fin->name, 1, PDB_DBNAMELEN, fin->file); + fin->name[PDB_DBNAMELEN] = '\0'; + + fin->attr = gbfgetuint16(fin->file); + fin->version = gbfgetuint16(fin->file); + fin->ctime = gbfgetuint32(fin->file); + fin->mtime = gbfgetuint32(fin->file); + fin->btime = gbfgetuint32(fin->file); + fin->revision = gbfgetuint32(fin->file); + fin->appinfo_offs = gbfgetint32(fin->file); + fin->index_offs = gbfgetuint32(fin->file); + fin->type = gbfgetuint32(fin->file); + fin->creator = gbfgetuint32(fin->file); + fin->uid = gbfgetuint32(fin->file); + + if (fin->appinfo_offs < 0) { + pdb_invalid_file(fin, "Invalid application data offset (%0xh)", fin->appinfo_offs); + } + if (fin->index_offs < 0) { + pdb_invalid_file(fin, "Invalid index offset (%0xh)", fin->index_offs); + } + #if 0 - fprintf(stderr, "%s: dbname \"%s\"\n", MYNAME, fin->name); - fprintf(stderr, "%s: attr %-8x\n", MYNAME, fin->attr); - fprintf(stderr, "%s: creator %-8x\n", MYNAME, fin->creator); - fprintf(stderr, "%s: type %-8x\n", MYNAME, fin->type); - fprintf(stderr, "%s: ver %-8u\n", MYNAME, fin->version); - fprintf(stderr, "%s: app-ofs %-8u\n", MYNAME, fin->appinfo_offs); - fprintf(stderr, "%s: index-ofs %-8u\n", MYNAME, fin->index_offs); -#endif - /* ID = */ (void) gbfgetuint32(fin->file); - ct = fin->rec_ct = gbfgetint16(fin->file); - if (ct >= 0x7FFF) - warning(MYNAME ": Probably invalid number of records (%0d)\n", fin->rec_ct); - - offs = 78; - - last_rec = NULL; - for (i = 0; i < ct; i++) { - pdbrec_t *rec; - - rec = xcalloc(1, sizeof(*rec)); - if (fin->attr & PDB_FLAG_RESOURCE) { - (void) gbfgetuint32(fin->file); /* type */ - rec->id = gbfgetint16(fin->file); - rec->offs = gbfgetuint32(fin->file); - if ((gbint32)rec->offs < 0) - pdb_invalid_file(fin, "Invalid offset to record (%0d, id = %d)", rec->offs, rec->id); - } - else { - gbuint32 x; - - rec->offs = gbfgetint32(fin->file); - x = gbfgetuint32(fin->file); - rec->id = x & 0x0ffff; - rec->category = (x >> 24) & 0x0f; - rec->flags = (x >> 24) & 0xf0; - if ((gbint32)rec->offs < 0) - pdb_invalid_file(fin, "Invalid offset to resource record (%0d, id = %d)", rec->offs, rec->id); - } - - if (last_rec == NULL) - fin->rec_list = rec; - else - last_rec->next = rec; - last_rec = rec; - } - - offs += (ct * 8); - last_rec = fin->rec_list; - - if (fin->appinfo_offs != 0) { - gbuint32 top; - - /* seek to application info offset */ - while (offs < fin->appinfo_offs) { - (void)gbfgetc(fin->file); - offs++; - } - - /* determine the length of application info */ - if (fin->index_offs != 0) top = fin->index_offs; - else top = 0x7FFFFFFU; - if (last_rec && (last_rec->offs < top)) top = last_rec->offs; - - if (top != 0x7FFFFFFU) { - fin->appinfo = xmalloc(top - offs); - fin->appinfo_len = gbfread(fin->appinfo, 1, top - offs, fin->file); - offs += fin->appinfo_len; - } - else { - gbuint32 size; - fin->appinfo = pdb_read_tail(fin->file, &size); - fin->appinfo_len = size; - offs += size; - } - } - - for (rec = fin->rec_list; rec; rec = rec->next) { - /* seek to current record */ - while (offs < rec->offs) { - (void) gbfgetc(fin->file); - offs++; - } - if (rec->next) { - rec->size = (gbint32)rec->next->offs - (gbint32)offs; - if (rec->size > 0) { - rec->data = xmalloc(rec->size); - rec->size = gbfread(rec->data, 1, rec->size, fin->file); - offs += rec->size; - } - else if (rec->size < 0) - pdb_invalid_file(fin, "Wrong data size in record with id %d.\n", rec->id); - } - else { - rec->data = pdb_read_tail(fin->file, &rec->size); - offs += rec->size; - } - } + fprintf(stderr, "%s: dbname \"%s\"\n", MYNAME, fin->name); + fprintf(stderr, "%s: attr %-8x\n", MYNAME, fin->attr); + fprintf(stderr, "%s: creator %-8x\n", MYNAME, fin->creator); + fprintf(stderr, "%s: type %-8x\n", MYNAME, fin->type); + fprintf(stderr, "%s: ver %-8u\n", MYNAME, fin->version); + fprintf(stderr, "%s: app-ofs %-8u\n", MYNAME, fin->appinfo_offs); + fprintf(stderr, "%s: index-ofs %-8u\n", MYNAME, fin->index_offs); +#endif + /* ID = */ (void) gbfgetuint32(fin->file); + ct = fin->rec_ct = gbfgetint16(fin->file); + if (ct >= 0x7FFF) { + warning(MYNAME ": Probably invalid number of records (%0d)\n", fin->rec_ct); + } + + offs = 78; + + last_rec = NULL; + for (i = 0; i < ct; i++) { + pdbrec_t *rec; + + rec = xcalloc(1, sizeof(*rec)); + if (fin->attr & PDB_FLAG_RESOURCE) { + (void) gbfgetuint32(fin->file); /* type */ + rec->id = gbfgetint16(fin->file); + rec->offs = gbfgetuint32(fin->file); + if ((gbint32)rec->offs < 0) { + pdb_invalid_file(fin, "Invalid offset to record (%0d, id = %d)", rec->offs, rec->id); + } + } else { + gbuint32 x; + + rec->offs = gbfgetint32(fin->file); + x = gbfgetuint32(fin->file); + rec->id = x & 0x0ffff; + rec->category = (x >> 24) & 0x0f; + rec->flags = (x >> 24) & 0xf0; + if ((gbint32)rec->offs < 0) { + pdb_invalid_file(fin, "Invalid offset to resource record (%0d, id = %d)", rec->offs, rec->id); + } + } + + if (last_rec == NULL) { + fin->rec_list = rec; + } else { + last_rec->next = rec; + } + last_rec = rec; + } + + offs += (ct * 8); + last_rec = fin->rec_list; + + if (fin->appinfo_offs != 0) { + gbuint32 top; + + /* seek to application info offset */ + while (offs < fin->appinfo_offs) { + (void)gbfgetc(fin->file); + offs++; + } + + /* determine the length of application info */ + if (fin->index_offs != 0) { + top = fin->index_offs; + } else { + top = 0x7FFFFFFU; + } + if (last_rec && (last_rec->offs < top)) { + top = last_rec->offs; + } + + if (top != 0x7FFFFFFU) { + fin->appinfo = xmalloc(top - offs); + fin->appinfo_len = gbfread(fin->appinfo, 1, top - offs, fin->file); + offs += fin->appinfo_len; + } else { + gbuint32 size; + fin->appinfo = pdb_read_tail(fin->file, &size); + fin->appinfo_len = size; + offs += size; + } + } + + for (rec = fin->rec_list; rec; rec = rec->next) { + /* seek to current record */ + while (offs < rec->offs) { + (void) gbfgetc(fin->file); + offs++; + } + if (rec->next) { + rec->size = (gbint32)rec->next->offs - (gbint32)offs; + if (rec->size > 0) { + rec->data = xmalloc(rec->size); + rec->size = gbfread(rec->data, 1, rec->size, fin->file); + offs += rec->size; + } else if (rec->size < 0) { + pdb_invalid_file(fin, "Wrong data size in record with id %d.\n", rec->id); + } + } else { + rec->data = pdb_read_tail(fin->file, &rec->size); + offs += rec->size; + } + } } pdbfile * pdb_open(const char *filename, const char *module) { - pdbfile *res; - - res = xcalloc(1, sizeof(*res)); - res->file = gbfopen_be(filename, "rb", module); - res->mode = 1; - - pdb_load_data(res); - pdb_rewind(res); - - return res; + pdbfile *res; + + res = xcalloc(1, sizeof(*res)); + res->file = gbfopen_be(filename, "rb", module); + res->mode = 1; + + pdb_load_data(res); + pdb_rewind(res); + + return res; } int pdb_read_rec_by_id(pdbfile *fin, const gbuint32 rec_id, gbuint8 *flags, gbuint8 *category, void **data) { - pdbrec_t *rec; - - for (rec = fin->rec_list; rec; rec = rec->next) { - if (rec->id == rec_id) { - if (data) *data = rec->data; - if (flags) *flags = rec->flags; - if (category) *category = rec->category; - return rec->size; - } - } - return -1; + pdbrec_t *rec; + + for (rec = fin->rec_list; rec; rec = rec->next) { + if (rec->id == rec_id) { + if (data) { + *data = rec->data; + } + if (flags) { + *flags = rec->flags; + } + if (category) { + *category = rec->category; + } + return rec->size; + } + } + return -1; } pdbfile * pdb_create(const char *filename, const char *module) { - pdbfile *res; + pdbfile *res; - res = xcalloc(1, sizeof(*res)); - strncpy(res->name, "Palm/OS Database", PDB_DBNAMELEN); - res->file = gbfopen_be(filename, "wb", module);; - res->mode = 2; + res = xcalloc(1, sizeof(*res)); + strncpy(res->name, "Palm/OS Database", PDB_DBNAMELEN); + res->file = gbfopen_be(filename, "wb", module);; + res->mode = 2; - return res; + return res; } -void +void pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const gbuint32 rec_id, const void *data, const gbuint32 size) { - pdbrec_t *rec, *cur; - - rec = xcalloc(1, sizeof(*rec)); - rec->category = category; - rec->flags = category; - rec->id = rec_id; - rec->size = size; - if (size > 0) { - rec->data = xmalloc(size); - memcpy(rec->data, data, size); - } - - /* insert rec into rec_list sorted by id */ - cur = fout->rec_list; - if (cur == NULL) fout->rec_list = rec; - else { - pdbrec_t *prev = NULL; - - while (cur) { - if (rec_id < cur->id) { - rec->next = cur; - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - break; - } - else if (rec_id == cur->id) { /* Overwrite record with id ... */ - rec->next = cur->next; - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - if (cur->data) xfree(cur->data); - xfree(cur); - cur = rec; - break; - } - prev = cur; - cur = cur->next; - } - if (! cur) { - if (prev == NULL) fout->rec_list = rec; - else prev->next = rec; - } - } - fout->rec_ct++; + pdbrec_t *rec, *cur; + + rec = xcalloc(1, sizeof(*rec)); + rec->category = category; + rec->flags = category; + rec->id = rec_id; + rec->size = size; + if (size > 0) { + rec->data = xmalloc(size); + memcpy(rec->data, data, size); + } + + /* insert rec into rec_list sorted by id */ + cur = fout->rec_list; + if (cur == NULL) { + fout->rec_list = rec; + } else { + pdbrec_t *prev = NULL; + + while (cur) { + if (rec_id < cur->id) { + rec->next = cur; + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + break; + } else if (rec_id == cur->id) { /* Overwrite record with id ... */ + rec->next = cur->next; + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + if (cur->data) { + xfree(cur->data); + } + xfree(cur); + cur = rec; + break; + } + prev = cur; + cur = cur->next; + } + if (! cur) { + if (prev == NULL) { + fout->rec_list = rec; + } else { + prev->next = rec; + } + } + } + fout->rec_ct++; } /* all data was buffered, write now to file */ @@ -303,129 +332,147 @@ pdb_write_rec(pdbfile *fout, const gbuint8 flags, const gbuint8 category, const static void pdb_flush(pdbfile *file) { - pdbrec_t *rec; - gbfile *fout = file->file; - int len, offs; - - offs = 78; - file->index_offs = 0; - offs += (file->rec_ct * 8); - - offs += 2; - - if (file->appinfo && (file->appinfo_len > 0)) { - file->appinfo_offs = offs; - offs += file->appinfo_len; - } - else - file->appinfo_offs = 0; - - rec = file->rec_list; - while (rec) { /* prepare data records */ - rec->offs = offs; - offs += rec->size; - rec = rec->next; - } - - len = strlen(file->name); - gbfwrite(file->name, 1, len, fout); - while (len++ < PDB_DBNAMELEN) gbfputc(0, fout); - - gbfputuint16(file->attr, fout); - gbfputuint16(file->version, fout); - gbfputuint32(file->ctime, fout); - gbfputuint32(file->mtime, fout); - gbfputuint32(file->btime, fout); - gbfputuint32(file->revision, fout); - gbfputuint32(file->appinfo_offs, fout); - gbfputuint32(file->index_offs, fout); - gbfputuint32(file->type, fout); - gbfputuint32(file->creator, fout); - gbfputuint32(file->uid, fout); - - gbfputuint32(0, fout); /* ? ID ? */ - gbfputuint16(file->rec_ct, fout); - - for (rec = file->rec_list; rec; rec = rec->next) { - gbuint32 attr; - - gbfputint32(rec->offs, fout); - attr = (rec->category & 0x0f) | (rec->flags & 0xf0); - gbfputint32((rec->id & 0x0ffffff) | (attr << 24), fout); - } - gbfputint16(0, fout); - - if (file->appinfo && (file->appinfo_len > 0)) { - gbfwrite(file->appinfo, 1, file->appinfo_len, fout); - } - - for (rec = file->rec_list; rec; rec = rec->next) { - if (rec->size > 0) - gbfwrite(rec->data, 1, rec->size, fout); - } + pdbrec_t *rec; + gbfile *fout = file->file; + int len, offs; + + offs = 78; + file->index_offs = 0; + offs += (file->rec_ct * 8); + + offs += 2; + + if (file->appinfo && (file->appinfo_len > 0)) { + file->appinfo_offs = offs; + offs += file->appinfo_len; + } else { + file->appinfo_offs = 0; + } + + rec = file->rec_list; + while (rec) { /* prepare data records */ + rec->offs = offs; + offs += rec->size; + rec = rec->next; + } + + len = strlen(file->name); + gbfwrite(file->name, 1, len, fout); + while (len++ < PDB_DBNAMELEN) { + gbfputc(0, fout); + } + + gbfputuint16(file->attr, fout); + gbfputuint16(file->version, fout); + gbfputuint32(file->ctime, fout); + gbfputuint32(file->mtime, fout); + gbfputuint32(file->btime, fout); + gbfputuint32(file->revision, fout); + gbfputuint32(file->appinfo_offs, fout); + gbfputuint32(file->index_offs, fout); + gbfputuint32(file->type, fout); + gbfputuint32(file->creator, fout); + gbfputuint32(file->uid, fout); + + gbfputuint32(0, fout); /* ? ID ? */ + gbfputuint16(file->rec_ct, fout); + + for (rec = file->rec_list; rec; rec = rec->next) { + gbuint32 attr; + + gbfputint32(rec->offs, fout); + attr = (rec->category & 0x0f) | (rec->flags & 0xf0); + gbfputint32((rec->id & 0x0ffffff) | (attr << 24), fout); + } + gbfputint16(0, fout); + + if (file->appinfo && (file->appinfo_len > 0)) { + gbfwrite(file->appinfo, 1, file->appinfo_len, fout); + } + + for (rec = file->rec_list; rec; rec = rec->next) { + if (rec->size > 0) { + gbfwrite(rec->data, 1, rec->size, fout); + } + } } void pdb_close(pdbfile *file) { - pdbrec_t *rec; - - if (! file) return; - - if (file->mode & 2) { + pdbrec_t *rec; + + if (! file) { + return; + } + + if (file->mode & 2) { #if 0 - /* this can be done later */ - if (gpsbabel_time == 0) { /* !!! We are in testo !!! */ - file->ctime = 0; /* (now we also can do a bincompare) */ - file->mtime = 0; - file->btime = 0; - } + /* this can be done later */ + if (gpsbabel_time == 0) { /* !!! We are in testo !!! */ + file->ctime = 0; /* (now we also can do a bincompare) */ + file->mtime = 0; + file->btime = 0; + } #endif - pdb_flush(file); - } - - gbfclose(file->file); - - if ((file->mode & 1) && file->appinfo) xfree(file->appinfo); - - rec = file->rec_list; - while (rec) { - pdbrec_t *tmp = rec; - rec = rec->next; - - if (tmp->data) xfree(tmp->data); - xfree(tmp); - } - xfree(file); + pdb_flush(file); + } + + gbfclose(file->file); + + if ((file->mode & 1) && file->appinfo) { + xfree(file->appinfo); + } + + rec = file->rec_list; + while (rec) { + pdbrec_t *tmp = rec; + rec = rec->next; + + if (tmp->data) { + xfree(tmp->data); + } + xfree(tmp); + } + xfree(file); } int pdb_eof(pdbfile *fin) { - return (fin->rec_curr) ? 0 : 1; + return (fin->rec_curr) ? 0 : 1; } int pdb_read_rec(pdbfile *fin, gbuint8 *flags, gbuint8 *category, gbuint32 *rec_id, void **data) { - if (pdb_eof(fin)) return -1; - else { - pdbrec_t *rec = fin->rec_curr; - fin->rec_curr = rec->next; - - if (data) *data = rec->data; - if (flags) *flags = rec->flags; - if (category) *category = rec->category; - if (rec_id) *rec_id = rec->id; - - return rec->size; - } + if (pdb_eof(fin)) { + return -1; + } else { + pdbrec_t *rec = fin->rec_curr; + fin->rec_curr = rec->next; + + if (data) { + *data = rec->data; + } + if (flags) { + *flags = rec->flags; + } + if (category) { + *category = rec->category; + } + if (rec_id) { + *rec_id = rec->id; + } + + return rec->size; + } } void pdb_rewind(pdbfile *fin) { - fin->rec_curr = fin->rec_list; + fin->rec_curr = fin->rec_list; } #endif diff --git a/gpsbabel/pdbfile.h b/gpsbabel/pdbfile.h index b1c652f04..b93159479 100644 --- a/gpsbabel/pdbfile.h +++ b/gpsbabel/pdbfile.h @@ -4,7 +4,7 @@ Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org Written after study the Coldsync project - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -39,35 +39,35 @@ #define EPOCH_1904 2082844800L typedef struct pdbrec_s { - gbuint32 offs; - gbuint32 size; - gbuint32 id; - gbuint8 category; - gbuint8 flags; - char *data; - struct pdbrec_s *next; + gbuint32 offs; + gbuint32 size; + gbuint32 id; + gbuint8 category; + gbuint8 flags; + char *data; + struct pdbrec_s *next; } pdbrec_t; typedef struct { - gbfile *file; - char mode; /* file-mode: 1 = read / 2 = write */ - char name[PDB_DBNAMELEN + 1]; /* database name */ - gbuint16 attr; /* attributes */ - gbuint16 version; /* version */ - time_t ctime; /* creation time */ - time_t mtime; /* modification time */ - time_t btime; /* backup time */ - gbuint32 revision; - gbuint32 appinfo_offs; /* offset to application info */ - gbuint32 index_offs; /* offset to sort-index info */ - gbuint32 creator; - gbuint32 type; - gbuint32 uid; - gbuint16 rec_ct; - struct pdbrec_s *rec_list; - struct pdbrec_s *rec_curr; - void *appinfo; - int appinfo_len; + gbfile *file; + char mode; /* file-mode: 1 = read / 2 = write */ + char name[PDB_DBNAMELEN + 1]; /* database name */ + gbuint16 attr; /* attributes */ + gbuint16 version; /* version */ + time_t ctime; /* creation time */ + time_t mtime; /* modification time */ + time_t btime; /* backup time */ + gbuint32 revision; + gbuint32 appinfo_offs; /* offset to application info */ + gbuint32 index_offs; /* offset to sort-index info */ + gbuint32 creator; + gbuint32 type; + gbuint32 uid; + gbuint16 rec_ct; + struct pdbrec_s *rec_list; + struct pdbrec_s *rec_curr; + void *appinfo; + int appinfo_len; } pdbfile; diff --git a/gpsbabel/pocketfms_bc.c b/gpsbabel/pocketfms_bc.c index 588b83dc8..64cb34f22 100755 --- a/gpsbabel/pocketfms_bc.c +++ b/gpsbabel/pocketfms_bc.c @@ -26,29 +26,29 @@ static char header_id[] = "BRC"; typedef struct breadcrumb { - // header - char id[4]; // 0x42 0x52 0x43 0x00 <=> "BRC" - gbuint16 version; // 0x0100 - gbuint16 reserve1; // 0x0000 - // data - float latitude; - float longitude; - float altitude; // meter - float speed; // m/s - float course; // degrees - float magvar; // degrees - float separation; // meter - float ehpe; // estimated horizontal position error - float evpe; // estimated vertical position error - float espe; // estimated speed position error - gbuint16 fix; // 1..none, 2..2D, 3..3D, 4..dgps, 5pps - gbuint16 year; // 1999..2999 - gbuint16 month; // 1..12 - gbuint16 day; // 0..31 - gbuint16 hour; // 0.23 - gbuint16 minute; // 0..59 - gbuint16 second; // 0..59 - gbuint16 reserve2; // 0x0000 + // header + char id[4]; // 0x42 0x52 0x43 0x00 <=> "BRC" + gbuint16 version; // 0x0100 + gbuint16 reserve1; // 0x0000 + // data + float latitude; + float longitude; + float altitude; // meter + float speed; // m/s + float course; // degrees + float magvar; // degrees + float separation; // meter + float ehpe; // estimated horizontal position error + float evpe; // estimated vertical position error + float espe; // estimated speed position error + gbuint16 fix; // 1..none, 2..2D, 3..3D, 4..dgps, 5pps + gbuint16 year; // 1999..2999 + gbuint16 month; // 1..12 + gbuint16 day; // 0..31 + gbuint16 hour; // 0.23 + gbuint16 minute; // 0..59 + gbuint16 second; // 0..59 + gbuint16 reserve2; // 0x0000 } BREADCRUMB; static gbfile *file_in, *file_out; @@ -56,67 +56,68 @@ static gbfile *file_in, *file_out; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void read_tracks(void) { - struct breadcrumb bc; - route_head *trk_head = route_head_alloc(); - trk_head->rte_num = 1; - trk_head->rte_name = xstrdup("PocketFMS"); - trk_head->rte_desc = xstrdup("Breadcrumb"); - trk_head->rte_url = xstrdup("www.pocketfms.com"); - track_add_head(trk_head); - - while (1 == gbfread(&bc, sizeof (bc), 1, file_in)) { - struct tm tm; - waypoint *wpt; - - if (strcmp (bc.id, header_id) != 0) - fatal(MYNAME ": invalid breadcrumb header in input file.\n"); - - memset(&tm, 0, sizeof (tm)); - tm.tm_year = le_readu16(&bc.year)-1900; - tm.tm_mon = le_readu16(&bc.month)-1; - tm.tm_mday = le_readu16(&bc.day); - tm.tm_hour = le_readu16(&bc.hour); - tm.tm_min = le_readu16(&bc.minute); - tm.tm_sec = le_readu16(&bc.second); - - wpt = waypt_new(); - wpt->latitude = le_read_float(&bc.latitude); - wpt->longitude = le_read_float(&bc.longitude); - wpt->altitude = FEET_TO_METERS(le_read_float(&bc.altitude)); - wpt->creation_time = mkgmtime(&tm); - wpt->hdop = le_read_float(&bc.ehpe); - wpt->vdop = le_read_float(&bc.evpe); - wpt->pdop = le_read_float(&bc.espe); - wpt->course = le_read_float(&bc.course); - wpt->speed = le_read_float(&bc.speed); - wpt->fix = le_readu16(&bc.fix) - 1; - - track_add_wpt(trk_head, wpt); - } + struct breadcrumb bc; + route_head *trk_head = route_head_alloc(); + trk_head->rte_num = 1; + trk_head->rte_name = xstrdup("PocketFMS"); + trk_head->rte_desc = xstrdup("Breadcrumb"); + trk_head->rte_url = xstrdup("www.pocketfms.com"); + track_add_head(trk_head); + + while (1 == gbfread(&bc, sizeof(bc), 1, file_in)) { + struct tm tm; + waypoint *wpt; + + if (strcmp(bc.id, header_id) != 0) { + fatal(MYNAME ": invalid breadcrumb header in input file.\n"); + } + + memset(&tm, 0, sizeof(tm)); + tm.tm_year = le_readu16(&bc.year)-1900; + tm.tm_mon = le_readu16(&bc.month)-1; + tm.tm_mday = le_readu16(&bc.day); + tm.tm_hour = le_readu16(&bc.hour); + tm.tm_min = le_readu16(&bc.minute); + tm.tm_sec = le_readu16(&bc.second); + + wpt = waypt_new(); + wpt->latitude = le_read_float(&bc.latitude); + wpt->longitude = le_read_float(&bc.longitude); + wpt->altitude = FEET_TO_METERS(le_read_float(&bc.altitude)); + wpt->creation_time = mkgmtime(&tm); + wpt->hdop = le_read_float(&bc.ehpe); + wpt->vdop = le_read_float(&bc.evpe); + wpt->pdop = le_read_float(&bc.espe); + wpt->course = le_read_float(&bc.course); + wpt->speed = le_read_float(&bc.speed); + wpt->fix = le_readu16(&bc.fix) - 1; + + track_add_wpt(trk_head, wpt); + } } static void @@ -127,64 +128,64 @@ route_head_noop(const route_head *wp) static void pocketfms_waypt_disp(const waypoint *wpt) { - struct breadcrumb bc; - struct tm *tm; - - memset (&bc, 0, sizeof (bc)); - tm = localtime(&wpt->creation_time); - if (wpt->creation_time) { - tm = gmtime(&wpt->creation_time); - } - - strcpy (bc.id, header_id); - le_write16(&bc.version, 1); - le_write_float(&bc.latitude, wpt->latitude); - le_write_float(&bc.longitude, wpt->longitude); - le_write_float(&bc.altitude, METERS_TO_FEET(wpt->altitude)); - if (tm) { - le_write16(&bc.year, tm->tm_year + 1900); - le_write16(&bc.month, tm->tm_mon + 1); - le_write16(&bc.day, tm->tm_mday); - le_write16(&bc.hour, tm->tm_hour); - le_write16(&bc.minute, tm->tm_min); - le_write16(&bc.second, tm->tm_sec); - } - le_write_float(&bc.ehpe, wpt->hdop); - le_write_float(&bc.evpe, wpt->vdop); - le_write_float(&bc.espe, wpt->pdop); - le_write_float(&bc.course, wpt->course); - le_write_float(&bc.speed, wpt->speed); - le_write16(&bc.fix, wpt->fix+1); - - gbfwrite(&bc, sizeof (bc), 1, file_out); + struct breadcrumb bc; + struct tm *tm; + + memset(&bc, 0, sizeof(bc)); + tm = localtime(&wpt->creation_time); + if (wpt->creation_time) { + tm = gmtime(&wpt->creation_time); + } + + strcpy(bc.id, header_id); + le_write16(&bc.version, 1); + le_write_float(&bc.latitude, wpt->latitude); + le_write_float(&bc.longitude, wpt->longitude); + le_write_float(&bc.altitude, METERS_TO_FEET(wpt->altitude)); + if (tm) { + le_write16(&bc.year, tm->tm_year + 1900); + le_write16(&bc.month, tm->tm_mon + 1); + le_write16(&bc.day, tm->tm_mday); + le_write16(&bc.hour, tm->tm_hour); + le_write16(&bc.minute, tm->tm_min); + le_write16(&bc.second, tm->tm_sec); + } + le_write_float(&bc.ehpe, wpt->hdop); + le_write_float(&bc.evpe, wpt->vdop); + le_write_float(&bc.espe, wpt->pdop); + le_write_float(&bc.course, wpt->course); + le_write_float(&bc.speed, wpt->speed); + le_write16(&bc.fix, wpt->fix+1); + + gbfwrite(&bc, sizeof(bc), 1, file_out); } static void data_read(void) { - read_tracks(); + read_tracks(); } static void data_write(void) { - track_disp_all(route_head_noop, route_head_noop, pocketfms_waypt_disp); + track_disp_all(route_head_noop, route_head_noop, pocketfms_waypt_disp); } ff_vecs_t pocketfms_bc_vecs = { - ff_type_file, - { - ff_cap_none, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_none, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/pocketfms_fp.c b/gpsbabel/pocketfms_fp.c index f67173686..97dafd003 100755 --- a/gpsbabel/pocketfms_fp.c +++ b/gpsbabel/pocketfms_fp.c @@ -33,158 +33,164 @@ static xg_callback wpt_s, wpt_from_lat, wpt_from_lon, wpt_from_name, wpt_from_el static xg_callback wpt_e, wpt_to_lat, wpt_to_lon, wpt_to_name, wpt_to_elev, wpt_altitude; static xg_tag_mapping gl_map[] = { - { wpt_s, cb_start, "/PocketFMSFlightplan/LIB" }, - { wpt_from_lat, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Latitude" }, - { wpt_from_lon, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Longitude" }, - { wpt_from_elev, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Elevation" }, - { wpt_from_name, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/FriendlyShortname" }, - { wpt_to_lat, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Latitude" }, - { wpt_to_lon, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Longitude" }, - { wpt_to_name, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/FriendlyShortname" }, - { wpt_to_elev, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Elevation" }, - { wpt_altitude, cb_start, "/PocketFMSFlightplan/LIB/PlannedAltitude" }, - { wpt_e, cb_end, "/PocketFMSFlightplan/LIB" }, - { NULL, 0, NULL} + { wpt_s, cb_start, "/PocketFMSFlightplan/LIB" }, + { wpt_from_lat, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Latitude" }, + { wpt_from_lon, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Longitude" }, + { wpt_from_elev, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/Elevation" }, + { wpt_from_name, cb_cdata, "/PocketFMSFlightplan/LIB/FromPoint/FriendlyShortname" }, + { wpt_to_lat, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Latitude" }, + { wpt_to_lon, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Longitude" }, + { wpt_to_name, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/FriendlyShortname" }, + { wpt_to_elev, cb_cdata, "/PocketFMSFlightplan/LIB/ToPoint/Elevation" }, + { wpt_altitude, cb_start, "/PocketFMSFlightplan/LIB/PlannedAltitude" }, + { wpt_e, cb_end, "/PocketFMSFlightplan/LIB" }, + { NULL, 0, NULL} }; static void rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void data_read(void) { - xml_read(); + xml_read(); } static void rd_deinit(void) { - if (route != NULL) - { - waypoint *head = (waypoint *) QUEUE_FIRST(&route->waypoint_list); - waypoint *tail = (waypoint *) QUEUE_LAST(&route->waypoint_list); - if (head != NULL) - route->rte_name = xstrdup (head->shortname); - route->rte_name = xstrappend(route->rte_name, " - "); - if (tail != NULL) - { - route->rte_name = xstrappend(route->rte_name, tail->shortname); - tail->altitude = dest_altitude; - } - } - xml_deinit(); + if (route != NULL) { + waypoint *head = (waypoint *) QUEUE_FIRST(&route->waypoint_list); + waypoint *tail = (waypoint *) QUEUE_LAST(&route->waypoint_list); + if (head != NULL) { + route->rte_name = xstrdup(head->shortname); + } + route->rte_name = xstrappend(route->rte_name, " - "); + if (tail != NULL) { + route->rte_name = xstrappend(route->rte_name, tail->shortname); + tail->altitude = dest_altitude; + } + } + xml_deinit(); } static void wr_init(const char *fname) { - fatal("Writing file of type %s is not supported\n", MYNAME); + fatal("Writing file of type %s is not supported\n", MYNAME); } void wpt_s(const char *args, const char **unused) { - if (isFirst == 1) { - wpt_from = waypt_new(); - route = route_head_alloc(); - route->rte_desc=xstrdup("PocketFMS flightplan"); - route_add_head(route); - } - wpt_to = waypt_new(); + if (isFirst == 1) { + wpt_from = waypt_new(); + route = route_head_alloc(); + route->rte_desc=xstrdup("PocketFMS flightplan"); + route_add_head(route); + } + wpt_to = waypt_new(); } void wpt_e(const char *args, const char **unused) { - if (isFirst == 1) { - route_add_wpt(route, wpt_from); - if (doing_wpts) - waypt_add(waypt_dupe(wpt_from)); - wpt_from = NULL; - isFirst = 0; - } - route_add_wpt(route, wpt_to); - if (doing_wpts) - waypt_add(waypt_dupe(wpt_to)); - wpt_to = NULL; + if (isFirst == 1) { + route_add_wpt(route, wpt_from); + if (doing_wpts) { + waypt_add(waypt_dupe(wpt_from)); + } + wpt_from = NULL; + isFirst = 0; + } + route_add_wpt(route, wpt_to); + if (doing_wpts) { + waypt_add(waypt_dupe(wpt_to)); + } + wpt_to = NULL; } void wpt_from_lat(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->latitude = atof(args); + if (wpt_from != NULL) { + wpt_from->latitude = atof(args); + } } void wpt_from_lon(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->longitude = atof(args); + if (wpt_from != NULL) { + wpt_from->longitude = atof(args); + } } void wpt_from_name(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->shortname = xstrappend(wpt_from->shortname, args); + if (wpt_from != NULL) { + wpt_from->shortname = xstrappend(wpt_from->shortname, args); + } } void wpt_from_elev(const char *args, const char **unused) { - if (wpt_from != NULL) - wpt_from->altitude = FEET_TO_METERS(atof(args)); + if (wpt_from != NULL) { + wpt_from->altitude = FEET_TO_METERS(atof(args)); + } } void wpt_to_lat(const char *args, const char **unused) { - wpt_to->latitude = atof(args); + wpt_to->latitude = atof(args); } void wpt_to_lon(const char *args, const char **unused) { - wpt_to->longitude = atof(args); + wpt_to->longitude = atof(args); } void wpt_to_name(const char *args, const char **unused) { - wpt_to->shortname = xstrappend(wpt_to->shortname, args); + wpt_to->shortname = xstrappend(wpt_to->shortname, args); } void wpt_to_elev(const char *args, const char **unused) { - dest_altitude = FEET_TO_METERS(atof(args)); + dest_altitude = FEET_TO_METERS(atof(args)); } void wpt_altitude(const char *args, const char **attrv) { - int isFeet = 0; - const char **avp = &attrv[0]; - while (*avp) { - if (0 == strcmp(avp[0], "Value")) { - wpt_to->altitude = atof(avp[1]); - } - if (0 == strcmp(avp[0], "Unit")) { - isFeet = strcmp (avp[1], "ft") == 0 ? 1 : 0; - } - avp += 2; - } - if (isFeet) - wpt_to->altitude = FEET_TO_METERS(wpt_to->altitude); + int isFeet = 0; + const char **avp = &attrv[0]; + while (*avp) { + if (0 == strcmp(avp[0], "Value")) { + wpt_to->altitude = atof(avp[1]); + } + if (0 == strcmp(avp[0], "Unit")) { + isFeet = strcmp(avp[1], "ft") == 0 ? 1 : 0; + } + avp += 2; + } + if (isFeet) { + wpt_to->altitude = FEET_TO_METERS(wpt_to->altitude); + } } ff_vecs_t pocketfms_fp_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/pocketfms_wp.c b/gpsbabel/pocketfms_wp.c index ec05c5220..b5428bc98 100755 --- a/gpsbabel/pocketfms_wp.c +++ b/gpsbabel/pocketfms_wp.c @@ -28,102 +28,99 @@ static gbfile *file_in, *file_out; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "r", MYNAME); + file_in = gbfopen_le(fname, "r", MYNAME); } double wppos_to_dec(char *value) { - if (strstr(value, "°") == NULL) - return atof(value); - else - { - int degrees, minutes; - float seconds; - int sign = 1; - - if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+') - { - value = &value[1]; - } - else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-') - { - value = &value[1]; - sign = -1; - } - - sscanf(value, "%d°%d'%f\"", °rees, &minutes, &seconds); - return sign * (degrees + ((float)minutes / 60) + (seconds / 3600)); - } + if (strstr(value, "°") == NULL) { + return atof(value); + } else { + int degrees, minutes; + float seconds; + int sign = 1; + + if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+') { + value = &value[1]; + } else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-') { + value = &value[1]; + sign = -1; + } + + sscanf(value, "%d°%d'%f\"", °rees, &minutes, &seconds); + return sign * (degrees + ((float)minutes / 60) + (seconds / 3600)); + } } static void data_read(void) { - char *buff; - int linecount = 0; - while ((buff = gbfgetstr(file_in))) { - char *s; - waypoint *wpt; - rtrim(buff); - if (strlen(buff) == 0) - break; - linecount++; - wpt = waypt_new(); - s = buff; - s = csv_lineparse(s, "\\w", "", linecount); - wpt->shortname = xstrdup(s); - s = csv_lineparse(NULL, "\\w", "", linecount); - wpt->latitude = wppos_to_dec(s); - s = csv_lineparse(NULL, "\\w", "", linecount); - wpt->longitude = wppos_to_dec(s); - waypt_add(wpt); - } + char *buff; + int linecount = 0; + while ((buff = gbfgetstr(file_in))) { + char *s; + waypoint *wpt; + rtrim(buff); + if (strlen(buff) == 0) { + break; + } + linecount++; + wpt = waypt_new(); + s = buff; + s = csv_lineparse(s, "\\w", "", linecount); + wpt->shortname = xstrdup(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->latitude = wppos_to_dec(s); + s = csv_lineparse(NULL, "\\w", "", linecount); + wpt->longitude = wppos_to_dec(s); + waypt_add(wpt); + } } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "w", MYNAME); + file_out = gbfopen_le(fname, "w", MYNAME); } static void enigma_waypt_disp(const waypoint *wpt) { - gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude); + gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude); } static void data_write(void) { - waypt_disp_all(enigma_waypt_disp); + waypt_disp_all(enigma_waypt_disp); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } ff_vecs_t pocketfms_wp_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_none, /* tracks */ - ff_cap_none, /* routes */ - }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_none, /* tracks */ + ff_cap_none, /* routes */ + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/polygon.c b/gpsbabel/polygon.c index 5f2abce18..7ec0acbde 100644 --- a/gpsbabel/polygon.c +++ b/gpsbabel/polygon.c @@ -1,6 +1,6 @@ /* Inside/Outside polygon filter - + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -28,70 +28,70 @@ static char *polyfileopt = NULL; static char *exclopt = NULL; /* - * This test for insideness is essentially an odd/even test. The + * This test for insideness is essentially an odd/even test. The * traditional (simple) implementation of the odd/even test counts - * intersections along a test ray, and if it should happen to exactly hit - * a vertex of the polygon, it throws away the result and fires a different + * intersections along a test ray, and if it should happen to exactly hit + * a vertex of the polygon, it throws away the result and fires a different * test ray. Since we're potentially testing hundreds of test points against * a polygon with hundreds of sides, this seemed both wasteful and difficult * to coordinate, so instead I added extra state to try to figure out what we - * would have seen if we had just missed the vertex. The result is the + * would have seen if we had just missed the vertex. The result is the * hodgepodge of "limbo" states explained below. On the credit side of the * ledger, though, the tests for intersection are vastly simplified by always * having a horizontal test ray. - * - * The general structure of this filter is: we loop over the points in the + * + * The general structure of this filter is: we loop over the points in the * polygon. For each point, we update the state of each of the waypoints in * the test set. Thus, the state of every waypoint is indeterminate until - * the end of the outer loop, at which point the state of every waypoint + * the end of the outer loop, at which point the state of every waypoint * should theoretically be completely determined. - * - * The bits following this comment encode the current state of the test point - * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here - * for completeness. If it's not INSIDE, and it's not something else, it's + * + * The bits following this comment encode the current state of the test point + * as we go around the polygon. OUTSIDE clearly isn't a bit; it's just here + * for completeness. If it's not INSIDE, and it's not something else, it's * clearly OUTSIDE. - * - * INSIDE is self-explanatory. What it means is that the last time we were - * certain of our state, we were inside of the polygon. - * - * LIMBO encodes a bit more state information, to handle the case where our + * + * INSIDE is self-explanatory. What it means is that the last time we were + * certain of our state, we were inside of the polygon. + * + * LIMBO encodes a bit more state information, to handle the case where our * test ray (a horizontal line) has intersected one of the vertices of the - * polygon exactly. If the two lines that meet at that vertex are on + * polygon exactly. If the two lines that meet at that vertex are on * opposite sides of the test ray, it was an intersection. Otherwise, it just - * grazed a local minimum or maximum and so counted as either zero or two - * intersections - not a change in state. Horizontal lines encountered + * grazed a local minimum or maximum and so counted as either zero or two + * intersections - not a change in state. Horizontal lines encountered * while in limbo don't change the limbo state. All other lines do. * The rest of the bits talk about how we got into limbo, and thus what to do * when we get out of limbo. - * + * * LIMBO_UP means that the last line segment we saw going into limbo was * headed upward. When we see another non-horizontal line segment, whether * we flip the INSIDE bit or not depends on whether it also goes upward. If * it does, we flip the INSIDE bit. Otherwise, we just clear our limbo state * and go on as if nothing had happened. - * - * LIMBO_BEGIN means that the very first vertex in the polygon put us into a + * + * LIMBO_BEGIN means that the very first vertex in the polygon put us into a * limbo state. We won't be able to resolve that limbo state until we get to * the end of the cycle, and it can actually coexist with another more local - * limbo state. The next two bits talk about the beginning limbo state in + * limbo state. The next two bits talk about the beginning limbo state in * more detail. - * + * * BEGIN_UP means that the first non-horizontal line segment we encountered * while in a LIMBO_BEGIN state went upward. As with LIMBO_UP, this is used - * to determine the final disposition of the limbo state when we get back + * to determine the final disposition of the limbo state when we get back * around to the other end of the cycle. - * + * * BEGIN_HOR is fairly temporary. It says that we've encountered one or more * horizontal line segments at the beginning of the cycle, so we haven't yet * been able to resolve the state of BEGIN_UP. It's a way of propagating the * "firstness" forward until we can make a decision, without propagating it * for every test point. - * - * UP is used to remember which way we were going in case we encounter a - * limbo state. - * - * -- RLP - */ + * + * UP is used to remember which way we were going in case we encounter a + * limbo state. + * + * -- RLP + */ #define OUTSIDE 0 #define INSIDE 1 @@ -103,262 +103,252 @@ static char *exclopt = NULL; #define UP 64 typedef struct { - unsigned short state; - unsigned short override; + unsigned short state; + unsigned short override; } extra_data; static arglist_t polygon_args[] = { - {"file", &polyfileopt, "File containing vertices of polygon", - NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"exclude", &exclopt, "Exclude points inside the polygon", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "file", &polyfileopt, "File containing vertices of polygon", + NULL, ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points inside the polygon", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -static void polytest ( double lat1, double lon1, - double lat2, double lon2, - double wlat, double wlon, - unsigned short *state, int first, int last ) { - - if ( lat1 == wlat ) { - if ( lat2 < wlat ) { - /* going down */ - if (*state & LIMBO) { - if ( *state & LIMBO_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO &~LIMBO_UP; - } - else if (*state & LIMBO_BEGIN) { - if ( *state & BEGIN_HOR ) { - *state = *state & ~BEGIN_HOR; - } - else if ( last ) { - if ( *state & BEGIN_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - } - else if ( first && (lon1 > wlon)) { - *state |= LIMBO_BEGIN; - } - } - else if ( lat2 == wlat ) { - if ( first & (lon1 > wlon || lon2 > wlon)) { - *state |= LIMBO_BEGIN | BEGIN_HOR; - } - else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { - if ( (!!(*state & LIMBO_UP)) != (!!(*state & BEGIN_UP))) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO & ~LIMBO_UP & - ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( *state & LIMBO ) { - /* do nothing */ - } - else { - if ( lon1 <= wlon && lon2 > wlon ) { - if ( *state & UP ) { - *state &= ~UP; - *state |= LIMBO_UP; - } - *state = *state | LIMBO; - } - } - } - else { - /* going up */ - if (*state & LIMBO) { - if ( !(*state & LIMBO_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO & ~LIMBO_UP; - } - else if (*state & LIMBO_BEGIN) { - if ( *state & BEGIN_HOR ) { - *state &= ~BEGIN_HOR; - *state |= BEGIN_UP; - } - else if ( last ) { - if ( !(*state & BEGIN_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - } - else if ( first && (lon1 > wlon)) { - *state |= LIMBO_BEGIN | BEGIN_UP; - } - } - *state = *state & ~UP; - } - else if ( lat2 == wlat ) { - if ( lat1 < wlat ) { - if ( last ) { - if ( *state & BEGIN_UP ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( lon2 > wlon ) { - *state |= LIMBO; - } - } - /* no case for lat1==wlat; that's above */ - else { - if ( last ) { - if ( !(*state & BEGIN_UP) ) { - *state = *state ^ INSIDE; - } - *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; - } - else if ( lon2 > wlon ) { - *state |= LIMBO | LIMBO_UP; - } - else { - *state |= UP; - } - } - } - else { - if ( (lat1 > wlat && lat2 < wlat) || - (lat1 < wlat && lat2 > wlat)) { - /* we only care if the lines might intersect */ - if ( lon1 > wlon && lon2 > wlon ) { - *state = *state ^ INSIDE; - } - else if (!(lon1 <= wlon && lon2 <= wlon)) { - /* we're inside the bbox of a diagonal line. math time. */ - double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); - if ( loni > wlon ) { - *state = *state ^ INSIDE; - } - } - } - } +static void polytest(double lat1, double lon1, + double lat2, double lon2, + double wlat, double wlon, + unsigned short *state, int first, int last) +{ + + if (lat1 == wlat) { + if (lat2 < wlat) { + /* going down */ + if (*state & LIMBO) { + if (*state & LIMBO_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO &~LIMBO_UP; + } else if (*state & LIMBO_BEGIN) { + if (*state & BEGIN_HOR) { + *state = *state & ~BEGIN_HOR; + } else if (last) { + if (*state & BEGIN_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } else if (first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN; + } + } else if (lat2 == wlat) { + if (first & (lon1 > wlon || lon2 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_HOR; + } else if (last && (*state & LIMBO_BEGIN) && (*state & LIMBO)) { + if ((!!(*state & LIMBO_UP)) != (!!(*state & BEGIN_UP))) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP & + ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (*state & LIMBO) { + /* do nothing */ + } else { + if (lon1 <= wlon && lon2 > wlon) { + if (*state & UP) { + *state &= ~UP; + *state |= LIMBO_UP; + } + *state = *state | LIMBO; + } + } + } else { + /* going up */ + if (*state & LIMBO) { + if (!(*state & LIMBO_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO & ~LIMBO_UP; + } else if (*state & LIMBO_BEGIN) { + if (*state & BEGIN_HOR) { + *state &= ~BEGIN_HOR; + *state |= BEGIN_UP; + } else if (last) { + if (!(*state & BEGIN_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } + } else if (first && (lon1 > wlon)) { + *state |= LIMBO_BEGIN | BEGIN_UP; + } + } + *state = *state & ~UP; + } else if (lat2 == wlat) { + if (lat1 < wlat) { + if (last) { + if (*state & BEGIN_UP) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (lon2 > wlon) { + *state |= LIMBO; + } + } + /* no case for lat1==wlat; that's above */ + else { + if (last) { + if (!(*state & BEGIN_UP)) { + *state = *state ^ INSIDE; + } + *state = *state & ~LIMBO_BEGIN & ~BEGIN_UP; + } else if (lon2 > wlon) { + *state |= LIMBO | LIMBO_UP; + } else { + *state |= UP; + } + } + } else { + if ((lat1 > wlat && lat2 < wlat) || + (lat1 < wlat && lat2 > wlat)) { + /* we only care if the lines might intersect */ + if (lon1 > wlon && lon2 > wlon) { + *state = *state ^ INSIDE; + } else if (!(lon1 <= wlon && lon2 <= wlon)) { + /* we're inside the bbox of a diagonal line. math time. */ + double loni = lon1+(lon2-lon1)/(lat2-lat1)*(wlat-lat1); + if (loni > wlon) { + *state = *state ^ INSIDE; + } + } + } + } } #define BADVAL 999999 -void +void polygon_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - extra_data *ed; - double lat1, lon1, lat2, lon2; - double olat, olon; - int fileline = 0; - int first = 1; - int last = 0; - char *line; - gbfile *file_in; + queue * elem, * tmp; + waypoint * waypointp; + extra_data *ed; + double lat1, lon1, lat2, lon2; + double olat, olon; + int fileline = 0; + int first = 1; + int last = 0; + char *line; + gbfile *file_in; + + file_in = gbfopen(polyfileopt, "r", MYNAME); - file_in = gbfopen(polyfileopt, "r", MYNAME); - - olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; - while ((line = gbfgetstr(file_in))) { - char *pound = NULL; - int argsfound = 0; - - fileline++; - - pound = strchr( line, '#' ); - if ( pound ) *pound = '\0'; - - lat2 = lon2 = BADVAL; - argsfound = sscanf( line, "%lf %lf", &lat2, &lon2 ); - - if ( argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { - warning(MYNAME - ": Warning: Polygon file contains unusable vertex on line %d.\n", - fileline ); - } - else if ( lat1 != BADVAL && lon1 != BADVAL && - lat2 != BADVAL && lon2 != BADVAL ) { - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + olat = olon = lat1 = lon1 = lat2 = lon2 = BADVAL; + while ((line = gbfgetstr(file_in))) { + char *pound = NULL; + int argsfound = 0; - waypointp = (waypoint *)elem; - if ( waypointp->extra_data ) { - ed = (extra_data *) waypointp->extra_data; - } - else { - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->state = OUTSIDE; - ed->override = 0; - waypointp->extra_data = (extra_data *) ed; - } - if ( lat2 == waypointp->latitude && - lon2 == waypointp->longitude ) { - ed->override = 1; - } - if ( olat != BADVAL && olon != BADVAL && - olat == lat2 && olon == lon2 ) { - last = 1; - } - polytest( lat1, lon1, lat2, lon2, - waypointp->latitude, - waypointp->longitude, - &ed->state, first, last ); - first = 0; - last = 0; - } - } - if ( olat != BADVAL && olon != BADVAL && - olat == lat2 && olon == lon2 ) { - olat = BADVAL; - olon = BADVAL; - lat1 = BADVAL; - lon1 = BADVAL; - first = 1; - } - else if ( lat1 == BADVAL || lon1 == BADVAL ) { - olat = lat2; - olon = lon2; - lat1 = lat2; - lon1 = lon2; - } - else { - lat1 = lat2; - lon1 = lon2; - } - } - gbfclose(file_in); + fileline++; - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - ed = (extra_data *) wp->extra_data; - wp->extra_data = NULL; - if ( ed ) { - if ( ed->override ) ed->state = INSIDE; - if (((ed->state & INSIDE) == OUTSIDE ) == (exclopt == NULL)) { - waypt_del(wp); - waypt_free(wp); - } - xfree( ed ); - } - } + pound = strchr(line, '#'); + if (pound) { + *pound = '\0'; + } + + lat2 = lon2 = BADVAL; + argsfound = sscanf(line, "%lf %lf", &lat2, &lon2); + + if (argsfound != 2 && strspn(line, " \t\n") < strlen(line)) { + warning(MYNAME + ": Warning: Polygon file contains unusable vertex on line %d.\n", + fileline); + } else if (lat1 != BADVAL && lon1 != BADVAL && + lat2 != BADVAL && lon2 != BADVAL) { + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + + waypointp = (waypoint *)elem; + if (waypointp->extra_data) { + ed = (extra_data *) waypointp->extra_data; + } else { + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->state = OUTSIDE; + ed->override = 0; + waypointp->extra_data = (extra_data *) ed; + } + if (lat2 == waypointp->latitude && + lon2 == waypointp->longitude) { + ed->override = 1; + } + if (olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2) { + last = 1; + } + polytest(lat1, lon1, lat2, lon2, + waypointp->latitude, + waypointp->longitude, + &ed->state, first, last); + first = 0; + last = 0; + } + } + if (olat != BADVAL && olon != BADVAL && + olat == lat2 && olon == lon2) { + olat = BADVAL; + olon = BADVAL; + lat1 = BADVAL; + lon1 = BADVAL; + first = 1; + } else if (lat1 == BADVAL || lon1 == BADVAL) { + olat = lat2; + olon = lon2; + lat1 = lat2; + lon1 = lon2; + } else { + lat1 = lat2; + lon1 = lon2; + } + } + gbfclose(file_in); + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + ed = (extra_data *) wp->extra_data; + wp->extra_data = NULL; + if (ed) { + if (ed->override) { + ed->state = INSIDE; + } + if (((ed->state & INSIDE) == OUTSIDE) == (exclopt == NULL)) { + waypt_del(wp); + waypt_free(wp); + } + xfree(ed); + } + } } void -polygon_init(const char *args) { - /* do nothing */ +polygon_init(const char *args) +{ + /* do nothing */ } void -polygon_deinit(void) { - /* do nothing */ +polygon_deinit(void) +{ + /* do nothing */ } filter_vecs_t polygon_vecs = { - polygon_init, - polygon_process, - polygon_deinit, - NULL, - polygon_args + polygon_init, + polygon_process, + polygon_deinit, + NULL, + polygon_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/position.c b/gpsbabel/position.c index cc0527252..76503cc46 100644 --- a/gpsbabel/position.c +++ b/gpsbabel/position.c @@ -38,182 +38,195 @@ static char *purge_duplicates = NULL; static int check_time; typedef struct { - double distance; + double distance; } extra_data; static arglist_t position_args[] = { - {"distance", &distopt, "Maximum positional distance", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"all", &purge_duplicates, - "Suppress all points close to other points", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"time", &timeopt, "Maximum time in seconds beetween two points", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "distance", &distopt, "Maximum positional distance", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "all", &purge_duplicates, + "Suppress all points close to other points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "time", &timeopt, "Maximum time in seconds beetween two points", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static double gc_distance(double lat1, double lon1, double lat2, double lon2) { - return gcdist( - RAD(lat1), - RAD(lon1), - RAD(lat2), - RAD(lon2) - ); + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); } /* tear through a waypoint queue, processing points by distance */ -static void +static void position_runqueue(queue *q, int nelems, int qtype) { - queue * elem, * tmp; - waypoint ** comp; - int * qlist; - double dist, diff_time; - int i = 0, j, anyitem; - - comp = (waypoint **) xcalloc(nelems, sizeof(*comp)); - qlist = (int *) xcalloc(nelems, sizeof(*qlist)); - - QUEUE_FOR_EACH(q, elem, tmp) { - comp[i] = (waypoint *)elem; - qlist[i] = 0; - i++; - } - - for (i = 0 ; i < nelems ; i++) { - anyitem = 0; - - if (!qlist[i]) { - for (j = i + 1 ; j < nelems ; j++) { - if (!qlist[j]) { - dist = gc_distance(comp[j]->latitude, - comp[j]->longitude, - comp[i]->latitude, - comp[i]->longitude); - - /* convert radians to integer feet */ - dist = (int)(5280*radtomiles(dist)); - diff_time = fabs( waypt_time(comp[i]) - waypt_time(comp[j]) ); - - if (dist <= pos_dist) { - if(check_time && diff_time >= max_diff_time) - continue; - - qlist[j] = 1; - switch (qtype) { - case wptdata: - waypt_del(comp[j]); - waypt_free(comp[j]); - break; - case trkdata: - track_del_wpt(cur_rte, comp[j]); - break; - case rtedata: - route_del_wpt(cur_rte, comp[j]); - break; - default: - break; - } - anyitem = 1; - } - } - } - - if (anyitem && !!purge_duplicates) { - switch (qtype) { - case wptdata: - waypt_del(comp[i]); - break; - case trkdata: - track_del_wpt(cur_rte, comp[i]); - break; - case rtedata: - route_del_wpt(cur_rte, comp[i]); - break; - default: - break; - } - waypt_free(comp[i]); - } - } - } - - if (comp) - xfree(comp); - - if (qlist) - xfree(qlist); + queue * elem, * tmp; + waypoint ** comp; + int * qlist; + double dist, diff_time; + int i = 0, j, anyitem; + + comp = (waypoint **) xcalloc(nelems, sizeof(*comp)); + qlist = (int *) xcalloc(nelems, sizeof(*qlist)); + + QUEUE_FOR_EACH(q, elem, tmp) { + comp[i] = (waypoint *)elem; + qlist[i] = 0; + i++; + } + + for (i = 0 ; i < nelems ; i++) { + anyitem = 0; + + if (!qlist[i]) { + for (j = i + 1 ; j < nelems ; j++) { + if (!qlist[j]) { + dist = gc_distance(comp[j]->latitude, + comp[j]->longitude, + comp[i]->latitude, + comp[i]->longitude); + + /* convert radians to integer feet */ + dist = (int)(5280*radtomiles(dist)); + diff_time = fabs(waypt_time(comp[i]) - waypt_time(comp[j])); + + if (dist <= pos_dist) { + if (check_time && diff_time >= max_diff_time) { + continue; + } + + qlist[j] = 1; + switch (qtype) { + case wptdata: + waypt_del(comp[j]); + waypt_free(comp[j]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[j]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[j]); + break; + default: + break; + } + anyitem = 1; + } + } + } + + if (anyitem && !!purge_duplicates) { + switch (qtype) { + case wptdata: + waypt_del(comp[i]); + break; + case trkdata: + track_del_wpt(cur_rte, comp[i]); + break; + case rtedata: + route_del_wpt(cur_rte, comp[i]); + break; + default: + break; + } + waypt_free(comp[i]); + } + } + } + + if (comp) { + xfree(comp); + } + + if (qlist) { + xfree(qlist); + } } static void -position_process_route(const route_head * rh) { - int i = rh->rte_waypt_ct; +position_process_route(const route_head * rh) +{ + int i = rh->rte_waypt_ct; - if (i) { - cur_rte = (route_head *)rh; - position_runqueue((queue *)&rh->waypoint_list, i, rtedata); - cur_rte = NULL; - } + if (i) { + cur_rte = (route_head *)rh; + position_runqueue((queue *)&rh->waypoint_list, i, rtedata); + cur_rte = NULL; + } } -static void +static void position_noop_w(const waypoint *w) { } -static void +static void position_noop_t(const route_head *h) { } -void position_process(void) +void position_process(void) { - int i = waypt_count(); - - if (i) - position_runqueue(&waypt_head, i, wptdata); - - route_disp_all(position_process_route, position_noop_t, position_noop_w); - track_disp_all(position_process_route, position_noop_t, position_noop_w); + int i = waypt_count(); + + if (i) { + position_runqueue(&waypt_head, i, wptdata); + } + + route_disp_all(position_process_route, position_noop_t, position_noop_w); + track_disp_all(position_process_route, position_noop_t, position_noop_w); } void -position_init(const char *args) { - char *fm; - - pos_dist = 0; - max_diff_time = 0; - check_time = 0; - - if (distopt) { - pos_dist = strtod(distopt, &fm); - - if ((*fm == 'm') || (*fm == 'M')) { - /* distance is meters */ - pos_dist *= 3.2802; - } - } - - if (timeopt) { - check_time = 1; - max_diff_time = strtod(timeopt, &fm); - } +position_init(const char *args) +{ + char *fm; + + pos_dist = 0; + max_diff_time = 0; + check_time = 0; + + if (distopt) { + pos_dist = strtod(distopt, &fm); + + if ((*fm == 'm') || (*fm == 'M')) { + /* distance is meters */ + pos_dist *= 3.2802; + } + } + + if (timeopt) { + check_time = 1; + max_diff_time = strtod(timeopt, &fm); + } } void -position_deinit(void) { +position_deinit(void) +{ } filter_vecs_t position_vecs = { - position_init, - position_process, - position_deinit, - NULL, - position_args + position_init, + position_process, + position_deinit, + NULL, + position_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/psitrex.c b/gpsbabel/psitrex.c index 739fec4c9..9a6b64b4d 100755 --- a/gpsbabel/psitrex.c +++ b/gpsbabel/psitrex.c @@ -26,19 +26,19 @@ #include "garmin_tables.h" #include -#define MYNAME "PSITREX" +#define MYNAME "PSITREX" typedef enum { - ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */ - EOL, /* don't skip spaces and tabs to start; end on EOL */ - comma, /* skip spaces & tabs to start; ends on comma or EOL */ - whitespace, /* skip spaces & tabs to start; ends on white space or EOL */ - wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */ + ltrimEOL = 1 , /* skip spaces & tabs to start; ends on EOL */ + EOL, /* don't skip spaces and tabs to start; end on EOL */ + comma, /* skip spaces & tabs to start; ends on comma or EOL */ + whitespace, /* skip spaces & tabs to start; ends on white space or EOL */ + wscomma /* skip spaces & tabs to start; ends on white space, comma or EOL */ } psit_tokenSep_type; typedef struct psit_icon_mapping { - const int value; - const char *icon; + const int value; + const char *icon; } psit_icon_mapping_t; static gbfile *psit_file_in; @@ -56,223 +56,237 @@ char *snlen; static arglist_t psit_args[] = { -/* {"snlen", &snlen, "Length of generated shortnames", - NULL, ARGTYPE_INT, "1", NULL }, */ - ARG_TERMINATOR + /* {"snlen", &snlen, "Length of generated shortnames", + NULL, ARGTYPE_INT, "1", NULL }, */ + ARG_TERMINATOR }; /* Taken from PsiTrex 1.13 */ static const psit_icon_mapping_t psit_icon_value_table[] = { - { 0x00, "anchor" }, - { 0x06, "dollar" }, - { 0x07, "fish" }, - { 0x08, "fuel" }, - { 0x0a, "house" }, - { 0x0b, "knife" }, - { 0x0d, "mug" }, - { 0x0e, "skull" }, - { 0x12, "wpt_dot" }, - { 0x13, "wreck" }, - { 0x15, "mob" }, - { 0x0096, "boat_ramp" }, - { 0x0097, "camp" }, - { 0x0098, "restrooms" }, - { 0x0099, "showers" }, - { 0x009a, "drinking_wtr" }, - { 0x009b, "phone" }, - { 0x009c, "1st_aid" }, - { 0x009d, "info" }, - { 0x009e, "parking" }, - { 0x009f, "park" }, - { 0x00a0, "picnic" }, - { 0x00a1, "scenic" }, - { 0x00a2, "skiing" }, - { 0x00a3, "swimming" }, - { 0x00a4, "dam" }, - { 0x00a6, "danger" }, - { 0x00a9, "ball" }, - { 0x00aa, "car" }, - { 0x00ab, "deer" }, - { 0x00ac, "shpng_cart" }, - { 0x00ad, "lodging" }, - { 0x00ae, "mine" }, - { 0x00af, "trail_head" }, - { 0x00b0, "truck_stop" }, - { 0x00b2, "flag" }, - { 0x2005, "golf" }, - { 0x2006, "sml_cty" }, - { 0x2007, "med_cty" }, - { 0x2008, "lrg_cty" }, - { 0x200c, "amuse_pk" }, - { 0x200d, "bowling" }, - { 0x200e, "car_rental" }, - { 0x200f, "car_repair" }, - { 0x2010, "fastfood" }, - { 0x2011, "fitness" }, - { 0x2012, "movie" }, - { 0x2013, "museum" }, - { 0x2014, "pharmacy" }, - { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */ - { 0x2016, "post_ofc" }, - { 0x2017, "rv_park" }, - { 0x2018, "school" }, - { 0x2019, "stadium" }, - { 0x201a, "store" }, - { 0x201b, "zoo" }, - { 0x201c, "gas_plus" }, - { 0x201d, "faces" }, - { 0x2022, "weigh_sttn" }, - { 0x2023, "toll_booth" }, - { 0x2029, "bridge" }, - { 0x202a, "building" }, - { 0x202b, "cemetery" }, - { 0x202c, "church" }, - { 0x202e, "crossing" }, - { 0x2032, "oil_field" }, - { 0x2033, "tunnel" }, - { 0x2035, "forest" }, - { 0x2036, "summit" }, - { 0x203f, "geocache" }, - { 0x2040, "geocache_fnd" }, - { 0x4000, "airport" }, - { 0x4007, "tall_tower" }, - { 0x4008, "short_tower" }, - { 0x4009, "glider" }, - { 0x400a, "ultralight" }, - { 0x400b, "parachute" }, - { 0x4012, "seaplane" }, - { -1, NULL } + { 0x00, "anchor" }, + { 0x06, "dollar" }, + { 0x07, "fish" }, + { 0x08, "fuel" }, + { 0x0a, "house" }, + { 0x0b, "knife" }, + { 0x0d, "mug" }, + { 0x0e, "skull" }, + { 0x12, "wpt_dot" }, + { 0x13, "wreck" }, + { 0x15, "mob" }, + { 0x0096, "boat_ramp" }, + { 0x0097, "camp" }, + { 0x0098, "restrooms" }, + { 0x0099, "showers" }, + { 0x009a, "drinking_wtr" }, + { 0x009b, "phone" }, + { 0x009c, "1st_aid" }, + { 0x009d, "info" }, + { 0x009e, "parking" }, + { 0x009f, "park" }, + { 0x00a0, "picnic" }, + { 0x00a1, "scenic" }, + { 0x00a2, "skiing" }, + { 0x00a3, "swimming" }, + { 0x00a4, "dam" }, + { 0x00a6, "danger" }, + { 0x00a9, "ball" }, + { 0x00aa, "car" }, + { 0x00ab, "deer" }, + { 0x00ac, "shpng_cart" }, + { 0x00ad, "lodging" }, + { 0x00ae, "mine" }, + { 0x00af, "trail_head" }, + { 0x00b0, "truck_stop" }, + { 0x00b2, "flag" }, + { 0x2005, "golf" }, + { 0x2006, "sml_cty" }, + { 0x2007, "med_cty" }, + { 0x2008, "lrg_cty" }, + { 0x200c, "amuse_pk" }, + { 0x200d, "bowling" }, + { 0x200e, "car_rental" }, + { 0x200f, "car_repair" }, + { 0x2010, "fastfood" }, + { 0x2011, "fitness" }, + { 0x2012, "movie" }, + { 0x2013, "museum" }, + { 0x2014, "pharmacy" }, + { 0x2015, "pizza" }, /* how specific does this really need to be? C'mon! */ + { 0x2016, "post_ofc" }, + { 0x2017, "rv_park" }, + { 0x2018, "school" }, + { 0x2019, "stadium" }, + { 0x201a, "store" }, + { 0x201b, "zoo" }, + { 0x201c, "gas_plus" }, + { 0x201d, "faces" }, + { 0x2022, "weigh_sttn" }, + { 0x2023, "toll_booth" }, + { 0x2029, "bridge" }, + { 0x202a, "building" }, + { 0x202b, "cemetery" }, + { 0x202c, "church" }, + { 0x202e, "crossing" }, + { 0x2032, "oil_field" }, + { 0x2033, "tunnel" }, + { 0x2035, "forest" }, + { 0x2036, "summit" }, + { 0x203f, "geocache" }, + { 0x2040, "geocache_fnd" }, + { 0x4000, "airport" }, + { 0x4007, "tall_tower" }, + { 0x4008, "short_tower" }, + { 0x4009, "glider" }, + { 0x400a, "ultralight" }, + { 0x400b, "parachute" }, + { 0x4012, "seaplane" }, + { -1, NULL } }; static const char * psit_find_desc_from_icon_number(const int icon) { - const psit_icon_mapping_t *i; - - for (i = psit_icon_value_table; i->icon; i++) { - if (icon == i->value) { - return i->icon; - } - } - return ""; + const psit_icon_mapping_t *i; + + for (i = psit_icon_value_table; i->icon; i++) { + if (icon == i->value) { + return i->icon; + } + } + return ""; } static int psit_find_icon_number_from_desc(const char *desc) { - const psit_icon_mapping_t *i; - int def_icon = 18; - - if (!desc) { - return def_icon; - } - - for (i = psit_icon_value_table; i->icon; i++) { - if (case_ignore_strcmp(desc,i->icon) == 0) { - return i->value; - } - } - if (atoi(desc) > 0) return atoi(desc); - return def_icon; + const psit_icon_mapping_t *i; + int def_icon = 18; + + if (!desc) { + return def_icon; + } + + for (i = psit_icon_value_table; i->icon; i++) { + if (case_ignore_strcmp(desc,i->icon) == 0) { + return i->value; + } + } + if (atoi(desc) > 0) { + return atoi(desc); + } + return def_icon; } static void psit_rd_init(const char *fname) { - psit_file_in = gbfopen(fname, "r", MYNAME); + psit_file_in = gbfopen(fname, "r", MYNAME); } static void psit_rd_deinit(void) { - gbfclose(psit_file_in); + gbfclose(psit_file_in); } static void psit_wr_init(const char *fname) { - psit_file_out = gbfopen(fname, "w", MYNAME); + psit_file_out = gbfopen(fname, "w", MYNAME); } static void psit_wr_deinit(void) { - gbfclose(psit_file_out); + gbfclose(psit_file_out); } /* - * get characters until and including terminating NULL from psit_file_in + * get characters until and including terminating NULL from psit_file_in * and write into buf. */ static void psit_getToken(gbfile *psit_file, char *buf, size_t sz, psit_tokenSep_type delimType) { - int c = -1; - - *buf = 0; - - if (delimType != EOL) { - while ((c = gbfgetc(psit_file)) != EOF) { - if (!isspace(c)) break; - } - } - - if (gbfeof(psit_file)) return; - - if (delimType == EOL) { - c = gbfgetc(psit_file); - } - - if (c == '#') { - if (gbfgets(buf, sz, psit_file) == NULL) { - *buf = 0; - return; - } - /* use recursion to skip multiple comment lines or just to return the next token */ - psit_getToken(psit_file, buf, sz, delimType); - return; - } - - if ((delimType == EOL) || (delimType == ltrimEOL)) { - *buf = c; - buf++; - gbfgets(buf, sz-1, psit_file); - return; - } - - while (sz--) { - *buf++ = c; - if ((c = gbfgetc (psit_file)) == EOF) { - *buf = 0; - return; - } - if (((c == 0) || isspace(c)) && - ((delimType == whitespace) || (delimType == wscomma)) ) { - *buf = 0; - return; - } - if (((delimType == comma) || (delimType == wscomma)) && - (c == ',')) { - *buf = 0; - return; - } - } + int c = -1; + + *buf = 0; + + if (delimType != EOL) { + while ((c = gbfgetc(psit_file)) != EOF) { + if (!isspace(c)) { + break; + } + } + } + + if (gbfeof(psit_file)) { + return; + } + + if (delimType == EOL) { + c = gbfgetc(psit_file); + } + + if (c == '#') { + if (gbfgets(buf, sz, psit_file) == NULL) { + *buf = 0; + return; + } + /* use recursion to skip multiple comment lines or just to return the next token */ + psit_getToken(psit_file, buf, sz, delimType); + return; + } + + if ((delimType == EOL) || (delimType == ltrimEOL)) { + *buf = c; + buf++; + gbfgets(buf, sz-1, psit_file); + return; + } + + while (sz--) { + *buf++ = c; + if ((c = gbfgetc(psit_file)) == EOF) { + *buf = 0; + return; + } + if (((c == 0) || isspace(c)) && + ((delimType == whitespace) || (delimType == wscomma))) { + *buf = 0; + return; + } + if (((delimType == comma) || (delimType == wscomma)) && + (c == ',')) { + *buf = 0; + return; + } + } } /* - * test if a token is known - * + * test if a token is known + * */ static int psit_isKnownToken(char *buf) { - if (strcmp(buf, "Track:") == 0) return 0; - if (strcmp(buf, "Route:") == 0) return 0; - if (strcmp(buf, "Waypoint:") == 0) return 0; - if (strcmp(buf, "Map:") == 0) return 0; - return 1; + if (strcmp(buf, "Track:") == 0) { + return 0; + } + if (strcmp(buf, "Route:") == 0) { + return 0; + } + if (strcmp(buf, "Waypoint:") == 0) { + return 0; + } + if (strcmp(buf, "Map:") == 0) { + return 0; + } + return 1; } /* @@ -282,43 +296,42 @@ psit_isKnownToken(char *buf) static void psit_waypoint_r(gbfile *psit_file, waypoint **wpt) { - int garmin_icon_num; + int garmin_icon_num; - waypoint *thisWaypoint; + waypoint *thisWaypoint; - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); - thisWaypoint->latitude = atof(psit_current_token); + thisWaypoint->latitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } - /* the name */ - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - rtrim(psit_current_token); - thisWaypoint->shortname = xstrdup(psit_current_token); - thisWaypoint->description = xstrdup(""); + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - rtrim(psit_current_token); - /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ - /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ - garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); - waypt_add(thisWaypoint); + waypt_add(thisWaypoint); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } } /* @@ -328,43 +341,44 @@ psit_waypoint_r(gbfile *psit_file, waypoint **wpt) static void psit_waypoint_w(gbfile *psit_file, const waypoint *wpt) { - int icon; - const char *ident; - char *src = 0; /* BUGBUG Passed to mkshort */ - - gbfprintf(psit_file, "%11.6f,%11.6f,", - wpt->latitude, - wpt->longitude); - - if (wpt->altitude == unknown_alt) - gbfprintf(psit_file, "********,"); - else - gbfprintf(psit_file, "%8.2f,", - wpt->altitude); - - ident = global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, src) : - wpt->shortname; - - gbfprintf(psit_file, " %-6s, ", ident); - icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); - - if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { - icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); - } - - ident = psit_find_desc_from_icon_number(icon); - if (strlen(ident) == 0) - gbfprintf(psit_file, "%1d\n", icon); - else - gbfprintf(psit_file, "%s\n", ident); + int icon; + const char *ident; + char *src = 0; /* BUGBUG Passed to mkshort */ + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) { + gbfprintf(psit_file, "********,"); + } else + gbfprintf(psit_file, "%8.2f,", + wpt->altitude); + + ident = global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, src) : + wpt->shortname; + + gbfprintf(psit_file, " %-6s, ", ident); + icon = gt_find_icon_number_from_desc(wpt->icon_descr, PCX); + + if (get_cache_icon(wpt) && wpt->icon_descr && (strcmp(wpt->icon_descr, "Geocache Found") != 0)) { + icon = gt_find_icon_number_from_desc(get_cache_icon(wpt), PCX); + } + + ident = psit_find_desc_from_icon_number(icon); + if (strlen(ident) == 0) { + gbfprintf(psit_file, "%1d\n", icon); + } else { + gbfprintf(psit_file, "%s\n", ident); + } } static void psit_waypoint_w_wrapper(const waypoint *wpt) { - psit_waypoint_w(psit_file_out, wpt); + psit_waypoint_w(psit_file_out, wpt); } /* @@ -374,76 +388,77 @@ psit_waypoint_w_wrapper(const waypoint *wpt) static void psit_route_r(gbfile *psit_file, route_head **rte) { - char rtename[256]; - unsigned int rte_num; + char rtename[256]; + unsigned int rte_num; - int garmin_icon_num; + int garmin_icon_num; - route_head *rte_head; - unsigned int rte_count; + route_head *rte_head; + unsigned int rte_count; - waypoint *thisWaypoint; + waypoint *thisWaypoint; - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - if (strlen(psit_current_token) == 0) { - strcpy(rtename, "ROUTE"); - } - else { - strcpy(rtename, psit_current_token); - } + if (strlen(psit_current_token) == 0) { + strcpy(rtename, "ROUTE"); + } else { + strcpy(rtename, psit_current_token); + } - rtrim(rtename); + rtrim(rtename); - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(rtename); - route_add_head(rte_head); - *rte = rte_head; + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(rtename); + route_add_head(rte_head); + *rte = rte_head; - rte_num = 0; + rte_num = 0; - rte_count = 0; + rte_count = 0; - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - while (psit_isKnownToken(psit_current_token) != 0) { - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); - thisWaypoint->latitude = atof(psit_current_token); + thisWaypoint->latitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } - /* the name */ - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - rtrim(psit_current_token); - thisWaypoint->shortname = xstrdup(psit_current_token); - thisWaypoint->description = xstrdup(""); + /* the name */ + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + rtrim(psit_current_token); + thisWaypoint->shortname = xstrdup(psit_current_token); + thisWaypoint->description = xstrdup(""); - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - rtrim(psit_current_token); - /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ - /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ - garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); - thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + rtrim(psit_current_token); + /* since PsiTrex only deals with Garmins, let's use the "proper" Garmin icon name */ + /* convert the PsiTrex name to the number, which is the PCX one; from there to Garmin desc */ + garmin_icon_num = psit_find_icon_number_from_desc(psit_current_token); + thisWaypoint->icon_descr = gt_find_desc_from_icon_number(garmin_icon_num, PCX, NULL); - route_add_wpt(rte_head, thisWaypoint); + route_add_wpt(rte_head, thisWaypoint); - if (gbfeof(psit_file)) break; + if (gbfeof(psit_file)) { + break; + } - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } - else break; - } + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } else { + break; + } + } } /* @@ -453,55 +468,57 @@ psit_route_r(gbfile *psit_file, route_head **rte) static void psit_routehdr_w(gbfile *psit_file, const route_head *rte) { - char hdr[20]; - unsigned int rte_datapoints; - char *rname; - - waypoint *testwpt; - time_t uniqueValue = 0; - int allWptNameLengths; - - queue *elem, *tmp; - - /* total nodes (waypoints) this route */ - rte_datapoints = 0; - allWptNameLengths = 0; - - if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ - char *c; - - QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { - testwpt = (waypoint *)elem; - if (rte_datapoints == 0) { - uniqueValue = testwpt->creation_time; - } - rte_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* route name */ - if (!rte->rte_name) { - sprintf(hdr, "Route%04x", (unsigned) uniqueValue); - rname = xstrdup(hdr); - } - else - rname = xstrdup(rte->rte_name); - - /* check for psitrex comment sign; replace with '$' */ - while ((c = strchr(rname, '#'))) *c = '$'; - - gbfprintf(psit_file, "Route: %s\n", rname); - xfree(rname); - } + char hdr[20]; + unsigned int rte_datapoints; + char *rname; + + waypoint *testwpt; + time_t uniqueValue = 0; + int allWptNameLengths; + + queue *elem, *tmp; + + /* total nodes (waypoints) this route */ + rte_datapoints = 0; + allWptNameLengths = 0; + + if (rte->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid route - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&rte->waypoint_list, elem, tmp) { + testwpt = (waypoint *)elem; + if (rte_datapoints == 0) { + uniqueValue = testwpt->creation_time; + } + rte_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* route name */ + if (!rte->rte_name) { + sprintf(hdr, "Route%04x", (unsigned) uniqueValue); + rname = xstrdup(hdr); + } else { + rname = xstrdup(rte->rte_name); + } + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(rname, '#'))) { + *c = '$'; + } + + gbfprintf(psit_file, "Route: %s\n", rname); + xfree(rname); + } } static void psit_routehdr_w_wrapper(const route_head *rte) { - psit_routehdr_w(psit_file_out, rte); + psit_routehdr_w(psit_file_out, rte); } @@ -512,99 +529,99 @@ psit_routehdr_w_wrapper(const route_head *rte) static void psit_track_r(gbfile *psit_file, route_head **trk) { - char tbuf[100]; - char trkname[256]; - unsigned int trk_num; - - struct tm tmTime; - time_t dateTime = 0; - route_head *track_head = NULL; - unsigned int trk_count; - - waypoint *thisWaypoint; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); - if (strlen(psit_current_token) == 0) { - strcpy(trkname, "TRACK"); - } - else { - strcpy(trkname, psit_current_token); - } - - rtrim(trkname); - - trk_num = 0; - - trk_count = 0; - - track_head = NULL; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - - while (psit_isKnownToken(psit_current_token) != 0) { - if (strlen(psit_current_token) > 0) { - thisWaypoint = waypt_new(); - - thisWaypoint->latitude = atof(psit_current_token); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - thisWaypoint->longitude = atof(psit_current_token); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); - if (psit_current_token[0] == '*') { - thisWaypoint->altitude = unknown_alt; - } - else { - thisWaypoint->altitude = atof(psit_current_token); - } - - /* date portion of the date time DD/MM/YY */ - psit_getToken(psit_file, psit_current_token, - sizeof(psit_current_token), whitespace); - sscanf(psit_current_token, "%02d/%02d/%02d", - &(tmTime.tm_mday) , &(tmTime.tm_mon), - &(tmTime.tm_year)); - - /* years are less 1900 in the tm struct */ - tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100); - /* months are 0 to 11 in the tm struct */ - tmTime.tm_mon--; - /* time portion of the date time hh:mm:ss */ - psit_getToken(psit_file,psit_current_token, - sizeof(psit_current_token), wscomma); - sscanf(psit_current_token, "%02d:%02d:%02d", - &(tmTime.tm_hour) , &(tmTime.tm_min), - &(tmTime.tm_sec)); - - tmTime.tm_isdst = 0; - dateTime = mkgmtime(&tmTime); - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace); - - if ((strcmp(psit_current_token, "1") == 0) || (track_head == NULL)) { - track_head = route_head_alloc(); - /* Add a number to the track name. With Garmins, the "first" tracklog is usually ACTIVE LOG - the second is ACTIVE LOG001 and so on */ - if (trk_num > 0) { - sprintf(tbuf, "%s%03d", trkname, trk_num); - track_head->rte_name = xstrdup(tbuf); - } - else { - track_head->rte_name = xstrdup(trkname); - } - trk_num++; - track_add_head(track_head); - } - - thisWaypoint->creation_time = dateTime; - track_add_wpt(track_head, thisWaypoint); - - if (gbfeof(psit_file)) break; - - psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); - } - else break; - } + char tbuf[100]; + char trkname[256]; + unsigned int trk_num; + + struct tm tmTime; + time_t dateTime = 0; + route_head *track_head = NULL; + unsigned int trk_count; + + waypoint *thisWaypoint; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), ltrimEOL); + if (strlen(psit_current_token) == 0) { + strcpy(trkname, "TRACK"); + } else { + strcpy(trkname, psit_current_token); + } + + rtrim(trkname); + + trk_num = 0; + + trk_count = 0; + + track_head = NULL; + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + + while (psit_isKnownToken(psit_current_token) != 0) { + if (strlen(psit_current_token) > 0) { + thisWaypoint = waypt_new(); + + thisWaypoint->latitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + thisWaypoint->longitude = atof(psit_current_token); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), comma); + if (psit_current_token[0] == '*') { + thisWaypoint->altitude = unknown_alt; + } else { + thisWaypoint->altitude = atof(psit_current_token); + } + + /* date portion of the date time DD/MM/YY */ + psit_getToken(psit_file, psit_current_token, + sizeof(psit_current_token), whitespace); + sscanf(psit_current_token, "%02d/%02d/%02d", + &(tmTime.tm_mday) , &(tmTime.tm_mon), + &(tmTime.tm_year)); + + /* years are less 1900 in the tm struct */ + tmTime.tm_year += (tmTime.tm_year > 50 ? 0 : 100); + /* months are 0 to 11 in the tm struct */ + tmTime.tm_mon--; + /* time portion of the date time hh:mm:ss */ + psit_getToken(psit_file,psit_current_token, + sizeof(psit_current_token), wscomma); + sscanf(psit_current_token, "%02d:%02d:%02d", + &(tmTime.tm_hour) , &(tmTime.tm_min), + &(tmTime.tm_sec)); + + tmTime.tm_isdst = 0; + dateTime = mkgmtime(&tmTime); + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), whitespace); + + if ((strcmp(psit_current_token, "1") == 0) || (track_head == NULL)) { + track_head = route_head_alloc(); + /* Add a number to the track name. With Garmins, the "first" tracklog is usually ACTIVE LOG + the second is ACTIVE LOG001 and so on */ + if (trk_num > 0) { + sprintf(tbuf, "%s%03d", trkname, trk_num); + track_head->rte_name = xstrdup(tbuf); + } else { + track_head->rte_name = xstrdup(trkname); + } + trk_num++; + track_add_head(track_head); + } + + thisWaypoint->creation_time = dateTime; + track_add_wpt(track_head, thisWaypoint); + + if (gbfeof(psit_file)) { + break; + } + + psit_getToken(psit_file,psit_current_token,sizeof(psit_current_token), wscomma); + } else { + break; + } + } } /* @@ -614,55 +631,57 @@ psit_track_r(gbfile *psit_file, route_head **trk) static void psit_trackhdr_w(gbfile *psit_file, const route_head *trk) { - char hdr[30]; - unsigned int trk_datapoints; - char *tname; - waypoint *testwpt; - time_t uniqueValue = 0; - - queue *elem, *tmp; - - if (psit_track_state == 2) { - /* total nodes (waypoints) this track */ - trk_datapoints = 0; - if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ - char *c; - - QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { - if (trk_datapoints == 0) { - testwpt = (waypoint *)elem; - uniqueValue = testwpt->creation_time; - } - trk_datapoints++; - } - - if (uniqueValue == 0) { - uniqueValue = current_time(); - } - - /* track name */ - if (!trk->rte_name) { - sprintf(hdr, "Track%04x", (unsigned) uniqueValue); - tname = xstrdup(hdr); - } - else - tname = xstrdup(trk->rte_name); - - /* check for psitrex comment sign; replace with '$' */ - while ((c = strchr(tname, '#'))) *c = '$'; - - gbfprintf (psit_file, "Track: %s\n", tname); - - xfree(tname); - } - } - psit_track_state = 1; + char hdr[30]; + unsigned int trk_datapoints; + char *tname; + waypoint *testwpt; + time_t uniqueValue = 0; + + queue *elem, *tmp; + + if (psit_track_state == 2) { + /* total nodes (waypoints) this track */ + trk_datapoints = 0; + if (trk->waypoint_list.next) { /* this test doesn't do what I want i.e test if this is a valid track - treat as a placeholder for now */ + char *c; + + QUEUE_FOR_EACH(&trk->waypoint_list, elem, tmp) { + if (trk_datapoints == 0) { + testwpt = (waypoint *)elem; + uniqueValue = testwpt->creation_time; + } + trk_datapoints++; + } + + if (uniqueValue == 0) { + uniqueValue = current_time(); + } + + /* track name */ + if (!trk->rte_name) { + sprintf(hdr, "Track%04x", (unsigned) uniqueValue); + tname = xstrdup(hdr); + } else { + tname = xstrdup(trk->rte_name); + } + + /* check for psitrex comment sign; replace with '$' */ + while ((c = strchr(tname, '#'))) { + *c = '$'; + } + + gbfprintf(psit_file, "Track: %s\n", tname); + + xfree(tname); + } + } + psit_track_state = 1; } static void psit_trackhdr_w_wrapper(const route_head *trk) { - psit_trackhdr_w(psit_file_out, trk); + psit_trackhdr_w(psit_file_out, trk); } @@ -673,136 +692,140 @@ psit_trackhdr_w_wrapper(const route_head *trk) static void psit_trackdatapoint_w(gbfile *psit_file, const waypoint *wpt) { - time_t t = wpt->creation_time; - struct tm *tmTime = gmtime(&t); - - gbfprintf(psit_file, "%11.6f,%11.6f,", - wpt->latitude, - wpt->longitude); - - if (wpt->altitude == unknown_alt) - gbfprintf(psit_file, "********, "); - else - gbfprintf(psit_file, "%8.2f, ", - wpt->altitude); - - /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */ - gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,", - tmTime->tm_mday, - tmTime->tm_mon+1, - tmTime->tm_year % 100, - tmTime->tm_hour, - tmTime->tm_min, - tmTime->tm_sec); - - gbfprintf(psit_file," %d\n", psit_track_state); - psit_track_state = 0; + time_t t = wpt->creation_time; + struct tm *tmTime = gmtime(&t); + + gbfprintf(psit_file, "%11.6f,%11.6f,", + wpt->latitude, + wpt->longitude); + + if (wpt->altitude == unknown_alt) { + gbfprintf(psit_file, "********, "); + } else + gbfprintf(psit_file, "%8.2f, ", + wpt->altitude); + + /* Following date time format is fixed and reveals the origin of PsiTrex (i.e. the UK) */ + gbfprintf(psit_file, "%02d/%02d/%02d %02d:%02d:%02d,", + tmTime->tm_mday, + tmTime->tm_mon+1, + tmTime->tm_year % 100, + tmTime->tm_hour, + tmTime->tm_min, + tmTime->tm_sec); + + gbfprintf(psit_file," %d\n", psit_track_state); + psit_track_state = 0; } static void psit_trackdatapoint_w_wrapper(const waypoint *wpt) { - psit_trackdatapoint_w(psit_file_out, wpt); + psit_trackdatapoint_w(psit_file_out, wpt); } static void psit_read(void) { - waypoint *wpt; - route_head *rte; - route_head *trk; + waypoint *wpt; + route_head *rte; + route_head *trk; #ifdef DUMP_ICON_TABLE - printf("static icon_mapping_t icon_table[] = {\n"); + printf("static icon_mapping_t icon_table[] = {\n"); #endif - psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace); - - do { - if (strlen(psit_current_token) == 0) break; - - if (strcmp(psit_current_token, "Track:") == 0) { - if (global_opts.objective == trkdata) { - psit_track_r(psit_file_in, &trk); - } - else break; /* psitrex files only have one format in; */ - /* if this is a track file and we don't want them, them bail out */ - } - else if (strcmp(psit_current_token, "Route:") == 0) { - if (global_opts.objective == rtedata) { - psit_route_r(psit_file_in, &rte); - } - else break; /* ditto, but for routes */ - } - else { - /* Must be waypoints in this file */ - if (global_opts.objective == wptdata) { - psit_waypoint_r(psit_file_in, &wpt); + psit_getToken(psit_file_in, psit_current_token, sizeof(psit_current_token), whitespace); + + do { + if (strlen(psit_current_token) == 0) { + break; + } + + if (strcmp(psit_current_token, "Track:") == 0) { + if (global_opts.objective == trkdata) { + psit_track_r(psit_file_in, &trk); + } else { + break; /* psitrex files only have one format in; */ + } + /* if this is a track file and we don't want them, them bail out */ + } else if (strcmp(psit_current_token, "Route:") == 0) { + if (global_opts.objective == rtedata) { + psit_route_r(psit_file_in, &rte); + } else { + break; /* ditto, but for routes */ + } + } else { + /* Must be waypoints in this file */ + if (global_opts.objective == wptdata) { + psit_waypoint_r(psit_file_in, &wpt); #ifdef DUMP_ICON_TABLE - printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); + printf("\t{ %4u, \"%s\" },\n", icon, wpt->shortname); #endif - } - else break; - } - } while (!gbfeof(psit_file_in)); + } else { + break; + } + } + } while (!gbfeof(psit_file_in)); - return; + return; #ifdef DUMP_ICON_TABLE - printf("\t{ -1, NULL },\n"); - printf("};\n"); + printf("\t{ -1, NULL },\n"); + printf("};\n"); #endif } -static void +static void psit_noop(const route_head *wp) { - /* no-op */ + /* no-op */ } void psit_write(void) { - int short_length; + int short_length; - if (snlen) - short_length = atoi(snlen); - else - short_length = 10; + if (snlen) { + short_length = atoi(snlen); + } else { + short_length = 10; + } - mkshort_handle = mkshort_new_handle(); + mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, short_length); - setshort_whitespace_ok(mkshort_handle, 0); + setshort_length(mkshort_handle, short_length); + setshort_whitespace_ok(mkshort_handle, 0); - psit_track_state = 2; + psit_track_state = 2; - if (global_opts.objective == wptdata) { - waypt_disp_all(psit_waypoint_w_wrapper); - } - if (global_opts.objective == rtedata) { - route_disp_all(psit_routehdr_w_wrapper, psit_noop, psit_waypoint_w_wrapper); - } - if (global_opts.objective == trkdata) { - track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); - } + if (global_opts.objective == wptdata) { + waypt_disp_all(psit_waypoint_w_wrapper); + } + if (global_opts.objective == rtedata) { + route_disp_all(psit_routehdr_w_wrapper, psit_noop, psit_waypoint_w_wrapper); + } + if (global_opts.objective == trkdata) { + track_disp_all(psit_trackhdr_w_wrapper, psit_noop, psit_trackdatapoint_w_wrapper); + } - mkshort_del_handle(&mkshort_handle); + mkshort_del_handle(&mkshort_handle); } ff_vecs_t psit_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - psit_rd_init, - psit_wr_init, - psit_rd_deinit, - psit_wr_deinit, - psit_read, - psit_write, - NULL, - psit_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + psit_rd_init, + psit_wr_init, + psit_rd_deinit, + psit_wr_deinit, + psit_read, + psit_write, + NULL, + psit_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/psp.c b/gpsbabel/psp.c index 8934b4eb8..b6114b27f 100644 --- a/gpsbabel/psp.c +++ b/gpsbabel/psp.c @@ -1,7 +1,7 @@ /* PocketStreets 2002 Pushpin Files Contributed to gpsbabel by Alex Mottram (geo_alexm at cox-internet.com) - + Copyright (C) 2002 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -43,357 +43,364 @@ static short_handle mkshort_handle; static void psp_write_str(const char *str) { - if (str && *str) { - short *unicode; - int len; - - /* convert UTF-8 string into a unicode sequence */ - /* not perfect, but enough for us */ - unicode = cet_str_any_to_uni(str, global_opts.charset, &len); - if (len > MAXPSPSTRINGSIZE) len = MAXPSPSTRINGSIZE; - gbfputc((unsigned char)len, psp_file_out); - if (len) gbfwrite(unicode, 2, len, psp_file_out); - - xfree(unicode); - } - else - gbfputc(0, psp_file_out); + if (str && *str) { + short *unicode; + int len; + + /* convert UTF-8 string into a unicode sequence */ + /* not perfect, but enough for us */ + unicode = cet_str_any_to_uni(str, global_opts.charset, &len); + if (len > MAXPSPSTRINGSIZE) { + len = MAXPSPSTRINGSIZE; + } + gbfputc((unsigned char)len, psp_file_out); + if (len) { + gbfwrite(unicode, 2, len, psp_file_out); + } + + xfree(unicode); + } else { + gbfputc(0, psp_file_out); + } } /* ToDo: move the code inside to CET library */ static char * psp_read_str(gbfile *fin) { - int len; - gbint16 *buff; - char *res; - - len = (unsigned char)gbfgetc(fin); - if (len == 0) return NULL; - - buff = xmalloc(len * sizeof(*buff)); - gbfread(buff, sizeof(*buff), len, fin); - res = cet_str_uni_to_utf8(buff, len); - xfree(buff); - - return res; + int len; + gbint16 *buff; + char *res; + + len = (unsigned char)gbfgetc(fin); + if (len == 0) { + return NULL; + } + + buff = xmalloc(len * sizeof(*buff)); + gbfread(buff, sizeof(*buff), len, fin); + res = cet_str_uni_to_utf8(buff, len); + xfree(buff); + + return res; } /* Implement the grid in ascii art... This makes a bit of sense if you stand on a point over the north pole and look down on the earth. --180 -90 0 90 180 +-180 -90 0 90 180 ------------------------------------ /\ | 0x03 U|S 0x02 U|k 0x00 | 0x01 | 90 |--------|--------|--------|--------| 0 | 0x07 | 0x06 | 0x04 | 0x05 | -90 ------------------------------------ \/ -*/ -static +*/ +static char grid_byte(double lat, double lon) { - char c = 0x00; - - if ((lon >= 0.0) && (lon < 90.0)) { - if (lat >= 0.0) { - c = 0x00; - } else { - c = 0x04; - } - } else - if (lon >= 90.0) { - if (lat >= 0.0) { - c = 0x01; - } else { - c = 0x05; - } - } else - if ((lon < 0.0) && (lon >= -90.0)) { - if (lat >= 0.0) { - c = 0x02; - } else { - c = 0x06; - } - } else - if (lon < -90.0) { - if (lat >= 0.0) { - c = 0x03; - } else { - c = 0x07; - } + char c = 0x00; + + if ((lon >= 0.0) && (lon < 90.0)) { + if (lat >= 0.0) { + c = 0x00; + } else { + c = 0x04; + } + } else if (lon >= 90.0) { + if (lat >= 0.0) { + c = 0x01; + } else { + c = 0x05; + } + } else if ((lon < 0.0) && (lon >= -90.0)) { + if (lat >= 0.0) { + c = 0x02; + } else { + c = 0x06; } - - return (c); -} + } else if (lon < -90.0) { + if (lat >= 0.0) { + c = 0x03; + } else { + c = 0x07; + } + } + + return (c); +} void decode_psp_coordinates(double * lat, double * lon, const char lonbyte) { - /* This is some sort of 1/2 Polar, 1/2 Cartesian coordinate mess in */ - /* the pin file. I really shouldn't have to do this. Zones 02 and 03 */ - /* work properly. The other zones are assumptions based on 02 and 03 */ - - if ((lonbyte == 0x02) || (lonbyte == 0x06)) { - /* one step west of zero longitude */ - if (*lon > 0.0) - *lon *= -1.0; - } else - if ((lonbyte == 0x03) || (lonbyte == 0x07)) { - /* two steps west of zero longitude */ - if (*lon > 0.0) - *lon -= 180.0; - } else - if ((lonbyte == 0x00) || (lonbyte == 0x04)) { - /* one step east of zero longitude */ - if (*lon < 0.0) - *lon *= -1.0; - } else - if ((lonbyte == 0x01) || (lonbyte == 0x05)) { - /* two steps east of zero longitude */ - if (*lon < 0.0) - *lon += 180.0; + /* This is some sort of 1/2 Polar, 1/2 Cartesian coordinate mess in */ + /* the pin file. I really shouldn't have to do this. Zones 02 and 03 */ + /* work properly. The other zones are assumptions based on 02 and 03 */ + + if ((lonbyte == 0x02) || (lonbyte == 0x06)) { + /* one step west of zero longitude */ + if (*lon > 0.0) { + *lon *= -1.0; + } + } else if ((lonbyte == 0x03) || (lonbyte == 0x07)) { + /* two steps west of zero longitude */ + if (*lon > 0.0) { + *lon -= 180.0; + } + } else if ((lonbyte == 0x00) || (lonbyte == 0x04)) { + /* one step east of zero longitude */ + if (*lon < 0.0) { + *lon *= -1.0; } + } else if ((lonbyte == 0x01) || (lonbyte == 0x05)) { + /* two steps east of zero longitude */ + if (*lon < 0.0) { + *lon += 180.0; + } + } } static int valid_psp_header(char * header) { - char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50 }; /* 1niP */ + char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50 }; /* 1niP */ + + return (memcmp(header_bytes, header, 4)); - return (memcmp(header_bytes, header, 4)); - } static void psp_rd_init(const char *fname) { - psp_file_in = gbfopen_le(fname, "rb", MYNAME); + psp_file_in = gbfopen_le(fname, "rb", MYNAME); } static void psp_rd_deinit(void) { - gbfclose(psp_file_in); + gbfclose(psp_file_in); } static void psp_wr_init(const char *fname) { - psp_file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); + psp_file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void psp_wr_deinit(void) { - mkshort_del_handle(&mkshort_handle); - gbfclose(psp_file_out); + mkshort_del_handle(&mkshort_handle); + gbfclose(psp_file_out); } static void psp_read(void) { - char buff[MAXPSPSTRINGSIZE + 1]; - double radians; - double lat, lon; - waypoint *wpt_tmp; - short int pincount; - short int pindex; - char gridbyte = 0x00; - char *tmp; + char buff[MAXPSPSTRINGSIZE + 1]; + double radians; + double lat, lon; + waypoint *wpt_tmp; + short int pincount; + short int pindex; + char gridbyte = 0x00; + char *tmp; + + /* 32 bytes - file header */ + psp_fread(&buff[0], 1, 32, psp_file_in); - /* 32 bytes - file header */ - psp_fread(&buff[0], 1, 32, psp_file_in); + if (valid_psp_header(buff) != 0) { + fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); + } - if (valid_psp_header(buff) != 0) { - fatal(MYNAME ": input file does not appear to be a valid .PSP file.\n"); - } + pincount = le_read16(&buff[12]); - pincount = le_read16(&buff[12]); + while (pincount--) { + wpt_tmp = waypt_new(); - while (pincount--) { - wpt_tmp = waypt_new(); + wpt_tmp->altitude = unknown_alt; - wpt_tmp->altitude = unknown_alt; - - /* offset 0x20 - 0x21 pin index */ - psp_fread(&pindex, 1, 2, psp_file_in); + /* offset 0x20 - 0x21 pin index */ + psp_fread(&pindex, 1, 2, psp_file_in); - /* offset 0x22 - 0x23 */ - psp_fread(&buff[0], 1, 2, psp_file_in); + /* offset 0x22 - 0x23 */ + psp_fread(&buff[0], 1, 2, psp_file_in); - /* offset 0x24 */ - /* 1 byte, the grid byte - needed for sign corrections later*/ - psp_fread(&gridbyte, 1, 1, psp_file_in); + /* offset 0x24 */ + /* 1 byte, the grid byte - needed for sign corrections later*/ + psp_fread(&gridbyte, 1, 1, psp_file_in); - /* 8 bytes - latitude in radians */ - radians = psp_fread_double(psp_file_in); - lat = DEG(radians); + /* 8 bytes - latitude in radians */ + radians = psp_fread_double(psp_file_in); + lat = DEG(radians); - /* 8 bytes - longitude in radians */ - radians = psp_fread_double(psp_file_in); - lon = DEG(radians); + /* 8 bytes - longitude in radians */ + radians = psp_fread_double(psp_file_in); + lon = DEG(radians); - /* since we don't know the origin of this PSP file, we use */ - /* the grid byte adjust longitude, if necessary, mimicing */ - /* the behavior of pocketstreets correcting the data. This */ - /* does not correct the fact that points in eastern US are */ - /* written with the wrong coordinates by S&T. (MS bug) */ + /* since we don't know the origin of this PSP file, we use */ + /* the grid byte adjust longitude, if necessary, mimicing */ + /* the behavior of pocketstreets correcting the data. This */ + /* does not correct the fact that points in eastern US are */ + /* written with the wrong coordinates by S&T. (MS bug) */ - decode_psp_coordinates(&lat, &lon, gridbyte); + decode_psp_coordinates(&lat, &lon, gridbyte); - wpt_tmp->latitude = lat; - wpt_tmp->longitude = lon; - - /* 1 byte - pin display properties */ - psp_fread(&buff[0], 1, 1, psp_file_in); + wpt_tmp->latitude = lat; + wpt_tmp->longitude = lon; - /* 3 bytes - unknown */ - psp_fread(&buff[0], 1, 3, psp_file_in); + /* 1 byte - pin display properties */ + psp_fread(&buff[0], 1, 1, psp_file_in); - /* 1 bytes - icon (values: 0x00 - 0x27) */ - psp_fread(&buff[0], 1, 1, psp_file_in); + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); - /* 3 bytes - unknown */ - psp_fread(&buff[0], 1, 3, psp_file_in); + /* 1 bytes - icon (values: 0x00 - 0x27) */ + psp_fread(&buff[0], 1, 1, psp_file_in); - wpt_tmp->shortname = psp_read_str(psp_file_in); - wpt_tmp->description = psp_read_str(psp_file_in); - tmp = psp_read_str(psp_file_in); /* (address?) */ - if (tmp) xfree(tmp); + /* 3 bytes - unknown */ + psp_fread(&buff[0], 1, 3, psp_file_in); + + wpt_tmp->shortname = psp_read_str(psp_file_in); + wpt_tmp->description = psp_read_str(psp_file_in); + tmp = psp_read_str(psp_file_in); /* (address?) */ + if (tmp) { + xfree(tmp); + } - waypt_add(wpt_tmp); - } + waypt_add(wpt_tmp); + } } static void psp_waypt_pr(const waypoint *wpt) { - double lon, lat; - char tbuf[64]; - char c; - static short int pindex = 0; - char *shortname; - char *description; - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = xstrdup(wpt->description); - } else { - /* no description available */ - shortname = xstrdup(""); - } - } else{ - shortname = xstrdup(wpt->shortname); - } - - if (! wpt->description) { - if (shortname) { - description = xstrdup(shortname); - } else { - description = xstrdup(""); - } - } else{ - description = xstrdup(wpt->description); - } - - /* convert lat/long back to radians */ - lat = RAD(wpt->latitude); - lon = RAD(wpt->longitude); - - pindex++; - /* 2 bytes - pin index */ - gbfputint16(pindex, psp_file_out); - - /* 2 bytes - null bytes */ - gbfputint16(0, psp_file_out); - - - /* set the grid byte */ - c = grid_byte(wpt->latitude, - wpt->longitude); - - /* since the grid byte matches with what pocketstreets does to */ - /* input files, our output appears identical to a pin file that */ - /* has already been processed and corrected by pocketstreets. */ - /* Due to the grid and signs, it'll look different than one that */ - /* comes straight from S&T. */ - - /* the grid byte */ - gbfwrite(&c, 1, 1, psp_file_out); - - /* 8 bytes - latitude/radians */ - psp_fwrite_double(lat, psp_file_out); - - /* 8 bytes - longitude/radians */ - psp_fwrite_double(lon, psp_file_out); - - /* 1 byte - pin properties */ - c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */ - gbfwrite(&c, 1, 1, psp_file_out); - - memset(tbuf, '\0', sizeof(tbuf)); - - /* 3 unknown bytes */ - gbfwrite(tbuf, 1, 3, psp_file_out); - - /* 1 icon byte 0x00 = PIN */ - gbfwrite(tbuf, 1, 1, psp_file_out); - - /* 3 unknown bytes */ - gbfwrite(tbuf, 1, 3, psp_file_out); /* 3 junk */ - - psp_write_str(shortname); - psp_write_str(description); - - /* just for the hell of it, we'll scrap the third string. */ - psp_write_str(""); - - xfree(shortname); - xfree(description); + double lon, lat; + char tbuf[64]; + char c; + static short int pindex = 0; + char *shortname; + char *description; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = xstrdup(wpt->description); + } + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else { + shortname = xstrdup(wpt->shortname); + } + + if (! wpt->description) { + if (shortname) { + description = xstrdup(shortname); + } else { + description = xstrdup(""); + } + } else { + description = xstrdup(wpt->description); + } + + /* convert lat/long back to radians */ + lat = RAD(wpt->latitude); + lon = RAD(wpt->longitude); + + pindex++; + /* 2 bytes - pin index */ + gbfputint16(pindex, psp_file_out); + + /* 2 bytes - null bytes */ + gbfputint16(0, psp_file_out); + + + /* set the grid byte */ + c = grid_byte(wpt->latitude, + wpt->longitude); + + /* since the grid byte matches with what pocketstreets does to */ + /* input files, our output appears identical to a pin file that */ + /* has already been processed and corrected by pocketstreets. */ + /* Due to the grid and signs, it'll look different than one that */ + /* comes straight from S&T. */ + + /* the grid byte */ + gbfwrite(&c, 1, 1, psp_file_out); + + /* 8 bytes - latitude/radians */ + psp_fwrite_double(lat, psp_file_out); + + /* 8 bytes - longitude/radians */ + psp_fwrite_double(lon, psp_file_out); + + /* 1 byte - pin properties */ + c = 0x14; /* display pin name on, display notes on. 0x04 = no notes */ + gbfwrite(&c, 1, 1, psp_file_out); + + memset(tbuf, '\0', sizeof(tbuf)); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); + + /* 1 icon byte 0x00 = PIN */ + gbfwrite(tbuf, 1, 1, psp_file_out); + + /* 3 unknown bytes */ + gbfwrite(tbuf, 1, 3, psp_file_out); /* 3 junk */ + + psp_write_str(shortname); + psp_write_str(description); + + /* just for the hell of it, we'll scrap the third string. */ + psp_write_str(""); + + xfree(shortname); + xfree(description); } static void psp_write(void) { - short int s; - unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + short int s; + unsigned char header_bytes[] = { 0x31, 0x6E, 0x69, 0x50, 0x20, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /* the header: */ + /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ + /* offset 0x0C - 0x0D = 2 byte pin count */ - /* the header: */ - /* 31 6E 69 50 20 00 00 00 08 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 */ - /* offset 0x0C - 0x0D = 2 byte pin count */ + s = waypt_count(); - s = waypt_count(); - - if (global_opts.synthesize_shortnames) { - setshort_length(mkshort_handle, 32); - setshort_whitespace_ok(mkshort_handle, 1); - } + if (global_opts.synthesize_shortnames) { + setshort_length(mkshort_handle, 32); + setshort_whitespace_ok(mkshort_handle, 1); + } - if (s > MAXPSPOUTPUTPINS) { - fatal(MYNAME ": attempt to output too many pushpins (%d). The max is %d. Sorry.\n", s, MAXPSPOUTPUTPINS); - } + if (s > MAXPSPOUTPUTPINS) { + fatal(MYNAME ": attempt to output too many pushpins (%d). The max is %d. Sorry.\n", s, MAXPSPOUTPUTPINS); + } - /* insert waypoint count into header */ - le_write16(&header_bytes[12], s); + /* insert waypoint count into header */ + le_write16(&header_bytes[12], s); - gbfwrite(header_bytes, 1, 32, psp_file_out); + gbfwrite(header_bytes, 1, 32, psp_file_out); - waypt_disp_all(psp_waypt_pr); + waypt_disp_all(psp_waypt_pr); } ff_vecs_t psp_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - psp_rd_init, - psp_wr_init, - psp_rd_deinit, - psp_wr_deinit, - psp_read, - psp_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* Fixed because of unicode strings in psp files (see psp_read_str / psp_write_str) */ + ff_type_file, + FF_CAP_RW_WPT, + psp_rd_init, + psp_wr_init, + psp_rd_deinit, + psp_wr_deinit, + psp_read, + psp_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* Fixed because of unicode strings in psp files (see psp_read_str / psp_write_str) */ }; diff --git a/gpsbabel/queue.c b/gpsbabel/queue.c index 3e8181159..3bd0c082c 100644 --- a/gpsbabel/queue.c +++ b/gpsbabel/queue.c @@ -25,23 +25,23 @@ void enqueue(queue *new_el, queue *old) { - new_el->next = old->next; - new_el->prev = old; - old->next->prev = new_el; - old->next = new_el; + new_el->next = old->next; + new_el->prev = old; + old->next->prev = new_el; + old->next = new_el; } queue * dequeue(queue *element) { - queue *prev = element->prev; - queue *next = element->next; - - next->prev = prev; - prev->next = next; - - QUEUE_INIT(element); - return element; + queue *prev = element->prev; + queue *next = element->next; + + next->prev = prev; + prev->next = next; + + QUEUE_INIT(element); + return element; } /* @@ -55,17 +55,17 @@ dequeue(queue *element) /* * Demonstration code for sorting a linked list. - * + * * The algorithm used is Mergesort, because that works really well * on linked lists, without requiring the O(N) extra space it needs * when you do it on arrays. - * - * ... + * + * ... */ /* * This file is copyright 2001 Simon Tatham. - * + * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without @@ -74,10 +74,10 @@ dequeue(queue *element) * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: - * + * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -90,114 +90,133 @@ dequeue(queue *element) void -sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)) +sortqueue(queue *qh, int (*cmp)(const queue *, const queue *)) { - queue *p, *q, *e, *tail, *oldhead, *list; - int insize, nmerges, psize, qsize, i; - - /* - * Special case: if `list' is empty, we're done. - */ - if (QUEUE_EMPTY(qh)) - return; - - /* - * The algorithm doesn't really want the extra list head - * element. So remove the list head for now. Put it back later. - */ - - list = QUEUE_FIRST(qh); - dequeue(qh); - - insize = 1; - - while (1) { - p = list; - oldhead = list; /* only used for circular linkage */ - list = NULL; - tail = NULL; - - nmerges = 0; /* count number of merges we do in this pass */ - - while (p) { - nmerges++; /* there exists a merge to be done */ - /* step `insize' places along from p */ - q = p; - psize = 0; - for (i = 0; i < insize; i++) { - psize++; - q = (q->next == oldhead ? NULL : q->next); - if (!q) break; - } - - /* if q hasn't fallen off end, we have - * two lists to merge */ - qsize = insize; - - /* now we have two lists; merge them */ - while (psize > 0 || (qsize > 0 && q)) { - - /* decide whether next element of - * merge comes from p or q - */ - if (psize == 0) { - /* p is empty; e must come from q. */ - e = q; q = q->next; qsize--; - if (q == oldhead) q = NULL; - } else if (qsize == 0 || !q) { - /* q is empty; e must come from p. */ - e = p; p = p->next; psize--; - if (p == oldhead) p = NULL; - } else if (cmp(p,q) <= 0) { - /* First element of p is - * lower (or same); e must - * come from p. - */ - e = p; p = p->next; psize--; - if (p == oldhead) p = NULL; - } else { - /* First element of q is - * lower; e must come from - * q. - */ - e = q; q = q->next; qsize--; - if (q == oldhead) q = NULL; - } - - /* add the next element to the merged list */ - if (tail) { - tail->next = e; - } else { - list = e; - } - - /* Maintain reverse pointers in a - * doubly linked list. */ - e->prev = tail; - - tail = e; - } - - /* now p has stepped `insize' places - * along, and q has too */ - p = q; - } - tail->next = list; - list->prev = tail; - - /* If we have done only one merge, we're finished. - * Allow for nmerges==0, the empty list case. - */ - if (nmerges <= 1) { - - /* Put the list head back at the start of the list */ - ENQUEUE_TAIL(list, qh); - return; - - } - - /* Otherwise repeat, merging lists twice the size */ - insize *= 2; - } + queue *p, *q, *e, *tail, *oldhead, *list; + int insize, nmerges, psize, qsize, i; + + /* + * Special case: if `list' is empty, we're done. + */ + if (QUEUE_EMPTY(qh)) { + return; + } + + /* + * The algorithm doesn't really want the extra list head + * element. So remove the list head for now. Put it back later. + */ + + list = QUEUE_FIRST(qh); + dequeue(qh); + + insize = 1; + + while (1) { + p = list; + oldhead = list; /* only used for circular linkage */ + list = NULL; + tail = NULL; + + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) { + nmerges++; /* there exists a merge to be done */ + /* step `insize' places along from p */ + q = p; + psize = 0; + for (i = 0; i < insize; i++) { + psize++; + q = (q->next == oldhead ? NULL : q->next); + if (!q) { + break; + } + } + + /* if q hasn't fallen off end, we have + * two lists to merge */ + qsize = insize; + + /* now we have two lists; merge them */ + while (psize > 0 || (qsize > 0 && q)) { + + /* decide whether next element of + * merge comes from p or q + */ + if (psize == 0) { + /* p is empty; e must come from q. */ + e = q; + q = q->next; + qsize--; + if (q == oldhead) { + q = NULL; + } + } else if (qsize == 0 || !q) { + /* q is empty; e must come from p. */ + e = p; + p = p->next; + psize--; + if (p == oldhead) { + p = NULL; + } + } else if (cmp(p,q) <= 0) { + /* First element of p is + * lower (or same); e must + * come from p. + */ + e = p; + p = p->next; + psize--; + if (p == oldhead) { + p = NULL; + } + } else { + /* First element of q is + * lower; e must come from + * q. + */ + e = q; + q = q->next; + qsize--; + if (q == oldhead) { + q = NULL; + } + } + + /* add the next element to the merged list */ + if (tail) { + tail->next = e; + } else { + list = e; + } + + /* Maintain reverse pointers in a + * doubly linked list. */ + e->prev = tail; + + tail = e; + } + + /* now p has stepped `insize' places + * along, and q has too */ + p = q; + } + tail->next = list; + list->prev = tail; + + /* If we have done only one merge, we're finished. + * Allow for nmerges==0, the empty list case. + */ + if (nmerges <= 1) { + + /* Put the list head back at the start of the list */ + ENQUEUE_TAIL(list, qh); + return; + + } + + /* Otherwise repeat, merging lists twice the size */ + insize *= 2; + } } diff --git a/gpsbabel/queue.h b/gpsbabel/queue.h index 5b53ab9e1..a72efabc6 100644 --- a/gpsbabel/queue.h +++ b/gpsbabel/queue.h @@ -20,14 +20,14 @@ */ typedef struct queue { - struct queue *next; - struct queue *prev; + struct queue *next; + struct queue *prev; } queue; void enqueue(queue *new_el, queue *old); queue * dequeue(queue *element); -void sortqueue (queue *qh, int (*cmp)(const queue *, const queue *)); +void sortqueue(queue *qh, int (*cmp)(const queue *, const queue *)); #define QUEUE_INIT(head) (head)->next = ((head)->prev = head) #define QUEUE_FIRST(head) ((head)->next) diff --git a/gpsbabel/quovadis.c b/gpsbabel/quovadis.c index 295e272d2..67dd99d87 100644 --- a/gpsbabel/quovadis.c +++ b/gpsbabel/quovadis.c @@ -32,238 +32,238 @@ static char *dbname = NULL; static arglist_t quovadis_args[] = { - {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + {"dbname", &dbname, "Database name", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, + ARG_TERMINATOR }; static struct qv_icon_mapping mapping[] = { - { gt_unknown, QUESTION_ICON }, - { gt_traditional, HOSPITAL_ICON }, - { gt_multi, DOCUMENT_ICON }, - { gt_virtual, CAMERA_ICON }, - { gt_letterbox, MAILBOX_ICON }, - { gt_event, MEETING_ICON }, - { gt_suprise, GIFTSHOP_ICON }, + { gt_unknown, QUESTION_ICON }, + { gt_traditional, HOSPITAL_ICON }, + { gt_multi, DOCUMENT_ICON }, + { gt_virtual, CAMERA_ICON }, + { gt_letterbox, MAILBOX_ICON }, + { gt_event, MEETING_ICON }, + { gt_suprise, GIFTSHOP_ICON }, }; #define num_mappings (sizeof(mapping) / sizeof(struct qv_icon_mapping)) -static geocache_type icon_to_wpt(int icon_bitmap) { - unsigned int i; +static geocache_type icon_to_wpt(int icon_bitmap) +{ + unsigned int i; - for (i = 0; i < num_mappings; i++) { - if (icon_bitmap == mapping[i].bitmap_id) { - return mapping[i].gc_type; - } + for (i = 0; i < num_mappings; i++) { + if (icon_bitmap == mapping[i].bitmap_id) { + return mapping[i].gc_type; } - return gt_unknown; + } + return gt_unknown; } -static int wpt_to_icon(geocache_type type) { - unsigned int i; +static int wpt_to_icon(geocache_type type) +{ + unsigned int i; - for (i = 0; i < num_mappings; i++) { - if (type == mapping[i].gc_type) { - return mapping[i].bitmap_id; - } + for (i = 0; i < num_mappings; i++) { + if (type == mapping[i].gc_type) { + return mapping[i].bitmap_id; } - return QUESTION_ICON; + } + return QUESTION_ICON; } static void rd_init(const char *fname) { - file_in = pdb_open(fname, MYNAME); + file_in = pdb_open(fname, MYNAME); } static void rd_deinit(void) { - pdb_close(file_in); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_in); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void wr_init(const char *fname) { - file_out = pdb_create(fname, MYNAME); - ct = 0; + file_out = pdb_create(fname, MYNAME); + ct = 0; } static void wr_deinit(void) { - pdb_close(file_out); - if ( dbname ) { - xfree(dbname); - dbname = NULL; - } + pdb_close(file_out); + if (dbname) { + xfree(dbname); + dbname = NULL; + } } static void data_read(void) { - struct record *rec; - pdbrec_t *pdb_rec; - int i; + struct record *rec; + pdbrec_t *pdb_rec; + int i; - if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { - fatal(MYNAME ": Not a QuoVadis file.\n"); - } - - /* Ignore the first record, it contains one zero byte */ - for(pdb_rec = file_in->rec_list->next; pdb_rec; pdb_rec = pdb_rec->next) { - int num_recs = pdb_rec->size / sizeof(struct record); - for (i = 0; i < num_recs; i++) { - waypoint *wpt_tmp; - - wpt_tmp = waypt_new(); - - rec = (struct record *) - &(pdb_rec->data[i * sizeof(struct record)]); - - wpt_tmp->longitude = - (be_read32(&rec->longitude) / 1000000.0) - 180.0; - wpt_tmp->latitude = - 90.0 - (be_read32(&rec->latitude) / 1000000.0); - wpt_tmp->shortname = xstrdup(rec->name); - - waypt_alloc_gc_data(wpt_tmp)->type = - icon_to_wpt(be_read16(&rec->icon_bitmap)); - - waypt_add(wpt_tmp); - } - } -} + if ((file_in->creator != MYCREATOR) || (file_in->type != MYTYPE)) { + fatal(MYNAME ": Not a QuoVadis file.\n"); + } + /* Ignore the first record, it contains one zero byte */ + for (pdb_rec = file_in->rec_list->next; pdb_rec; pdb_rec = pdb_rec->next) { + int num_recs = pdb_rec->size / sizeof(struct record); + for (i = 0; i < num_recs; i++) { + waypoint *wpt_tmp; -static void -quovadis_writewpt(waypoint *wpt) -{ - struct record *rec; - int i; + wpt_tmp = waypt_new(); - if (current_rec == NULL) { - gbuint8 dummy = 0; - - pdb_write_rec(file_out, 0, 0, ct++, &dummy, 1); + rec = (struct record *) + &(pdb_rec->data[i * sizeof(struct record)]); - current_rec = (gbuint8 *) xcalloc(MAXCHUNKSIZE, 1); - rec_index = 0; - rec_ptr = current_rec; - } + wpt_tmp->longitude = + (be_read32(&rec->longitude) / 1000000.0) - 180.0; + wpt_tmp->latitude = + 90.0 - (be_read32(&rec->latitude) / 1000000.0); + wpt_tmp->shortname = xstrdup(rec->name); - rec = (struct record *) xcalloc(sizeof(*rec),1); + waypt_alloc_gc_data(wpt_tmp)->type = + icon_to_wpt(be_read16(&rec->icon_bitmap)); - be_write32(&rec->longitude, (unsigned int) ((wpt->longitude + - 180.0) * 1000000.0)); - be_write32(&rec->latitude, (unsigned int) ((90.0 - wpt->latitude) * 1000000.0)); - if ( wpt->shortname ) { - strncpy(rec->name, wpt->shortname, 32 ); - rec->name[31] = '\0'; - } - else { - rec->name[0] = '\0'; - } - be_write16(&rec->icon_bitmap, wpt_to_icon(wpt->gc_data->type)); - be_write32(&rec->note_id, 0); - rec->name_scale = DEFAULT_NAME_SCALE; - rec->icon_scale = DEFAULT_ICON_SCALE; - for (i = 0; i < 7; i++) { - rec->reserved[i] = 0; + waypt_add(wpt_tmp); } + } +} - memcpy(rec_ptr, rec, sizeof(*rec)); - rec_ptr += sizeof(*rec); - rec_index += 1; - xfree(rec); - if (rec_index == MAXRECORDS) { - fatal(MYNAME ": cannot store more than %lu records at this time.\n", - (unsigned long) MAXRECORDS); - } +static void +quovadis_writewpt(waypoint *wpt) +{ + struct record *rec; + int i; + + if (current_rec == NULL) { + gbuint8 dummy = 0; + + pdb_write_rec(file_out, 0, 0, ct++, &dummy, 1); + + current_rec = (gbuint8 *) xcalloc(MAXCHUNKSIZE, 1); + rec_index = 0; + rec_ptr = current_rec; + } + + rec = (struct record *) xcalloc(sizeof(*rec),1); + + be_write32(&rec->longitude, (unsigned int)((wpt->longitude + + 180.0) * 1000000.0)); + be_write32(&rec->latitude, (unsigned int)((90.0 - wpt->latitude) * 1000000.0)); + if (wpt->shortname) { + strncpy(rec->name, wpt->shortname, 32); + rec->name[31] = '\0'; + } else { + rec->name[0] = '\0'; + } + be_write16(&rec->icon_bitmap, wpt_to_icon(wpt->gc_data->type)); + be_write32(&rec->note_id, 0); + rec->name_scale = DEFAULT_NAME_SCALE; + rec->icon_scale = DEFAULT_ICON_SCALE; + for (i = 0; i < 7; i++) { + rec->reserved[i] = 0; + } + + memcpy(rec_ptr, rec, sizeof(*rec)); + rec_ptr += sizeof(*rec); + rec_index += 1; + xfree(rec); + + if (rec_index == MAXRECORDS) { + fatal(MYNAME ": cannot store more than %lu records at this time.\n", + (unsigned long) MAXRECORDS); + } } -struct hdr{ - char *wpt_name; - waypoint *wpt; +struct hdr { + char *wpt_name; + waypoint *wpt; }; static -int +int compare(const void *a, const void *b) { - const struct hdr *wa = (const struct hdr *) a; - const struct hdr *wb = (const struct hdr *) b; + const struct hdr *wa = (const struct hdr *) a; + const struct hdr *wb = (const struct hdr *) b; - return strcmp(wa->wpt->shortname, wb->wpt->shortname); + return strcmp(wa->wpt->shortname, wb->wpt->shortname); } static void data_write(void) { - int i, ct = waypt_count(); - struct hdr *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - waypoint *waypointp; - - if ( dbname ) { - strncpy( file_out->name, dbname, PDB_DBNAMELEN ); - } - else { - strncpy(file_out->name, "QuoVadisMarkerDB", PDB_DBNAMELEN); - } - file_out->name[PDB_DBNAMELEN-1] = 0; - file_out->attr = PDB_FLAG_BACKUP; - file_out->ctime = file_out->mtime = current_time() + 2082844800U; - file_out->type = MYTYPE; /* CWpt */ - file_out->creator = MYCREATOR; /* cGPS */ - file_out->version = 1; - - /* - * All this is to sort by waypoint names before going to QuoVadis. - * Turns out plain old strcmp will do the trick... - */ - - htable = (struct hdr *) xmalloc(ct * sizeof(*htable)); - bh = htable; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - bh->wpt = waypointp; - bh->wpt_name = waypointp->shortname; - bh ++; - } - qsort(htable, ct, sizeof(*bh), compare); - - for (i=0;iname, dbname, PDB_DBNAMELEN); + } else { + strncpy(file_out->name, "QuoVadisMarkerDB", PDB_DBNAMELEN); + } + file_out->name[PDB_DBNAMELEN-1] = 0; + file_out->attr = PDB_FLAG_BACKUP; + file_out->ctime = file_out->mtime = current_time() + 2082844800U; + file_out->type = MYTYPE; /* CWpt */ + file_out->creator = MYCREATOR; /* cGPS */ + file_out->version = 1; + + /* + * All this is to sort by waypoint names before going to QuoVadis. + * Turns out plain old strcmp will do the trick... + */ + + htable = (struct hdr *) xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + bh->wpt_name = waypointp->shortname; + bh ++; + } + qsort(htable, ct, sizeof(*bh), compare); + + for (i=0; i 18.12 miles, 26 => 46 feet */ - char icon_scale; /* As above. */ - unsigned char reserved[8]; + char icon_scale; /* As above. */ + unsigned char reserved[8]; }; struct qv_icon_mapping { - const geocache_type gc_type; - const int bitmap_id; + const geocache_type gc_type; + const int bitmap_id; }; /* Icon Types */ diff --git a/gpsbabel/radius.c b/gpsbabel/radius.c index 831c4a8f4..dde26d064 100644 --- a/gpsbabel/radius.c +++ b/gpsbabel/radius.c @@ -41,183 +41,204 @@ static int maxct; static waypoint * home_pos; typedef struct { - double distance; + double distance; } extra_data; static arglist_t radius_args[] = { - {"lat", &latopt, "Latitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"lon", &lonopt, "Longitude for center point (D.DDDDD)", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"distance", &distopt, "Maximum distance from center", - NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"exclude", &exclopt, "Exclude points close to center", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"nosort", &nosort, "Inhibit sort by distance to center", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"maxcount", &maxctarg,"Output no more than this number of points", - NULL, ARGTYPE_INT, "1", NULL }, - {"asroute", &routename,"Put resulting waypoints in route of this name", - NULL, ARGTYPE_STRING, NULL, NULL }, - ARG_TERMINATOR + { + "lat", &latopt, "Latitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "lon", &lonopt, "Longitude for center point (D.DDDDD)", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "distance", &distopt, "Maximum distance from center", + NULL, ARGTYPE_FLOAT | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "exclude", &exclopt, "Exclude points close to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "nosort", &nosort, "Inhibit sort by distance to center", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "maxcount", &maxctarg,"Output no more than this number of points", + NULL, ARGTYPE_INT, "1", NULL + }, + { + "asroute", &routename,"Put resulting waypoints in route of this name", + NULL, ARGTYPE_STRING, NULL, NULL + }, + ARG_TERMINATOR }; static double gc_distance(double lat1, double lon1, double lat2, double lon2) { - return gcdist( - RAD(lat1), - RAD(lon1), - RAD(lat2), - RAD(lon2) - ); + return gcdist( + RAD(lat1), + RAD(lon1), + RAD(lat2), + RAD(lon2) + ); } static int dist_comp(const void * a, const void * b) { - const waypoint *x1 = *(waypoint **)a; - const waypoint *x2 = *(waypoint **)b; - extra_data *x1e = (extra_data *) x1->extra_data; - extra_data *x2e = (extra_data *) x2->extra_data; - - if (x1e->distance > x2e->distance) - return 1; - if (x1e->distance < x2e->distance) - return -1; - return 0; + const waypoint *x1 = *(waypoint **)a; + const waypoint *x2 = *(waypoint **)b; + extra_data *x1e = (extra_data *) x1->extra_data; + extra_data *x2e = (extra_data *) x2->extra_data; + + if (x1e->distance > x2e->distance) { + return 1; + } + if (x1e->distance < x2e->distance) { + return -1; + } + return 0; } -void +void radius_process(void) { - queue * elem, * tmp; - waypoint * waypointp; - double dist; - waypoint ** comp; - int i, wc; - queue temp_head; - route_head *rte_head = NULL; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - extra_data *ed; - - waypointp = (waypoint *)elem; - dist = gc_distance(waypointp->latitude, - waypointp->longitude, - home_pos->latitude, - home_pos->longitude); - - /* convert radians to float point statute miles */ - dist = radtomiles(dist); - - if ((dist >= pos_dist) == (exclopt == NULL)) { - waypt_del(waypointp); - waypt_free(waypointp); - continue; - } - - ed = (extra_data *) xcalloc(1, sizeof(*ed)); - ed->distance = dist; - waypointp->extra_data = ed; - } - - wc = waypt_count(); - QUEUE_INIT(&temp_head); - - comp = (waypoint **) xcalloc(wc, sizeof(*comp)); - - i = 0; - - /* - * Create an array of remaining waypoints, popping them off the - * master queue as we go. This gives us something reasonable - * for qsort. - */ - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypoint *wp = (waypoint *) elem; - comp[i] = wp; - waypt_del(wp); - i++; - } - - if (!nosort) { - qsort(comp, wc, sizeof(waypoint *), dist_comp); - } - - if (routename) { - rte_head = route_head_alloc(); - rte_head->rte_name = xstrdup(routename); - route_add_head(rte_head); - } - - /* - * The comp array is now sorted by distance. As we run through it, - * we push them back onto the master wp list, letting us pass them - * on through in the modified order. - */ - for (i = 0; i < wc; i++) { - waypoint * wp = comp[i]; - - xfree(wp->extra_data); - wp->extra_data = NULL; - - if (maxctarg && i >= maxct) { - continue; - } - if (routename) { - route_add_wpt(rte_head, wp); - } else { - waypt_add(wp); - } - } - - xfree(comp); + queue * elem, * tmp; + waypoint * waypointp; + double dist; + waypoint ** comp; + int i, wc; + queue temp_head; + route_head *rte_head = NULL; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + extra_data *ed; + + waypointp = (waypoint *)elem; + dist = gc_distance(waypointp->latitude, + waypointp->longitude, + home_pos->latitude, + home_pos->longitude); + + /* convert radians to float point statute miles */ + dist = radtomiles(dist); + + if ((dist >= pos_dist) == (exclopt == NULL)) { + waypt_del(waypointp); + waypt_free(waypointp); + continue; + } + + ed = (extra_data *) xcalloc(1, sizeof(*ed)); + ed->distance = dist; + waypointp->extra_data = ed; + } + + wc = waypt_count(); + QUEUE_INIT(&temp_head); + + comp = (waypoint **) xcalloc(wc, sizeof(*comp)); + + i = 0; + + /* + * Create an array of remaining waypoints, popping them off the + * master queue as we go. This gives us something reasonable + * for qsort. + */ + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wp = (waypoint *) elem; + comp[i] = wp; + waypt_del(wp); + i++; + } + + if (!nosort) { + qsort(comp, wc, sizeof(waypoint *), dist_comp); + } + + if (routename) { + rte_head = route_head_alloc(); + rte_head->rte_name = xstrdup(routename); + route_add_head(rte_head); + } + + /* + * The comp array is now sorted by distance. As we run through it, + * we push them back onto the master wp list, letting us pass them + * on through in the modified order. + */ + for (i = 0; i < wc; i++) { + waypoint * wp = comp[i]; + + xfree(wp->extra_data); + wp->extra_data = NULL; + + if (maxctarg && i >= maxct) { + continue; + } + if (routename) { + route_add_wpt(rte_head, wp); + } else { + waypt_add(wp); + } + } + + xfree(comp); } void -radius_init(const char *args) { - char *fm; +radius_init(const char *args) +{ + char *fm; - pos_dist = 0; + pos_dist = 0; - if (distopt) { - pos_dist = strtod(distopt, &fm); + if (distopt) { + pos_dist = strtod(distopt, &fm); - if ((*fm == 'k') || (*fm == 'K')) { - /* distance is kilometers, convert to feet */ - pos_dist *= .6214; - } - } + if ((*fm == 'k') || (*fm == 'K')) { + /* distance is kilometers, convert to feet */ + pos_dist *= .6214; + } + } - if (maxctarg) { - maxct = atoi(maxctarg); - } else { - maxct = 0; - } + if (maxctarg) { + maxct = atoi(maxctarg); + } else { + maxct = 0; + } - home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); + home_pos = (waypoint *) xcalloc(sizeof(*home_pos), 1); - if (latopt) - home_pos->latitude = atof(latopt); - if (lonopt) - home_pos->longitude = atof(lonopt); + if (latopt) { + home_pos->latitude = atof(latopt); + } + if (lonopt) { + home_pos->longitude = atof(lonopt); + } } void -radius_deinit(void) { - if (home_pos) - xfree(home_pos); +radius_deinit(void) +{ + if (home_pos) { + xfree(home_pos); + } } filter_vecs_t radius_vecs = { - radius_init, - radius_process, - radius_deinit, - NULL, - radius_args + radius_init, + radius_process, + radius_deinit, + NULL, + radius_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/random.c b/gpsbabel/random.c index 199aa5b4c..add054f37 100644 --- a/gpsbabel/random.c +++ b/gpsbabel/random.c @@ -1,6 +1,6 @@ /* random - GPS data generator - + Copyright (C) 2007 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -27,25 +27,29 @@ static char *opt_points, *opt_seed; -static arglist_t random_args[] = { - { "points", &opt_points, "Generate # points", NULL, - ARGTYPE_INT, "1", NULL }, - { "seed", &opt_seed, "Starting seed of the internal number generator", NULL, - ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +static arglist_t random_args[] = { + { + "points", &opt_points, "Generate # points", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "seed", &opt_seed, "Starting seed of the internal number generator", NULL, + ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; static double rand_dbl(const double max) { - return max * rand() / (((double)RAND_MAX) + 1); + return max * rand() / (((double)RAND_MAX) + 1); } static int rand_int(const int max) { - return (int)((double)max * rand() / (((double)RAND_MAX) + 1)); + return (int)((double)max * rand() / (((double)RAND_MAX) + 1)); } /* rand_str always returns a valid string with len >= 0 */ @@ -53,32 +57,33 @@ rand_int(const int max) static char * rand_str(const int maxlen, const char *fmt) { - char *res; - int i, len; - - len = rand_int(maxlen) + 1; - - res = xmalloc(len + 1); - res[len] = '\0'; - - for (i = 0; i < len; i++) { - int c = rand_int(26 + 26 + 10); - if ( c < 26 ) - c += 'a'; - else if (c < 52) - c = (c - 26) + 'A'; - else - c = (c - 52) + '0'; - res[i] = c; - } - if (fmt) { - char *tmp; - xasprintf(&tmp, fmt, res); - xfree(res); - return tmp; - } - else - return res; + char *res; + int i, len; + + len = rand_int(maxlen) + 1; + + res = xmalloc(len + 1); + res[len] = '\0'; + + for (i = 0; i < len; i++) { + int c = rand_int(26 + 26 + 10); + if (c < 26) { + c += 'a'; + } else if (c < 52) { + c = (c - 26) + 'A'; + } else { + c = (c - 52) + '0'; + } + res[i] = c; + } + if (fmt) { + char *tmp; + xasprintf(&tmp, fmt, res); + xfree(res); + return tmp; + } else { + return res; + } } static void @@ -91,118 +96,154 @@ random_rd_deinit(void) { } -static void +static void random_read(void) { #define RND(a) (rand_int(a) > 0) - int i, points; - route_head *head; - waypoint *prev = NULL; - time_t time = gpsbabel_time; - - if (opt_seed) - srand(atoi(opt_seed)); - else - srand(gpsbabel_now); - - - points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1; - if (doing_trks || doing_rtes) { - head = route_head_alloc(); - if (doing_trks) { - head->rte_name = rand_str(8, "Trk_%s"); - track_add_head(head); - } - else { - head->rte_name = rand_str(8, "Rte_%s"); - route_add_head(head); - } - head->rte_desc = rand_str(16, NULL); - } - else head = NULL; - - for (i = 0; i < points; i++) { - - waypoint *wpt; - garmin_fs_t *gmsd; - - wpt = waypt_new(); - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - - do { - wpt->shortname = rand_str(8, "Wpt_%s"); - } while (wpt->shortname == NULL); - - wpt->latitude = rand_dbl(180) - 90; - wpt->longitude = rand_dbl(360) - 180; - - /* !!! "if RND(3) ..." produces some leaks in generated data !!! */ - - if RND(3) wpt->altitude = rand_int(1000) / 10; - if RND(3) WAYPT_SET(wpt, temperature, rand_int(320) / 10.0); - if RND(3) WAYPT_SET(wpt, proximity, rand_int(10000) / 10.0); - if RND(3) WAYPT_SET(wpt, depth, rand_int(10000) / 10.0); - - wpt->creation_time = time; - if RND(3) wpt->microseconds = rand_int(1000) * 1000; - time += rand_int(10) + 1; - - if (doing_trks) { - if (i > 0) { - wpt->latitude = prev->latitude + (rand_dbl(1) / 1000); - wpt->longitude = prev->longitude + (rand_dbl(1) / 1000); - WAYPT_SET(wpt, course, waypt_course(prev, wpt)); - WAYPT_SET(wpt, speed, waypt_speed(prev, wpt)); - } - wpt->sat = rand_int(12 + 1); - wpt->hdop = (rand_int(500)) / 10.0; - wpt->vdop = (rand_int(500)) / 10.0; - wpt->pdop = (rand_int(500)) / 10.0; - wpt->fix = rand_int(6) - 1; - if RND(3) wpt->cadence = rand_int(255); - if RND(3) wpt->heartrate = rand_int(255); - } - else { - if (doing_rtes && (i > 0)) { - wpt->latitude = prev->latitude + (rand_dbl(1) / 100); - wpt->longitude = prev->longitude + (rand_dbl(1) / 100); - } - if RND(3) wpt->description = rand_str(16, "Des_%s"); - if RND(3) wpt->notes = rand_str(16, "Nts_%s"); - if RND(3) GMSD_SET(addr, rand_str(8, "Adr_%s")); - if RND(3) GMSD_SET(city, rand_str(8, "Cty_%s")); - if RND(3) GMSD_SET(facility, rand_str(8, "Fac_%s")); - if RND(3) GMSD_SET(country, rand_str(8, "Ctr_%s")); - if RND(3) GMSD_SET(state, rand_str(8, "Sta_%s")); - if RND(3) GMSD_SET(phone_nr, rand_str(8, "Pnr_%s")); - if RND(3) GMSD_SET(postal_code, rand_str(8, "Pcd_%s")); - } - - if (doing_trks) track_add_wpt(head, wpt); - else if (doing_rtes) route_add_wpt(head, wpt); - else waypt_add(wpt); - - prev = wpt; - } + int i, points; + route_head *head; + waypoint *prev = NULL; + time_t time = gpsbabel_time; + + if (opt_seed) { + srand(atoi(opt_seed)); + } else { + srand(gpsbabel_now); + } + + + points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1; + if (doing_trks || doing_rtes) { + head = route_head_alloc(); + if (doing_trks) { + head->rte_name = rand_str(8, "Trk_%s"); + track_add_head(head); + } else { + head->rte_name = rand_str(8, "Rte_%s"); + route_add_head(head); + } + head->rte_desc = rand_str(16, NULL); + } else { + head = NULL; + } + + for (i = 0; i < points; i++) { + + waypoint *wpt; + garmin_fs_t *gmsd; + + wpt = waypt_new(); + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + + do { + wpt->shortname = rand_str(8, "Wpt_%s"); + } while (wpt->shortname == NULL); + + wpt->latitude = rand_dbl(180) - 90; + wpt->longitude = rand_dbl(360) - 180; + + /* !!! "if RND(3) ..." produces some leaks in generated data !!! */ + + if RND(3) { + wpt->altitude = rand_int(1000) / 10; + } + if RND(3) { + WAYPT_SET(wpt, temperature, rand_int(320) / 10.0); + } + if RND(3) { + WAYPT_SET(wpt, proximity, rand_int(10000) / 10.0); + } + if RND(3) { + WAYPT_SET(wpt, depth, rand_int(10000) / 10.0); + } + + wpt->creation_time = time; + if RND(3) { + wpt->microseconds = rand_int(1000) * 1000; + } + time += rand_int(10) + 1; + + if (doing_trks) { + if (i > 0) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 1000); + wpt->longitude = prev->longitude + (rand_dbl(1) / 1000); + WAYPT_SET(wpt, course, waypt_course(prev, wpt)); + WAYPT_SET(wpt, speed, waypt_speed(prev, wpt)); + } + wpt->sat = rand_int(12 + 1); + wpt->hdop = (rand_int(500)) / 10.0; + wpt->vdop = (rand_int(500)) / 10.0; + wpt->pdop = (rand_int(500)) / 10.0; + wpt->fix = rand_int(6) - 1; + if RND(3) { + wpt->cadence = rand_int(255); + } + if RND(3) { + wpt->heartrate = rand_int(255); + } + } else { + if (doing_rtes && (i > 0)) { + wpt->latitude = prev->latitude + (rand_dbl(1) / 100); + wpt->longitude = prev->longitude + (rand_dbl(1) / 100); + } + if RND(3) { + wpt->description = rand_str(16, "Des_%s"); + } + if RND(3) { + wpt->notes = rand_str(16, "Nts_%s"); + } + if RND(3) { + GMSD_SET(addr, rand_str(8, "Adr_%s")); + } + if RND(3) { + GMSD_SET(city, rand_str(8, "Cty_%s")); + } + if RND(3) { + GMSD_SET(facility, rand_str(8, "Fac_%s")); + } + if RND(3) { + GMSD_SET(country, rand_str(8, "Ctr_%s")); + } + if RND(3) { + GMSD_SET(state, rand_str(8, "Sta_%s")); + } + if RND(3) { + GMSD_SET(phone_nr, rand_str(8, "Pnr_%s")); + } + if RND(3) { + GMSD_SET(postal_code, rand_str(8, "Pcd_%s")); + } + } + + if (doing_trks) { + track_add_wpt(head, wpt); + } else if (doing_rtes) { + route_add_wpt(head, wpt); + } else { + waypt_add(wpt); + } + + prev = wpt; + } } ff_vecs_t random_vecs = { - ff_type_internal, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_read /* routes */ - }, - random_rd_init, - NULL, /* wr_init */ - random_rd_deinit, - NULL, /* wr_deinit */ - random_read, - NULL, /* write */ - NULL, /* exit */ - random_args, - CET_CHARSET_ASCII, 1 /* fixed */ + ff_type_internal, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_read /* routes */ + }, + random_rd_init, + NULL, /* wr_init */ + random_rd_deinit, + NULL, /* wr_deinit */ + random_read, + NULL, /* write */ + NULL, /* exit */ + random_args, + CET_CHARSET_ASCII, 1 /* fixed */ }; diff --git a/gpsbabel/raymarine.c b/gpsbabel/raymarine.c index d9d4aa54d..c24e17347 100644 --- a/gpsbabel/raymarine.c +++ b/gpsbabel/raymarine.c @@ -1,25 +1,25 @@ - /* +/* - Support for Raymarine Waypoint File (.rwf). + Support for Raymarine Waypoint File (.rwf). - Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2006,2007 Olaf Klein, o.b.klein@gpsbabel.org - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ -/* +/* Known format limits: Waypoint name: max. 16 characters @@ -28,9 +28,9 @@ ???: the character set may be only a subset of std. ASCII History: - + 2006/10/30: Initial release (not yet in GPSBabel source tree) - 2006/11/08: + 2006/11/08: 2007/03/17: Remove GUIDs from writer (not really valid) Fix "PredictedTwa" output Initialize location with "My Waypoints" @@ -64,10 +64,9 @@ static char *opt_location; #define MYNAME "raymarine" static -arglist_t raymarine_args[] = -{ - { "location", &opt_location, "Default location", "My Waypoints", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR +arglist_t raymarine_args[] = { + { "location", &opt_location, "Default location", "My Waypoints", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; /* from csv_util.c: convert excel time (days since 1900) to time_t and back again */ @@ -80,61 +79,61 @@ arglist_t raymarine_args[] = /* Bitmaps */ typedef struct { - const char *name; - const char *mps_name; + const char *name; + const char *mps_name; } raymarine_symbol_mapping_t; static raymarine_symbol_mapping_t raymarine_symbols[] = { - { /* 0 */ "Unknown Symbol 0" }, - { /* 1 */ "Unknown Symbol 1" }, - { /* 2 */ "Unknown Symbol 2" }, - { /* 3 */ "Red Square" }, - { /* 4 */ "Big Fish" }, - { /* 5 */ "Anchor" }, - { /* 6 */ "Smiley", "Contact, Smiley" }, - { /* 7 */ "Sad" }, - { /* 8 */ "Red Button", "Navaid, Red" }, - { /* 9 */ "Sailfish" }, - { /* 10 */ "Danger", "Skull and Crossbones" }, - { /* 11 */ "Attention" }, - { /* 12 */ "Black Square" }, - { /* 13 */ "Intl. Dive Flag", "Diver Down Flag 2" }, - { /* 14 */ "Vessel", "Marina" }, - { /* 15 */ "Lobster" }, - { /* 16 */ "Buoy", "Buoy, White" }, - { /* 17 */ "Exclamation" }, - { /* 18 */ "Red X" }, - { /* 19 */ "Check Mark" }, - { /* 20 */ "Black Plus" }, - { /* 21 */ "Black Cross" }, - { /* 22 */ "MOB" }, - { /* 23 */ "Billfish" }, - { /* 24 */ "Bottom Mark" }, - { /* 25 */ "Circle", "Circle, Red" }, - { /* 26 */ "Diamond", "Block, Red" }, - { /* 27 */ "Diamond Quarters", "Diamond, Red" }, - { /* 28 */ "U.S. Dive Flag", "Diver Down Flag 1" }, - { /* 29 */ "Dolphin" }, - { /* 30 */ "Few Fish" }, - { /* 31 */ "Multiple Fish" }, - { /* 32 */ "Many Fish" }, - { /* 33 */ "Single Fish" }, - { /* 34 */ "Small Fish" }, - { /* 35 */ "Marker" }, - { /* 36 */ "Cocktails", "Bar" }, - { /* 37 */ "Red Box Marker" }, - { /* 38 */ "Reef" }, - { /* 39 */ "Rocks" }, - { /* 40 */ "Fish School" }, - { /* 41 */ "Seaweed", "Weed Bed" }, - { /* 42 */ "Shark" }, - { /* 43 */ "Sportfisher" }, - { /* 44 */ "Swimmer", "Swimming Area" }, - { /* 45 */ "Top Mark" }, - { /* 46 */ "Trawler" }, - { /* 47 */ "Tree" }, - { /* 48 */ "Triangle", "Triangle, Red" }, - { /* 49 */ "Wreck", "Shipwreck" } + { /* 0 */ "Unknown Symbol 0" }, + { /* 1 */ "Unknown Symbol 1" }, + { /* 2 */ "Unknown Symbol 2" }, + { /* 3 */ "Red Square" }, + { /* 4 */ "Big Fish" }, + { /* 5 */ "Anchor" }, + { /* 6 */ "Smiley", "Contact, Smiley" }, + { /* 7 */ "Sad" }, + { /* 8 */ "Red Button", "Navaid, Red" }, + { /* 9 */ "Sailfish" }, + { /* 10 */ "Danger", "Skull and Crossbones" }, + { /* 11 */ "Attention" }, + { /* 12 */ "Black Square" }, + { /* 13 */ "Intl. Dive Flag", "Diver Down Flag 2" }, + { /* 14 */ "Vessel", "Marina" }, + { /* 15 */ "Lobster" }, + { /* 16 */ "Buoy", "Buoy, White" }, + { /* 17 */ "Exclamation" }, + { /* 18 */ "Red X" }, + { /* 19 */ "Check Mark" }, + { /* 20 */ "Black Plus" }, + { /* 21 */ "Black Cross" }, + { /* 22 */ "MOB" }, + { /* 23 */ "Billfish" }, + { /* 24 */ "Bottom Mark" }, + { /* 25 */ "Circle", "Circle, Red" }, + { /* 26 */ "Diamond", "Block, Red" }, + { /* 27 */ "Diamond Quarters", "Diamond, Red" }, + { /* 28 */ "U.S. Dive Flag", "Diver Down Flag 1" }, + { /* 29 */ "Dolphin" }, + { /* 30 */ "Few Fish" }, + { /* 31 */ "Multiple Fish" }, + { /* 32 */ "Many Fish" }, + { /* 33 */ "Single Fish" }, + { /* 34 */ "Small Fish" }, + { /* 35 */ "Marker" }, + { /* 36 */ "Cocktails", "Bar" }, + { /* 37 */ "Red Box Marker" }, + { /* 38 */ "Reef" }, + { /* 39 */ "Rocks" }, + { /* 40 */ "Fish School" }, + { /* 41 */ "Seaweed", "Weed Bed" }, + { /* 42 */ "Shark" }, + { /* 43 */ "Sportfisher" }, + { /* 44 */ "Swimmer", "Swimming Area" }, + { /* 45 */ "Top Mark" }, + { /* 46 */ "Trawler" }, + { /* 47 */ "Tree" }, + { /* 48 */ "Triangle", "Triangle, Red" }, + { /* 49 */ "Wreck", "Shipwreck" } }; #define RAYMARINE_SYMBOL_CT sizeof(raymarine_symbols) / sizeof(raymarine_symbol_mapping_t) @@ -143,20 +142,24 @@ static raymarine_symbol_mapping_t raymarine_symbols[] = { static int find_symbol_num(const char *descr) { - if ((descr != NULL) && (*descr)) { - - int i; - raymarine_symbol_mapping_t *a; - - a = &raymarine_symbols[0]; - - for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) { - if (case_ignore_strcmp(descr, a->name) == 0) return i; - if (a->mps_name && (case_ignore_strcmp(descr, a->mps_name) == 0)) return i; - } - } - - return RAYMARINE_STD_SYMBOL; + if ((descr != NULL) && (*descr)) { + + int i; + raymarine_symbol_mapping_t *a; + + a = &raymarine_symbols[0]; + + for (i = 0; i < RAYMARINE_SYMBOL_CT; i++, a++) { + if (case_ignore_strcmp(descr, a->name) == 0) { + return i; + } + if (a->mps_name && (case_ignore_strcmp(descr, a->mps_name) == 0)) { + return i; + } + } + } + + return RAYMARINE_STD_SYMBOL; } /* ============================================= */ @@ -166,86 +169,103 @@ find_symbol_num(const char *descr) static void raymarine_rd_init(const char *fname) { - fin = inifile_init(fname, MYNAME); - if (fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + fin = inifile_init(fname, MYNAME); + if (fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } } static void raymarine_rd_done(void) { - inifile_done(fin); + inifile_done(fin); } static void raymarine_read(void) { - waypoint *wpt; - int ix, rx; - - /* Read all waypoints */ - - for (ix = 0; ix < 0x3FFF; ix++) { - char sect[10]; - char *str, *name, *lat, *lon; - - /* built section identifier */ - snprintf(sect, sizeof(sect), "Wp%d", ix); - - /* try to read our most expected values */ - if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; - if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) break; - if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) break; - - wpt = waypt_new(); - wpt->shortname = xstrdup(name); - wpt->latitude = atof(lat); - wpt->longitude = atof(lon); - waypt_add(wpt); - - /* try to read optional values */ - if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) wpt->notes = xstrdup(str); - if (((str = inifile_readstr(fin, sect, "Time"))) && *str) wpt->creation_time = EXCEL_TO_TIMET(atof(str)); - if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) { - int symbol = atoi(str); - - if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT)) - symbol = RAYMARINE_STD_SYMBOL; - wpt->icon_descr = raymarine_symbols[symbol].name; - } - } - - /* Read all routes */ - - for (rx = 0; rx < 0x3FFF; rx++) { - char sect[10]; - char *name; - route_head *rte; - int wx; - - snprintf(sect, sizeof(sect), "Rt%d", rx); - if (NULL == (name = inifile_readstr(fin, sect, "Name"))) break; - - rte = route_head_alloc(); - rte->rte_name = xstrdup(name); - route_add_head(rte); - - for (wx = 0; wx < 0x3FFF; wx++) { - char buff[32]; - char *str; - waypoint * wpt; - - snprintf(buff, sizeof(buff), "Mk%d", wx); - str = inifile_readstr(fin, sect, buff); - if ((str == NULL) || (*str == '\0')) break; - - wpt = find_waypt_by_name(str); - if (wpt == NULL) - fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n", - str, rte->rte_name); - - route_add_wpt(rte, waypt_dupe(wpt)); - } - } + waypoint *wpt; + int ix, rx; + + /* Read all waypoints */ + + for (ix = 0; ix < 0x3FFF; ix++) { + char sect[10]; + char *str, *name, *lat, *lon; + + /* built section identifier */ + snprintf(sect, sizeof(sect), "Wp%d", ix); + + /* try to read our most expected values */ + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) { + break; + } + if (NULL == (lat = inifile_readstr(fin, sect, "Lat"))) { + break; + } + if (NULL == (lon = inifile_readstr(fin, sect, "Long"))) { + break; + } + + wpt = waypt_new(); + wpt->shortname = xstrdup(name); + wpt->latitude = atof(lat); + wpt->longitude = atof(lon); + waypt_add(wpt); + + /* try to read optional values */ + if (((str = inifile_readstr(fin, sect, "Notes"))) && *str) { + wpt->notes = xstrdup(str); + } + if (((str = inifile_readstr(fin, sect, "Time"))) && *str) { + wpt->creation_time = EXCEL_TO_TIMET(atof(str)); + } + if (((str = inifile_readstr(fin, sect, "Bmp"))) && *str) { + int symbol = atoi(str); + + if ((symbol < 3) && (symbol >= RAYMARINE_SYMBOL_CT)) { + symbol = RAYMARINE_STD_SYMBOL; + } + wpt->icon_descr = raymarine_symbols[symbol].name; + } + } + + /* Read all routes */ + + for (rx = 0; rx < 0x3FFF; rx++) { + char sect[10]; + char *name; + route_head *rte; + int wx; + + snprintf(sect, sizeof(sect), "Rt%d", rx); + if (NULL == (name = inifile_readstr(fin, sect, "Name"))) { + break; + } + + rte = route_head_alloc(); + rte->rte_name = xstrdup(name); + route_add_head(rte); + + for (wx = 0; wx < 0x3FFF; wx++) { + char buff[32]; + char *str; + waypoint * wpt; + + snprintf(buff, sizeof(buff), "Mk%d", wx); + str = inifile_readstr(fin, sect, buff); + if ((str == NULL) || (*str == '\0')) { + break; + } + + wpt = find_waypt_by_name(str); + if (wpt == NULL) + fatal(MYNAME ": No associated waypoint for route point %s (Route %s)!\n", + str, rte->rte_name); + + route_add_wpt(rte, waypt_dupe(wpt)); + } + } } /* ============================================= */ @@ -257,234 +277,241 @@ raymarine_read(void) static char same_points(const waypoint *A, const waypoint *B) { - return ( /* !!! We are case-sensitive !!! */ - (strcmp(A->shortname, B->shortname) == 0) && - (A->latitude == B->latitude) && - (A->longitude == B->longitude)); + return ( /* !!! We are case-sensitive !!! */ + (strcmp(A->shortname, B->shortname) == 0) && + (A->latitude == B->latitude) && + (A->longitude == B->longitude)); } static void register_waypt(const waypoint *ref, const char is_rtept) { - int i; - waypoint *wpt = (waypoint *) ref; - - for (i = 0; i < waypt_table_ct; i++) { - waypoint *cmp = waypt_table[i]; - - if (same_points(wpt, cmp)) { - wpt->extra_data = cmp->extra_data; - return; - } - } - - if (waypt_table_ct >= waypt_table_sz) { - waypt_table_sz += 32; - if (waypt_table) - waypt_table = (void *) xrealloc(waypt_table, waypt_table_sz * sizeof(wpt)); - else - waypt_table = (void *) xmalloc(waypt_table_sz * sizeof(wpt)); - } - - wpt->extra_data = (void *)mkshort(hshort_wpt, wpt->shortname); - - waypt_table[waypt_table_ct] = (waypoint *)wpt; - waypt_table_ct++; + int i; + waypoint *wpt = (waypoint *) ref; + + for (i = 0; i < waypt_table_ct; i++) { + waypoint *cmp = waypt_table[i]; + + if (same_points(wpt, cmp)) { + wpt->extra_data = cmp->extra_data; + return; + } + } + + if (waypt_table_ct >= waypt_table_sz) { + waypt_table_sz += 32; + if (waypt_table) { + waypt_table = (void *) xrealloc(waypt_table, waypt_table_sz * sizeof(wpt)); + } else { + waypt_table = (void *) xmalloc(waypt_table_sz * sizeof(wpt)); + } + } + + wpt->extra_data = (void *)mkshort(hshort_wpt, wpt->shortname); + + waypt_table[waypt_table_ct] = (waypoint *)wpt; + waypt_table_ct++; } static void enum_waypt_cb(const waypoint *wpt) { - register_waypt((waypoint *) wpt, 0); + register_waypt((waypoint *) wpt, 0); } static void enum_rtept_cb(const waypoint *wpt) { - register_waypt((waypoint *) wpt, 1); + register_waypt((waypoint *) wpt, 1); } -static int +static int qsort_cb(const void *a, const void *b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; - - return strcmp(wa->shortname, wb->shortname); + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return strcmp(wa->shortname, wb->shortname); } static void write_waypoint(gbfile *fout, const waypoint *wpt, const int waypt_no, const char *location) { - char *notes; - char *name; - double time; - - notes = wpt->notes; - if (notes == NULL) { - notes = wpt->description; - if (notes == NULL) notes = ""; - } - notes = csv_stringclean(notes, LINE_FEED); - time = (wpt->creation_time > 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time); - name = (char *)wpt->extra_data; - - gbfprintf(fout, "[Wp%d]" LINE_FEED - "Loc=%s" LINE_FEED - "Name=%s" LINE_FEED - "Lat=%.15f" LINE_FEED - "Long=%.15f" LINE_FEED, - waypt_no, location, name, wpt->latitude, wpt->longitude - ); - gbfprintf(fout, "Rng=%.15f" LINE_FEED - "Bear=%.15f" LINE_FEED - "Bmp=%d" LINE_FEED - "Fixed=1" LINE_FEED - "Locked=0" LINE_FEED - "Notes=%s" LINE_FEED, - 0.0, 0.0, - find_symbol_num(wpt->icon_descr), - notes - ); - gbfprintf(fout, "Rel=" LINE_FEED - "RelSet=0" LINE_FEED - "RcCount=0" LINE_FEED - "RcRadius=%.15f" LINE_FEED - "Show=1" LINE_FEED - "RcShow=0" LINE_FEED - "SeaTemp=%.15f" LINE_FEED - "Depth=%.15f" LINE_FEED - "Time=%.10f00000" LINE_FEED, - 0.0, -32678.0, 65535.0, time - ); - xfree(notes); + char *notes; + char *name; + double time; + + notes = wpt->notes; + if (notes == NULL) { + notes = wpt->description; + if (notes == NULL) { + notes = ""; + } + } + notes = csv_stringclean(notes, LINE_FEED); + time = (wpt->creation_time > 0) ? TIMET_TO_EXCEL(wpt->creation_time) : TIMET_TO_EXCEL(gpsbabel_time); + name = (char *)wpt->extra_data; + + gbfprintf(fout, "[Wp%d]" LINE_FEED + "Loc=%s" LINE_FEED + "Name=%s" LINE_FEED + "Lat=%.15f" LINE_FEED + "Long=%.15f" LINE_FEED, + waypt_no, location, name, wpt->latitude, wpt->longitude + ); + gbfprintf(fout, "Rng=%.15f" LINE_FEED + "Bear=%.15f" LINE_FEED + "Bmp=%d" LINE_FEED + "Fixed=1" LINE_FEED + "Locked=0" LINE_FEED + "Notes=%s" LINE_FEED, + 0.0, 0.0, + find_symbol_num(wpt->icon_descr), + notes + ); + gbfprintf(fout, "Rel=" LINE_FEED + "RelSet=0" LINE_FEED + "RcCount=0" LINE_FEED + "RcRadius=%.15f" LINE_FEED + "Show=1" LINE_FEED + "RcShow=0" LINE_FEED + "SeaTemp=%.15f" LINE_FEED + "Depth=%.15f" LINE_FEED + "Time=%.10f00000" LINE_FEED, + 0.0, -32678.0, 65535.0, time + ); + xfree(notes); } static void write_route_head_cb(const route_head *rte) { - char buff[32]; - char *name; - - name = rte->rte_name; - if ((name == NULL) || (*name == '\0')) { - snprintf(buff, sizeof(buff), "Route%d", rte_index); - name = buff; - } - name = mkshort(hshort_rte, name); - gbfprintf(fout, "[Rt%d]" LINE_FEED - "Name=%s" LINE_FEED - "Visible=1" LINE_FEED, - rte_index, - name - ); - xfree(name); - - rte_index++; - rte_wpt_index = 0; + char buff[32]; + char *name; + + name = rte->rte_name; + if ((name == NULL) || (*name == '\0')) { + snprintf(buff, sizeof(buff), "Route%d", rte_index); + name = buff; + } + name = mkshort(hshort_rte, name); + gbfprintf(fout, "[Rt%d]" LINE_FEED + "Name=%s" LINE_FEED + "Visible=1" LINE_FEED, + rte_index, + name + ); + xfree(name); + + rte_index++; + rte_wpt_index = 0; } static void write_route_wpt_cb(const waypoint *wpt) { - int i; - static const char *items[] = { - "Cog", - "Eta", - "Length", - "PredictedDrift", - "PredictedSet", - "PredictedSog", - "PredictedTime", - "PredictedTwa", - "PredictedTwd", - "PredictedTws" }; - - gbfprintf(fout, "Mk%d=%s" LINE_FEED, rte_wpt_index, (char *)wpt->extra_data); - for (i = 0; i < sizeof(items) / sizeof(char *); i++) - gbfprintf(fout, "%s%d=%.15f" LINE_FEED, items[i], rte_wpt_index, 0.0); - - rte_wpt_index++; - return; + int i; + static const char *items[] = { + "Cog", + "Eta", + "Length", + "PredictedDrift", + "PredictedSet", + "PredictedSog", + "PredictedTime", + "PredictedTwa", + "PredictedTwd", + "PredictedTws" + }; + + gbfprintf(fout, "Mk%d=%s" LINE_FEED, rte_wpt_index, (char *)wpt->extra_data); + for (i = 0; i < sizeof(items) / sizeof(char *); i++) { + gbfprintf(fout, "%s%d=%.15f" LINE_FEED, items[i], rte_wpt_index, 0.0); + } + + rte_wpt_index++; + return; } static void enum_route_hdr_cb(const route_head *rte) { - is_fatal(rte->rte_waypt_ct > 50, - MYNAME ": Routes with more than 50 points are not supported by Waymarine!"); + is_fatal(rte->rte_waypt_ct > 50, + MYNAME ": Routes with more than 50 points are not supported by Waymarine!"); } static short_handle raymarine_new_short_handle(void) { - short_handle res; - - res = mkshort_new_handle(); - - setshort_length(res, 16); - setshort_badchars(res, ","); - setshort_mustupper(res, 0); - setshort_mustuniq(res, 1); - setshort_whitespace_ok(res, 1); - setshort_repeating_whitespace_ok(res, 1); - - return res; + short_handle res; + + res = mkshort_new_handle(); + + setshort_length(res, 16); + setshort_badchars(res, ","); + setshort_mustupper(res, 0); + setshort_mustuniq(res, 1); + setshort_whitespace_ok(res, 1); + setshort_repeating_whitespace_ok(res, 1); + + return res; } static void raymarine_wr_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); + fout = gbfopen(fname, "wb", MYNAME); - hshort_wpt = raymarine_new_short_handle(); - hshort_rte = raymarine_new_short_handle(); + hshort_wpt = raymarine_new_short_handle(); + hshort_rte = raymarine_new_short_handle(); } static void raymarine_wr_done(void) { - mkshort_del_handle(&hshort_wpt); - mkshort_del_handle(&hshort_rte); + mkshort_del_handle(&hshort_wpt); + mkshort_del_handle(&hshort_rte); - gbfclose(fout); + gbfclose(fout); } static void raymarine_write(void) { - int i; - waypoint *wpt; - - waypt_table_sz = 0; - waypt_table_ct = 0; - waypt_table = NULL; - - /* enumerate all possible waypoints */ - waypt_disp_all(enum_waypt_cb); - route_disp_all(enum_route_hdr_cb, NULL, enum_rtept_cb); - - if (waypt_table_ct == 0) return; - - qsort(waypt_table, waypt_table_ct, sizeof(*waypt_table), qsort_cb); - - /* write out waypoint summary */ - for (i = 0; i < waypt_table_ct; i++) { - waypoint *wpt = waypt_table[i]; - write_waypoint(fout, wpt, i, opt_location); - } - - /* write out all routes with their waypoints */ - rte_index = 0; - route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb); - - /* release local used data */ - for (i = 0; i < waypt_table_ct; i++) { - wpt = waypt_table[i]; - xfree(wpt->extra_data); - wpt->extra_data = NULL; - } - xfree(waypt_table); + int i; + waypoint *wpt; + + waypt_table_sz = 0; + waypt_table_ct = 0; + waypt_table = NULL; + + /* enumerate all possible waypoints */ + waypt_disp_all(enum_waypt_cb); + route_disp_all(enum_route_hdr_cb, NULL, enum_rtept_cb); + + if (waypt_table_ct == 0) { + return; + } + + qsort(waypt_table, waypt_table_ct, sizeof(*waypt_table), qsort_cb); + + /* write out waypoint summary */ + for (i = 0; i < waypt_table_ct; i++) { + waypoint *wpt = waypt_table[i]; + write_waypoint(fout, wpt, i, opt_location); + } + + /* write out all routes with their waypoints */ + rte_index = 0; + route_disp_all(write_route_head_cb, NULL, write_route_wpt_cb); + + /* release local used data */ + for (i = 0; i < waypt_table_ct; i++) { + wpt = waypt_table[i]; + xfree(wpt->extra_data); + wpt->extra_data = NULL; + } + xfree(waypt_table); } /* ================================================== */ @@ -492,19 +519,19 @@ raymarine_write(void) /* ================================================== */ ff_vecs_t raymarine_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_read | ff_cap_write /* routes */, - }, - raymarine_rd_init, - raymarine_wr_init, - raymarine_rd_done, - raymarine_wr_done, - raymarine_read, - raymarine_write, - NULL, - raymarine_args, - CET_CHARSET_ASCII, 0 /* should we force this to 1 ? */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_read | ff_cap_write /* routes */, + }, + raymarine_rd_init, + raymarine_wr_init, + raymarine_rd_done, + raymarine_wr_done, + raymarine_read, + raymarine_write, + NULL, + raymarine_args, + CET_CHARSET_ASCII, 0 /* should we force this to 1 ? */ }; diff --git a/gpsbabel/reverse_route.c b/gpsbabel/reverse_route.c index c343d0d10..18bbe770a 100644 --- a/gpsbabel/reverse_route.c +++ b/gpsbabel/reverse_route.c @@ -27,45 +27,47 @@ static arglist_t reverse_route_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; -void -reverse_route_head( const route_head *rte ) +void +reverse_route_head(const route_head *rte) { - route_reverse(rte); + route_reverse(rte); } -void -reverse_route_process( void ) +void +reverse_route_process(void) { - track_disp_all( reverse_route_head, NULL, NULL ); - route_disp_all( reverse_route_head, NULL, NULL ); + track_disp_all(reverse_route_head, NULL, NULL); + route_disp_all(reverse_route_head, NULL, NULL); } void -reverse_route_init(const char *args) +reverse_route_init(const char *args) { - switch (global_opts.objective) { - case rtedata: break; - case trkdata: break; - default: - fatal(MYNAME ": This filter only works in track " - "or route (-t or -r) mode.\n"); - } + switch (global_opts.objective) { + case rtedata: + break; + case trkdata: + break; + default: + fatal(MYNAME ": This filter only works in track " + "or route (-t or -r) mode.\n"); + } } void -reverse_route_deinit(void) +reverse_route_deinit(void) { - /* do nothing */ + /* do nothing */ } filter_vecs_t reverse_route_vecs = { - reverse_route_init, - reverse_route_process, - reverse_route_deinit, - NULL, - reverse_route_args + reverse_route_init, + reverse_route_process, + reverse_route_deinit, + NULL, + reverse_route_args }; #endif diff --git a/gpsbabel/rgbcolors.c b/gpsbabel/rgbcolors.c index b89996157..9e523fc96 100644 --- a/gpsbabel/rgbcolors.c +++ b/gpsbabel/rgbcolors.c @@ -28,158 +28,158 @@ */ static const struct { - const char *cn; - unsigned char r; - unsigned char g; - unsigned char b; + const char *cn; + unsigned char r; + unsigned char g; + unsigned char b; } color_table[] = { - {"aliceblue", 240, 248, 255}, - {"antiquewhite", 250, 235, 215}, - {"aqua", 0, 255, 255}, - {"aquamarine", 127, 255, 212}, - {"azure", 240, 255, 255}, - {"beige", 245, 245, 220}, - {"bisque", 255, 228, 196}, - {"black", 0, 0, 0}, - {"blanchedalmond", 255, 235, 205}, - {"blue", 0, 0, 255}, - {"blueviolet", 138, 43, 226}, - {"brown", 165, 42, 42}, - {"burlywood", 222, 184, 135}, - {"cadetblue", 95, 158, 160}, - {"chartreuse", 127, 255, 0}, - {"chocolate", 210, 105, 30}, - {"coral", 255, 127, 80}, - {"cornflowerblue", 100, 149, 237}, - {"cornsilk", 255, 248, 220}, - {"crimson", 220, 20, 60}, - {"cyan", 0, 255, 255}, - {"darkblue", 0, 0, 139}, - {"darkcyan", 0, 139, 139}, - {"darkgoldenrod", 184, 134, 11}, - {"darkgray", 169, 169, 169}, - {"darkgreen", 0, 100, 0}, - {"darkgrey", 169, 169, 169}, - {"darkkhaki", 189, 183, 107}, - {"darkmagenta", 139, 0, 139}, - {"darkolivegreen", 85, 107, 47}, - {"darkorange", 255, 140, 0}, - {"darkorchid", 153, 50, 204}, - {"darkred", 139, 0, 0}, - {"darksalmon", 233, 150, 122}, - {"darkseagreen", 143, 188, 143}, - {"darkslateblue", 72, 61, 139}, - {"darkslategray", 47, 79, 79}, - {"darkslategrey", 47, 79, 79}, - {"darkturquoise", 0, 206, 209}, - {"darkviolet", 148, 0, 211}, - {"deeppink", 255, 20, 147}, - {"deepskyblue", 0, 191, 255}, - {"dimgray", 105, 105, 105}, - {"dimgrey", 105, 105, 105}, - {"dodgerblue", 30, 144, 255}, - {"firebrick", 178, 34, 34}, - {"floralwhite", 255, 250, 240}, - {"forestgreen", 34, 139, 34}, - {"fuchsia", 255, 0, 255}, - {"gainsboro", 220, 220, 220}, - {"ghostwhite", 248, 248, 255}, - {"gold", 255, 215, 0}, - {"goldenrod", 218, 165, 32}, - {"gray", 128, 128, 128}, - {"grey", 128, 128, 128}, - {"green", 0, 128, 0}, - {"greenyellow", 173, 255, 47}, - {"honeydew", 240, 255, 240}, - {"hotpink", 255, 105, 180}, - {"indianred", 205, 92, 92}, - {"indigo", 75, 0, 130}, - {"ivory", 255, 255, 240}, - {"khaki", 240, 230, 140}, - {"lavender", 230, 230, 250}, - {"lavenderblush", 255, 240, 245}, - {"lawngreen", 124, 252, 0}, - {"lemonchiffon", 255, 250, 205}, - {"lightblue", 173, 216, 230}, - {"lightcoral", 240, 128, 128}, - {"lightcyan", 224, 255, 255}, - {"lightgoldenrodyellow", 250, 250, 210}, - {"lightgray", 211, 211, 211}, - {"lightgreen", 144, 238, 144}, - {"lightgrey", 211, 211, 211}, - {"lightpink", 255, 182, 193}, - {"lightsalmon", 255, 160, 122}, - {"lightseagreen", 32, 178, 170}, - {"lightskyblue", 135, 206, 250}, - {"lightslategray", 119, 136, 153}, - {"lightslategrey", 119, 136, 153}, - {"lightsteelblue", 176, 196, 222}, - {"lightyellow", 255, 255, 224}, - {"lime", 0, 255, 0}, - {"limegreen", 50, 205, 50}, - {"linen", 250, 240, 230}, - {"magenta", 255, 0, 255}, - {"maroon", 128, 0, 0}, - {"mediumaquamarine", 102, 205, 170}, - {"mediumblue", 0, 0, 205}, - {"mediumorchid", 186, 85, 211}, - {"mediumpurple", 147, 112, 219}, - {"mediumseagreen", 60, 179, 113}, - {"mediumslateblue", 123, 104, 238}, - {"mediumspringgreen", 0, 250, 154}, - {"mediumturquoise", 72, 209, 204}, - {"mediumvioletred", 199, 21, 133}, - {"midnightblue", 25, 25, 112}, - {"mintcream", 245, 255, 250}, - {"mistyrose", 255, 228, 225}, - {"moccasin", 255, 228, 181}, - {"navajowhite", 255, 222, 173}, - {"navy", 0, 0, 128}, - {"oldlace", 253, 245, 230}, - {"olive", 128, 128, 0}, - {"olivedrab", 107, 142, 35}, - {"orange", 255, 165, 0}, - {"orangered", 255, 69, 0}, - {"orchid", 218, 112, 214}, - {"palegoldenrod", 238, 232, 170}, - {"palegreen", 152, 251, 152}, - {"paleturquoise", 175, 238, 238}, - {"palevioletred", 219, 112, 147}, - {"papayawhip", 255, 239, 213}, - {"peachpuff", 255, 218, 185}, - {"peru", 205, 133, 63}, - {"pink", 255, 192, 203}, - {"plum", 221, 160, 221}, - {"powderblue", 176, 224, 230}, - {"purple", 128, 0, 128}, - {"red", 255, 0, 0}, - {"rosybrown", 188, 143, 143}, - {"royalblue", 65, 105, 225}, - {"saddlebrown", 139, 69, 19}, - {"salmon", 250, 128, 114}, - {"sandybrown", 244, 164, 96}, - {"seagreen", 46, 139, 87}, - {"seashell", 255, 245, 238}, - {"sienna", 160, 82, 45}, - {"silver", 192, 192, 192}, - {"skyblue", 135, 206, 235}, - {"slateblue", 106, 90, 205}, - {"slategray", 112, 128, 144}, - {"slategrey", 112, 128, 144}, - {"snow", 255, 250, 250}, - {"springgreen", 0, 255, 127}, - {"steelblue", 70, 130, 180}, - {"tan", 210, 180, 140}, - {"teal", 0, 128, 128}, - {"thistle", 216, 191, 216}, - {"tomato", 255, 99, 71}, - {"turquoise", 64, 224, 208}, - {"violet", 238, 130, 238}, - {"wheat", 245, 222, 179}, - {"white", 255, 255, 255}, - {"whitesmoke", 245, 245, 245}, - {"yellow", 255, 255, 0}, - {"yellowgreen", 154, 205, 50}, + {"aliceblue", 240, 248, 255}, + {"antiquewhite", 250, 235, 215}, + {"aqua", 0, 255, 255}, + {"aquamarine", 127, 255, 212}, + {"azure", 240, 255, 255}, + {"beige", 245, 245, 220}, + {"bisque", 255, 228, 196}, + {"black", 0, 0, 0}, + {"blanchedalmond", 255, 235, 205}, + {"blue", 0, 0, 255}, + {"blueviolet", 138, 43, 226}, + {"brown", 165, 42, 42}, + {"burlywood", 222, 184, 135}, + {"cadetblue", 95, 158, 160}, + {"chartreuse", 127, 255, 0}, + {"chocolate", 210, 105, 30}, + {"coral", 255, 127, 80}, + {"cornflowerblue", 100, 149, 237}, + {"cornsilk", 255, 248, 220}, + {"crimson", 220, 20, 60}, + {"cyan", 0, 255, 255}, + {"darkblue", 0, 0, 139}, + {"darkcyan", 0, 139, 139}, + {"darkgoldenrod", 184, 134, 11}, + {"darkgray", 169, 169, 169}, + {"darkgreen", 0, 100, 0}, + {"darkgrey", 169, 169, 169}, + {"darkkhaki", 189, 183, 107}, + {"darkmagenta", 139, 0, 139}, + {"darkolivegreen", 85, 107, 47}, + {"darkorange", 255, 140, 0}, + {"darkorchid", 153, 50, 204}, + {"darkred", 139, 0, 0}, + {"darksalmon", 233, 150, 122}, + {"darkseagreen", 143, 188, 143}, + {"darkslateblue", 72, 61, 139}, + {"darkslategray", 47, 79, 79}, + {"darkslategrey", 47, 79, 79}, + {"darkturquoise", 0, 206, 209}, + {"darkviolet", 148, 0, 211}, + {"deeppink", 255, 20, 147}, + {"deepskyblue", 0, 191, 255}, + {"dimgray", 105, 105, 105}, + {"dimgrey", 105, 105, 105}, + {"dodgerblue", 30, 144, 255}, + {"firebrick", 178, 34, 34}, + {"floralwhite", 255, 250, 240}, + {"forestgreen", 34, 139, 34}, + {"fuchsia", 255, 0, 255}, + {"gainsboro", 220, 220, 220}, + {"ghostwhite", 248, 248, 255}, + {"gold", 255, 215, 0}, + {"goldenrod", 218, 165, 32}, + {"gray", 128, 128, 128}, + {"grey", 128, 128, 128}, + {"green", 0, 128, 0}, + {"greenyellow", 173, 255, 47}, + {"honeydew", 240, 255, 240}, + {"hotpink", 255, 105, 180}, + {"indianred", 205, 92, 92}, + {"indigo", 75, 0, 130}, + {"ivory", 255, 255, 240}, + {"khaki", 240, 230, 140}, + {"lavender", 230, 230, 250}, + {"lavenderblush", 255, 240, 245}, + {"lawngreen", 124, 252, 0}, + {"lemonchiffon", 255, 250, 205}, + {"lightblue", 173, 216, 230}, + {"lightcoral", 240, 128, 128}, + {"lightcyan", 224, 255, 255}, + {"lightgoldenrodyellow", 250, 250, 210}, + {"lightgray", 211, 211, 211}, + {"lightgreen", 144, 238, 144}, + {"lightgrey", 211, 211, 211}, + {"lightpink", 255, 182, 193}, + {"lightsalmon", 255, 160, 122}, + {"lightseagreen", 32, 178, 170}, + {"lightskyblue", 135, 206, 250}, + {"lightslategray", 119, 136, 153}, + {"lightslategrey", 119, 136, 153}, + {"lightsteelblue", 176, 196, 222}, + {"lightyellow", 255, 255, 224}, + {"lime", 0, 255, 0}, + {"limegreen", 50, 205, 50}, + {"linen", 250, 240, 230}, + {"magenta", 255, 0, 255}, + {"maroon", 128, 0, 0}, + {"mediumaquamarine", 102, 205, 170}, + {"mediumblue", 0, 0, 205}, + {"mediumorchid", 186, 85, 211}, + {"mediumpurple", 147, 112, 219}, + {"mediumseagreen", 60, 179, 113}, + {"mediumslateblue", 123, 104, 238}, + {"mediumspringgreen", 0, 250, 154}, + {"mediumturquoise", 72, 209, 204}, + {"mediumvioletred", 199, 21, 133}, + {"midnightblue", 25, 25, 112}, + {"mintcream", 245, 255, 250}, + {"mistyrose", 255, 228, 225}, + {"moccasin", 255, 228, 181}, + {"navajowhite", 255, 222, 173}, + {"navy", 0, 0, 128}, + {"oldlace", 253, 245, 230}, + {"olive", 128, 128, 0}, + {"olivedrab", 107, 142, 35}, + {"orange", 255, 165, 0}, + {"orangered", 255, 69, 0}, + {"orchid", 218, 112, 214}, + {"palegoldenrod", 238, 232, 170}, + {"palegreen", 152, 251, 152}, + {"paleturquoise", 175, 238, 238}, + {"palevioletred", 219, 112, 147}, + {"papayawhip", 255, 239, 213}, + {"peachpuff", 255, 218, 185}, + {"peru", 205, 133, 63}, + {"pink", 255, 192, 203}, + {"plum", 221, 160, 221}, + {"powderblue", 176, 224, 230}, + {"purple", 128, 0, 128}, + {"red", 255, 0, 0}, + {"rosybrown", 188, 143, 143}, + {"royalblue", 65, 105, 225}, + {"saddlebrown", 139, 69, 19}, + {"salmon", 250, 128, 114}, + {"sandybrown", 244, 164, 96}, + {"seagreen", 46, 139, 87}, + {"seashell", 255, 245, 238}, + {"sienna", 160, 82, 45}, + {"silver", 192, 192, 192}, + {"skyblue", 135, 206, 235}, + {"slateblue", 106, 90, 205}, + {"slategray", 112, 128, 144}, + {"slategrey", 112, 128, 144}, + {"snow", 255, 250, 250}, + {"springgreen", 0, 255, 127}, + {"steelblue", 70, 130, 180}, + {"tan", 210, 180, 140}, + {"teal", 0, 128, 128}, + {"thistle", 216, 191, 216}, + {"tomato", 255, 99, 71}, + {"turquoise", 64, 224, 208}, + {"violet", 238, 130, 238}, + {"wheat", 245, 222, 179}, + {"white", 255, 255, 255}, + {"whitesmoke", 245, 245, 245}, + {"yellow", 255, 255, 0}, + {"yellowgreen", 154, 205, 50}, }; @@ -187,24 +187,26 @@ static const struct { * Functions for converting human-readable colors to BBGGRR value. * Substantial optimization opportunities remain. */ -static int HexDigit( char hex ) { - const char *Digits = "0123456789ABCDEF"; - const char *digits = "0123456789abcdef"; - char * ofs = strchr( digits, hex ); - if ( ofs ) { - return ofs-digits; - } - - ofs = strchr( Digits, hex ); - if ( ofs ) { - return ofs-Digits; - } - return 0; +static int HexDigit(char hex) +{ + const char *Digits = "0123456789ABCDEF"; + const char *digits = "0123456789abcdef"; + char * ofs = strchr(digits, hex); + if (ofs) { + return ofs-digits; + } + + ofs = strchr(Digits, hex); + if (ofs) { + return ofs-Digits; + } + return 0; } -static int HexByte( const char* hex ) { - int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]); - return b; +static int HexByte(const char* hex) +{ + int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]); + return b; } /* @@ -214,35 +216,35 @@ static int HexByte( const char* hex ) { * * return the BBGGRR value for it. */ - + int -color_to_bbggrr( const char *opt_color ) +color_to_bbggrr(const char *opt_color) { - int color_num; - unsigned int i; - char *ep; - - color_num = strtol(opt_color, &ep, 10); - - if (ep != opt_color) { - return color_num; - } - - if ( opt_color[0] == '#' ) { - color_num = (HexByte( opt_color+1 )) + // red - (HexByte( opt_color+3 )<<8) + // green - (HexByte( opt_color+5 )<<16); // blue - return color_num; - } - - for (i = 0; i < sizeof(color_table) / sizeof(color_table[0]); i++) { - if (0 == case_ignore_strcmp(opt_color, color_table[i].cn)) { - return (color_table[i].b << 16) + - (color_table[i].g << 8) + - color_table[i].r; - } - } - - fatal( "unrecognized color name %s\n", opt_color ); - return -1; + int color_num; + unsigned int i; + char *ep; + + color_num = strtol(opt_color, &ep, 10); + + if (ep != opt_color) { + return color_num; + } + + if (opt_color[0] == '#') { + color_num = (HexByte(opt_color+1)) + // red + (HexByte(opt_color+3)<<8) + // green + (HexByte(opt_color+5)<<16); // blue + return color_num; + } + + for (i = 0; i < sizeof(color_table) / sizeof(color_table[0]); i++) { + if (0 == case_ignore_strcmp(opt_color, color_table[i].cn)) { + return (color_table[i].b << 16) + + (color_table[i].g << 8) + + color_table[i].r; + } + } + + fatal("unrecognized color name %s\n", opt_color); + return -1; } diff --git a/gpsbabel/route.c b/gpsbabel/route.c index 3c34e6cd4..0085db367 100644 --- a/gpsbabel/route.c +++ b/gpsbabel/route.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2002-2010 Robert Lipe, robertlipe@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -34,415 +34,426 @@ extern void update_common_traits(const waypoint* wpt); void route_init(void) { - QUEUE_INIT(&my_route_head); - QUEUE_INIT(&my_track_head); + QUEUE_INIT(&my_route_head); + QUEUE_INIT(&my_track_head); } unsigned int route_waypt_count(void) { - /* total wapoint count -- all routes */ - return rte_waypts; + /* total wapoint count -- all routes */ + return rte_waypts; } unsigned int route_count(void) { - return rte_head_ct; /* total # of routes */ + return rte_head_ct; /* total # of routes */ } unsigned int track_waypt_count(void) { - /* totaly waypoint count -- all tracks */ - return trk_waypts; + /* totaly waypoint count -- all tracks */ + return trk_waypts; } unsigned int track_count(void) { - return trk_head_ct; /* total # of tracks */ + return trk_head_ct; /* total # of tracks */ } route_head * route_head_alloc(void) { - route_head *rte_head; - rte_head = (route_head *) xcalloc(sizeof (*rte_head), 1); - QUEUE_INIT(&rte_head->Q); - QUEUE_INIT(&rte_head->waypoint_list); - rte_head->line_color.bbggrr = -1; - rte_head->line_color.opacity = 255; - rte_head->line_width = -1; - rte_head->session = curr_session(); - return rte_head; + route_head *rte_head; + rte_head = (route_head *) xcalloc(sizeof(*rte_head), 1); + QUEUE_INIT(&rte_head->Q); + QUEUE_INIT(&rte_head->waypoint_list); + rte_head->line_color.bbggrr = -1; + rte_head->line_color.opacity = 255; + rte_head->line_width = -1; + rte_head->session = curr_session(); + return rte_head; } static void any_route_free(route_head *rte) { - if ( rte->rte_name ) { - xfree(rte->rte_name); - } - if ( rte->rte_desc ) { - xfree(rte->rte_desc); - } - if ( rte->rte_url ) { - xfree(rte->rte_url); - } - waypt_flush(&rte->waypoint_list); - if ( rte->fs ) { - fs_chain_destroy( rte->fs ); - } - xfree(rte); + if (rte->rte_name) { + xfree(rte->rte_name); + } + if (rte->rte_desc) { + xfree(rte->rte_desc); + } + if (rte->rte_url) { + xfree(rte->rte_url); + } + waypt_flush(&rte->waypoint_list); + if (rte->fs) { + fs_chain_destroy(rte->fs); + } + xfree(rte); } static void -any_route_add_head( route_head *rte, queue *head ) { - ENQUEUE_TAIL( head, &rte->Q ); +any_route_add_head(route_head *rte, queue *head) +{ + ENQUEUE_TAIL(head, &rte->Q); } static void -any_route_del_head( route_head *rte ) { - dequeue( &rte->Q ); - any_route_free( rte ); +any_route_del_head(route_head *rte) +{ + dequeue(&rte->Q); + any_route_free(rte); } void route_add_head(route_head *rte) { - any_route_add_head( rte, &my_route_head ); - rte_head_ct++; + any_route_add_head(rte, &my_route_head); + rte_head_ct++; } void route_del_head(route_head *rte) { - any_route_del_head( rte ); - rte_head_ct--; + any_route_del_head(rte); + rte_head_ct--; } void track_add_head(route_head *rte) { - any_route_add_head( rte, &my_track_head ); - trk_head_ct++; + any_route_add_head(rte, &my_track_head); + trk_head_ct++; } void track_del_head(route_head *rte) { - any_route_del_head( rte ); - trk_head_ct--; + any_route_del_head(rte); + trk_head_ct--; } void track_insert_head(route_head *rte, route_head *predecessor) { - ENQUEUE_AFTER(&predecessor->Q, &rte->Q ); - trk_head_ct++; + ENQUEUE_AFTER(&predecessor->Q, &rte->Q); + trk_head_ct++; } -static +static route_head * common_route_by_name(queue *routes, const char *name) { - queue *elem, *tmp; - route_head *rte; + queue *elem, *tmp; + route_head *rte; - QUEUE_FOR_EACH(routes, elem, tmp) { - rte = (route_head *) elem; - if (0 == strcmp(rte->rte_name, name)) { - return rte; - } - } + QUEUE_FOR_EACH(routes, elem, tmp) { + rte = (route_head *) elem; + if (0 == strcmp(rte->rte_name, name)) { + return rte; + } + } - return NULL; + return NULL; } route_head * route_find_route_by_name(const char *name) { - return common_route_by_name(&my_route_head, name); + return common_route_by_name(&my_route_head, name); } route_head * route_find_track_by_name(const char *name) { - return common_route_by_name(&my_track_head, name); + return common_route_by_name(&my_track_head, name); } static void -any_route_add_wpt(route_head *rte, waypoint *wpt, int *ct, int synth ) -{ - ENQUEUE_TAIL(&rte->waypoint_list, &wpt->Q); - rte->rte_waypt_ct++; /* waypoints in this route */ - if ( ct ) { - (*ct)++; - } - if ( synth && !wpt->shortname ) { - char tmpnam[10]; - snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",*ct); - wpt->shortname = xstrdup(tmpnam); - wpt->wpt_flags.shortname_is_synthetic = 1; - } - update_common_traits(wpt); -} - -void -route_add_wpt( route_head *rte, waypoint *wpt ) -{ - // First point in a route is always a new segment. - // This improves compatibility when reading from - // segment-unaware formats. - if (QUEUE_EMPTY(&rte->waypoint_list)) { - wpt->wpt_flags.new_trkseg = 1; - } - - any_route_add_wpt( rte, wpt, &rte_waypts, 1 ); -} - -void -track_add_wpt( route_head *rte, waypoint *wpt ) -{ - // First point in a track is always a new segment. - // This improves compatibility when reading from - // segment-unaware formats. - if (QUEUE_EMPTY(&rte->waypoint_list)) { - wpt->wpt_flags.new_trkseg = 1; - } - - any_route_add_wpt( rte, wpt, &trk_waypts, 0 ); +any_route_add_wpt(route_head *rte, waypoint *wpt, int *ct, int synth) +{ + ENQUEUE_TAIL(&rte->waypoint_list, &wpt->Q); + rte->rte_waypt_ct++; /* waypoints in this route */ + if (ct) { + (*ct)++; + } + if (synth && !wpt->shortname) { + char tmpnam[10]; + snprintf(tmpnam, sizeof(tmpnam), "RPT%03d",*ct); + wpt->shortname = xstrdup(tmpnam); + wpt->wpt_flags.shortname_is_synthetic = 1; + } + update_common_traits(wpt); +} + +void +route_add_wpt(route_head *rte, waypoint *wpt) +{ + // First point in a route is always a new segment. + // This improves compatibility when reading from + // segment-unaware formats. + if (QUEUE_EMPTY(&rte->waypoint_list)) { + wpt->wpt_flags.new_trkseg = 1; + } + + any_route_add_wpt(rte, wpt, &rte_waypts, 1); +} + +void +track_add_wpt(route_head *rte, waypoint *wpt) +{ + // First point in a track is always a new segment. + // This improves compatibility when reading from + // segment-unaware formats. + if (QUEUE_EMPTY(&rte->waypoint_list)) { + wpt->wpt_flags.new_trkseg = 1; + } + + any_route_add_wpt(rte, wpt, &trk_waypts, 0); } waypoint * -route_find_waypt_by_name( route_head *rh, const char *name ) +route_find_waypt_by_name(route_head *rh, const char *name) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { - waypoint *waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { - return waypointp; - } - } - return NULL; + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + waypoint *waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + return NULL; } -static void -any_route_del_wpt( route_head *rte, waypoint *wpt, int *ct) +static void +any_route_del_wpt(route_head *rte, waypoint *wpt, int *ct) { - if (wpt->wpt_flags.new_trkseg && wpt != (waypoint*)QUEUE_LAST(&rte->waypoint_list)) { - waypoint* wpt_next = (waypoint*)QUEUE_NEXT(&wpt->Q); - wpt_next->wpt_flags.new_trkseg = 1; - } - wpt->wpt_flags.new_trkseg = 0; - dequeue( &wpt->Q ); - rte->rte_waypt_ct--; - if ( ct ) (*ct)--; + if (wpt->wpt_flags.new_trkseg && wpt != (waypoint*)QUEUE_LAST(&rte->waypoint_list)) { + waypoint* wpt_next = (waypoint*)QUEUE_NEXT(&wpt->Q); + wpt_next->wpt_flags.new_trkseg = 1; + } + wpt->wpt_flags.new_trkseg = 0; + dequeue(&wpt->Q); + rte->rte_waypt_ct--; + if (ct) { + (*ct)--; + } } -void -route_del_wpt( route_head *rte, waypoint *wpt ) +void +route_del_wpt(route_head *rte, waypoint *wpt) { - any_route_del_wpt( rte, wpt, &rte_waypts ); + any_route_del_wpt(rte, wpt, &rte_waypts); } -void -track_del_wpt( route_head *rte, waypoint *wpt ) +void +track_del_wpt(route_head *rte, waypoint *wpt) { - any_route_del_wpt( rte, wpt, &trk_waypts ); + any_route_del_wpt(rte, wpt, &trk_waypts); } void -route_disp (const route_head *rh, waypt_cb cb ) +route_disp(const route_head *rh, waypt_cb cb) { - queue *elem, *tmp; - if (!cb) { - return; - } - QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { - waypoint *waypointp; - waypointp = (waypoint *) elem; - (*cb)(waypointp); - } - + queue *elem, *tmp; + if (!cb) { + return; + } + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + waypoint *waypointp; + waypointp = (waypoint *) elem; + (*cb)(waypointp); + } + } -void +void route_reverse(const route_head *rte_hd) { - /* Cast away const-ness */ - route_head *rh = (route_head *) rte_hd; - queue *elem, *tmp; - QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { - ENQUEUE_HEAD(&rh->waypoint_list, dequeue(elem)); - } + /* Cast away const-ness */ + route_head *rh = (route_head *) rte_hd; + queue *elem, *tmp; + QUEUE_FOR_EACH(&rh->waypoint_list, elem, tmp) { + ENQUEUE_HEAD(&rh->waypoint_list, dequeue(elem)); + } } static void common_disp_all(queue *qh, route_hdr rh, route_trl rt, waypt_cb wc) { - queue *elem, *tmp; - QUEUE_FOR_EACH(qh, elem, tmp) { - const route_head *rhp; - rhp = (route_head *) elem; - if (rh) (*rh)(rhp); - route_disp(rhp, wc); - if (rt) (*rt)(rhp); - } + queue *elem, *tmp; + QUEUE_FOR_EACH(qh, elem, tmp) { + const route_head *rhp; + rhp = (route_head *) elem; + if (rh) { + (*rh)(rhp); + } + route_disp(rhp, wc); + if (rt) { + (*rt)(rhp); + } + } } static void common_disp_session(const session_t *se, queue *qh, route_hdr rh, route_trl rt, waypt_cb wc) { - queue *elem, *tmp; - QUEUE_FOR_EACH(qh, elem, tmp) { - const route_head *rhp; - rhp = (route_head *) elem; - if (rhp->session == se) { - if (rh) (*rh)(rhp); - route_disp(rhp, wc); - if (rt) (*rt)(rhp); - } - } + queue *elem, *tmp; + QUEUE_FOR_EACH(qh, elem, tmp) { + const route_head *rhp; + rhp = (route_head *) elem; + if (rhp->session == se) { + if (rh) { + (*rh)(rhp); + } + route_disp(rhp, wc); + if (rt) { + (*rt)(rhp); + } + } + } } -void +void route_disp_all(route_hdr rh, route_trl rt, waypt_cb wc) { - common_disp_all(&my_route_head, rh, rt, wc); + common_disp_all(&my_route_head, rh, rt, wc); } -void +void route_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc) { - common_disp_session(se, &my_route_head, rh, rt, wc); + common_disp_session(se, &my_route_head, rh, rt, wc); } -void +void track_disp_all(route_hdr rh, route_trl rt, waypt_cb wc) { - common_disp_all(&my_track_head, rh, rt, wc); + common_disp_all(&my_track_head, rh, rt, wc); } -void +void track_disp_session(const session_t *se, route_hdr rh, route_trl rt, waypt_cb wc) { - common_disp_session(se, &my_track_head, rh, rt, wc); + common_disp_session(se, &my_track_head, rh, rt, wc); } static void route_flush_q(queue *head) { - queue *elem, *tmp; - queue *q; + queue *elem, *tmp; + queue *q; - QUEUE_FOR_EACH(head, elem, tmp) { - q = dequeue(elem); - any_route_free((route_head *) q); - } + QUEUE_FOR_EACH(head, elem, tmp) { + q = dequeue(elem); + any_route_free((route_head *) q); + } } void route_flush_all_routes(void) { - route_flush_q(&my_route_head); - rte_head_ct = 0; - rte_waypts = 0; + route_flush_q(&my_route_head); + rte_head_ct = 0; + rte_waypts = 0; } void route_flush_all_tracks(void) { - route_flush_q(&my_track_head); - trk_head_ct = 0; - trk_waypts = 0; + route_flush_q(&my_track_head); + trk_head_ct = 0; + trk_waypts = 0; } void route_flush_all() { - route_flush_all_tracks(); - route_flush_all_routes(); + route_flush_all_tracks(); + route_flush_all_routes(); } -void -route_flush( queue *head ) +void +route_flush(queue *head) { - queue *elem, *tmp; - queue *q; - QUEUE_FOR_EACH(head, elem, tmp ) { - q = dequeue(elem); - any_route_free((route_head *)q); - } + queue *elem, *tmp; + queue *q; + QUEUE_FOR_EACH(head, elem, tmp) { + q = dequeue(elem); + any_route_free((route_head *)q); + } } void -route_copy( int *dst_count, int *dst_wpt_count, queue **dst, queue *src ) { - queue *elem, *tmp, *elem2, *tmp2; - route_head *rte_new; - int junk; - if ( !dst_wpt_count ) { - dst_wpt_count = &junk; - } - - if ( !*dst ) { - *dst = (queue *)xcalloc( 1, sizeof( queue )); - QUEUE_INIT( *dst ); - *dst_count = 0; - *dst_wpt_count = 0; - } - QUEUE_FOR_EACH(src, elem, tmp ) - { - route_head *rte_old = (route_head *)elem; - - rte_new = route_head_alloc(); - rte_new->rte_name = xstrdup( rte_old->rte_name ); - rte_new->rte_desc = xstrdup( rte_old->rte_desc ); - rte_new->rte_url = xstrdup( rte_old->rte_url ); - rte_new->fs = fs_chain_copy( rte_old->fs ); - rte_new->rte_num = rte_old->rte_num; - any_route_add_head( rte_new, *dst ); - QUEUE_FOR_EACH( &rte_old->waypoint_list, elem2, tmp2 ) - { - any_route_add_wpt( rte_new, waypt_dupe((waypoint *)elem2), dst_wpt_count, 0); - } - (*dst_count)++; - } +route_copy(int *dst_count, int *dst_wpt_count, queue **dst, queue *src) +{ + queue *elem, *tmp, *elem2, *tmp2; + route_head *rte_new; + int junk; + if (!dst_wpt_count) { + dst_wpt_count = &junk; + } + + if (!*dst) { + *dst = (queue *)xcalloc(1, sizeof(queue)); + QUEUE_INIT(*dst); + *dst_count = 0; + *dst_wpt_count = 0; + } + QUEUE_FOR_EACH(src, elem, tmp) { + route_head *rte_old = (route_head *)elem; + + rte_new = route_head_alloc(); + rte_new->rte_name = xstrdup(rte_old->rte_name); + rte_new->rte_desc = xstrdup(rte_old->rte_desc); + rte_new->rte_url = xstrdup(rte_old->rte_url); + rte_new->fs = fs_chain_copy(rte_old->fs); + rte_new->rte_num = rte_old->rte_num; + any_route_add_head(rte_new, *dst); + QUEUE_FOR_EACH(&rte_old->waypoint_list, elem2, tmp2) { + any_route_add_wpt(rte_new, waypt_dupe((waypoint *)elem2), dst_wpt_count, 0); + } + (*dst_count)++; + } } void -route_append( queue *src ) +route_append(queue *src) { - queue *dst = &my_route_head; - route_copy( &rte_head_ct, &rte_waypts, &dst, src ); + queue *dst = &my_route_head; + route_copy(&rte_head_ct, &rte_waypts, &dst, src); } void -track_append( queue *src ) +track_append(queue *src) { - queue *dst = &my_track_head; - route_copy( &trk_head_ct, &trk_waypts, &dst, src ); + queue *dst = &my_track_head; + route_copy(&trk_head_ct, &trk_waypts, &dst, src); } void route_backup(signed int *count, queue **head_bak) { - route_copy( count, NULL, head_bak, &my_route_head ); + route_copy(count, NULL, head_bak, &my_route_head); } static void route_restore_hdr(const route_head *rte) { - rte_head_ct++; + rte_head_ct++; } static void track_restore_hdr(const route_head *trk) { - trk_head_ct++; + trk_head_ct++; } static void @@ -453,54 +464,58 @@ route_restore_tlr(const route_head *rte) static void route_restore_wpt(const waypoint *wpt) { - rte_waypts++; + rte_waypts++; } static void track_restore_wpt(const waypoint *wpt) { - trk_waypts++; + trk_waypts++; } static void common_restore_finish(void) { - rte_head_ct = 0; - trk_head_ct = 0; - rte_waypts = 0; - trk_waypts = 0; - route_disp_all(route_restore_hdr, route_restore_tlr, route_restore_wpt); - track_disp_all(track_restore_hdr, route_restore_tlr, track_restore_wpt); + rte_head_ct = 0; + trk_head_ct = 0; + rte_waypts = 0; + trk_waypts = 0; + route_disp_all(route_restore_hdr, route_restore_tlr, route_restore_wpt); + track_disp_all(track_restore_hdr, route_restore_tlr, track_restore_wpt); } void -route_restore( queue *head_bak) +route_restore(queue *head_bak) { - if (head_bak == NULL) return; - - route_flush_q(&my_route_head); - QUEUE_INIT(&my_route_head); - QUEUE_MOVE(&my_route_head, head_bak); - - common_restore_finish(); + if (head_bak == NULL) { + return; + } + + route_flush_q(&my_route_head); + QUEUE_INIT(&my_route_head); + QUEUE_MOVE(&my_route_head, head_bak); + + common_restore_finish(); } void track_backup(signed int *count, queue **head_bak) { - route_copy( count, NULL, head_bak, &my_track_head ); + route_copy(count, NULL, head_bak, &my_track_head); } void -track_restore( queue *head_bak) +track_restore(queue *head_bak) { - if (head_bak == NULL) return; - - route_flush_q(&my_track_head); - QUEUE_INIT(&my_track_head); - QUEUE_MOVE(&my_track_head, head_bak); - - common_restore_finish(); + if (head_bak == NULL) { + return; + } + + route_flush_q(&my_track_head); + QUEUE_INIT(&my_track_head); + QUEUE_MOVE(&my_track_head, head_bak); + + common_restore_finish(); } /* @@ -510,13 +525,13 @@ track_restore( queue *head_bak) void routes_to_tracks(void) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&my_route_head, elem, tmp) { - route_head *trk = (route_head *) elem; - dequeue(&trk->Q); - ENQUEUE_TAIL(&my_track_head, &trk->Q); - } + QUEUE_FOR_EACH(&my_route_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_track_head, &trk->Q); + } } /* @@ -525,13 +540,13 @@ routes_to_tracks(void) void tracks_to_routes(void) { - queue *elem, *tmp; + queue *elem, *tmp; - QUEUE_FOR_EACH(&my_track_head, elem, tmp) { - route_head *trk = (route_head *) elem; - dequeue(&trk->Q); - ENQUEUE_TAIL(&my_route_head, &trk->Q); - } + QUEUE_FOR_EACH(&my_track_head, elem, tmp) { + route_head *trk = (route_head *) elem; + dequeue(&trk->Q); + ENQUEUE_TAIL(&my_route_head, &trk->Q); + } } @@ -539,135 +554,137 @@ tracks_to_routes(void) * This really makes more sense for tracks than routes. * Run over all the trackpoints, computing heading (course), speed, and * and so on. - * + * * If trkdatap is non-null upon entry, a pointer to an allocated collection * (hopefully interesting) statistics about the track will be placed there. */ void track_recompute(const route_head *trk, computed_trkdata **trkdatap) { - waypoint first; - waypoint *thisw; - waypoint *prev = &first; - queue *elem, *tmp; - int tkpt = 0; - int pts_hrt = 0; - double tot_hrt = 0.0; - int pts_cad = 0; - double tot_cad = 0.0; - char tkptname[100]; - computed_trkdata *tdata = (computed_trkdata *)xcalloc(1, sizeof (computed_trkdata)); - - if (trkdatap) { - *trkdatap = tdata; - } - - first.latitude = 0; - first.longitude = 0; - first.creation_time = 0; - tdata->min_hrt = 9999; - tdata->min_alt = -unknown_alt; - tdata->max_alt = unknown_alt; - - QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { - time_t timed; - double tlat, tlon, plat, plon, dist; - - thisw = (waypoint *)elem; - timed = thisw->creation_time - prev->creation_time; - - /* - * gcdist and heading want radians, not degrees. - */ - tlat = RAD(thisw->latitude); - tlon = RAD(thisw->longitude); - plat = RAD(prev->latitude); - plon = RAD(prev->longitude); - WAYPT_SET(thisw, course, heading_true_degrees(plat, plon, - tlat, tlon)); - dist = radtometers(gcdist(plat, plon, tlat, tlon)); - - /* - * Avoid that 6300 mile jump as we move from 0,0. - */ - if (plat && plon) { - tdata->distance_meters += dist; - } - - /* - * If we've moved as much as a meter, - * conditionally recompute speeds. - */ - if (timed && (dist > 1)) { - if(!WAYPT_HAS(thisw, speed)) { - // Only recompute speed if the waypoint - // didn't already have a speed - WAYPT_SET(thisw, speed, dist / labs(timed)); - } - if (thisw->speed > tdata->max_spd) { - tdata->max_spd = thisw->speed; - } - if (thisw->speed < tdata->min_spd) { - tdata->min_spd = thisw->speed; - } - } - - if (thisw->altitude != unknown_alt) { - if (thisw->altitude < tdata->min_alt) - tdata->min_alt = thisw->altitude; - if (thisw->altitude > tdata->max_alt) - tdata->max_alt = thisw->altitude; - } - - if (thisw->heartrate > 0) { - pts_hrt++; - tot_hrt += (float) thisw->heartrate; - } - - if ((thisw->heartrate > 0) && (thisw->heartrate < tdata->min_hrt)) { - tdata->min_hrt = (int) thisw->heartrate; - } - - if ((thisw->heartrate > 0) && (thisw->heartrate > tdata->max_hrt)) { - tdata->max_hrt = (int) thisw->heartrate; - } - - if (thisw->cadence > 0) { - pts_cad++; - tot_cad += (float) thisw->cadence; - } - - if ((thisw->cadence > 0) && (thisw->cadence > tdata->max_cad)) { - tdata->max_cad = (int) thisw->cadence; - } - - if (thisw->creation_time && (thisw->creation_time < tdata->start)) { - tdata->start = thisw->creation_time; - } - - if (thisw->creation_time > tdata->end) { - tdata->end = thisw->creation_time; - if (tdata->start == 0) { - tdata->start = tdata->end; - } - } - prev = thisw; - if (!thisw->shortname || !thisw->shortname[0] ) { - snprintf(tkptname, sizeof(tkptname), "%s-%d", - trk->rte_name ? trk->rte_name : "" , tkpt); - thisw->shortname = xstrdup(tkptname); - } - tkpt++; - } - - if (pts_hrt > 0) { - tdata->avg_hrt = tot_hrt / (float) pts_hrt; - } - - if (pts_cad > 0) { - tdata->avg_cad = tot_cad / (float) pts_cad; - } - - if (!trkdatap) { - xfree(tdata); - } + waypoint first; + waypoint *thisw; + waypoint *prev = &first; + queue *elem, *tmp; + int tkpt = 0; + int pts_hrt = 0; + double tot_hrt = 0.0; + int pts_cad = 0; + double tot_cad = 0.0; + char tkptname[100]; + computed_trkdata *tdata = (computed_trkdata *)xcalloc(1, sizeof(computed_trkdata)); + + if (trkdatap) { + *trkdatap = tdata; + } + + first.latitude = 0; + first.longitude = 0; + first.creation_time = 0; + tdata->min_hrt = 9999; + tdata->min_alt = -unknown_alt; + tdata->max_alt = unknown_alt; + + QUEUE_FOR_EACH((queue *)&trk->waypoint_list, elem, tmp) { + time_t timed; + double tlat, tlon, plat, plon, dist; + + thisw = (waypoint *)elem; + timed = thisw->creation_time - prev->creation_time; + + /* + * gcdist and heading want radians, not degrees. + */ + tlat = RAD(thisw->latitude); + tlon = RAD(thisw->longitude); + plat = RAD(prev->latitude); + plon = RAD(prev->longitude); + WAYPT_SET(thisw, course, heading_true_degrees(plat, plon, + tlat, tlon)); + dist = radtometers(gcdist(plat, plon, tlat, tlon)); + + /* + * Avoid that 6300 mile jump as we move from 0,0. + */ + if (plat && plon) { + tdata->distance_meters += dist; + } + + /* + * If we've moved as much as a meter, + * conditionally recompute speeds. + */ + if (timed && (dist > 1)) { + if (!WAYPT_HAS(thisw, speed)) { + // Only recompute speed if the waypoint + // didn't already have a speed + WAYPT_SET(thisw, speed, dist / labs(timed)); + } + if (thisw->speed > tdata->max_spd) { + tdata->max_spd = thisw->speed; + } + if (thisw->speed < tdata->min_spd) { + tdata->min_spd = thisw->speed; + } + } + + if (thisw->altitude != unknown_alt) { + if (thisw->altitude < tdata->min_alt) { + tdata->min_alt = thisw->altitude; + } + if (thisw->altitude > tdata->max_alt) { + tdata->max_alt = thisw->altitude; + } + } + + if (thisw->heartrate > 0) { + pts_hrt++; + tot_hrt += (float) thisw->heartrate; + } + + if ((thisw->heartrate > 0) && (thisw->heartrate < tdata->min_hrt)) { + tdata->min_hrt = (int) thisw->heartrate; + } + + if ((thisw->heartrate > 0) && (thisw->heartrate > tdata->max_hrt)) { + tdata->max_hrt = (int) thisw->heartrate; + } + + if (thisw->cadence > 0) { + pts_cad++; + tot_cad += (float) thisw->cadence; + } + + if ((thisw->cadence > 0) && (thisw->cadence > tdata->max_cad)) { + tdata->max_cad = (int) thisw->cadence; + } + + if (thisw->creation_time && (thisw->creation_time < tdata->start)) { + tdata->start = thisw->creation_time; + } + + if (thisw->creation_time > tdata->end) { + tdata->end = thisw->creation_time; + if (tdata->start == 0) { + tdata->start = tdata->end; + } + } + prev = thisw; + if (!thisw->shortname || !thisw->shortname[0]) { + snprintf(tkptname, sizeof(tkptname), "%s-%d", + trk->rte_name ? trk->rte_name : "" , tkpt); + thisw->shortname = xstrdup(tkptname); + } + tkpt++; + } + + if (pts_hrt > 0) { + tdata->avg_hrt = tot_hrt / (float) pts_hrt; + } + + if (pts_cad > 0) { + tdata->avg_cad = tot_cad / (float) pts_cad; + } + + if (!trkdatap) { + xfree(tdata); + } } diff --git a/gpsbabel/saroute.c b/gpsbabel/saroute.c index 519bde10e..24e3460c9 100644 --- a/gpsbabel/saroute.c +++ b/gpsbabel/saroute.c @@ -1,6 +1,6 @@ /* Read various Delorme routes including anr, rte, and rtd. - + Copyright (C) 2003 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -39,18 +39,28 @@ int control = 0; static arglist_t saroute_args[] = { - {"turns_important", &turns_important, - "Keep turns if simplify filter is used", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"turns_only", &turns_only, "Only read turns; skip all other points", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"split", &split, "Split into multiple routes at turns", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"controls", &controls, "Read control points as waypoint/route/none", - "none", ARGTYPE_STRING, ARG_NOMINMAX }, - {"times", ×ynth, "Synthesize track times", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "turns_important", &turns_important, + "Keep turns if simplify filter is used", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "turns_only", &turns_only, "Only read turns; skip all other points", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "split", &split, "Split into multiple routes at turns", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "controls", &controls, "Read control points as waypoint/route/none", + "none", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "times", ×ynth, "Synthesize track times", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define ReadShort(f) gbfgetint16(f) @@ -59,393 +69,391 @@ arglist_t saroute_args[] = { unsigned char * ReadRecord(gbfile *f, gbsize_t size) { - unsigned char *result = (unsigned char *) xmalloc(size); + unsigned char *result = (unsigned char *) xmalloc(size); - (void)gbfread(result, size, 1, f); - return result; + (void)gbfread(result, size, 1, f); + return result; } void Skip(gbfile * f, gbsize_t distance) { - gbfseek(f, distance, SEEK_CUR); + gbfseek(f, distance, SEEK_CUR); } static void rd_init(const char *fname) { - infile = gbfopen(fname, "rb", MYNAME); - if ( split && (turns_important || turns_only )) { - fatal( MYNAME - ": turns options are not compatible with split\n" ); - } - if ( controls ) { - switch( controls[0] ) { - case 'n': control = 0; break; - case 'r': control = 1; break; - case 'w': control = 2; break; - default: - fatal( MYNAME - ": unrecognized value for 'controls'\n" ); - break; - } - } + infile = gbfopen(fname, "rb", MYNAME); + if (split && (turns_important || turns_only)) { + fatal(MYNAME + ": turns options are not compatible with split\n"); + } + if (controls) { + switch (controls[0]) { + case 'n': + control = 0; + break; + case 'r': + control = 1; + break; + case 'w': + control = 2; + break; + default: + fatal(MYNAME + ": unrecognized value for 'controls'\n"); + break; + } + } } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void my_read(void) { - gbuint16 version; - gbuint32 count; - gbuint32 outercount; - gbuint32 recsize; - gbuint16 stringlen; - unsigned char *record; - static int serial = 0; - struct ll { - gbint32 lat; - gbint32 lon; - } *latlon; - gbuint16 coordcount; - route_head *track_head = NULL; - route_head *old_track_head = NULL; - waypoint *wpt_tmp; - char *routename = NULL; - double seglen = 0.0; - gbint32 starttime = 0; - gbint32 transittime = 0; - double totaldist = 0.0; - double oldlat = 0; - double oldlon = 0; - int first = 0; - - ReadShort(infile); /* magic */ - version = ReadShort(infile); - - ReadLong(infile); - if (version >= 6) { - ReadLong(infile); - ReadLong(infile); - } - - /* - * end of header - */ - - ReadShort(infile); - recsize = ReadLong(infile); - /* - * the first recsize, oddly, doesn't include the filename string - * but it does include the header. - */ - record = ReadRecord(infile, recsize); - - stringlen = le_read16((gbuint16 *)(record + 0x1a)); - if ( stringlen ) { - routename = (char *)xmalloc( stringlen + 1 ); - routename[stringlen] = '\0'; - memcpy( routename, record+0x1c, stringlen ); - } - Skip(infile, stringlen - 4); - xfree(record); - - /* - * end of filename record - */ - - /* - * here lie the route description records - */ - if ( version < 6 || (control == 1)) { - track_head = route_head_alloc(); - route_add_head(track_head); - if ( control ) { - track_head->rte_name = xstrdup("control points"); - } - else { - track_head->rte_name = xstrdup( routename ); - } - } - count = ReadLong(infile); - while (count) { - ReadShort(infile); - recsize = ReadLong(infile); - if (version < 6 || control) { - double lat; - double lon; - - record = ReadRecord(infile, recsize); - latlon = (struct ll *)(record); - - /* These records are backwards for some reason */ - lat = (0x80000000UL - - le_read32(&latlon->lon)) / (double)(0x800000); - lon = (0x80000000UL - - le_read32(&latlon->lat)) / (double)(0x800000); - - wpt_tmp = waypt_new(); - wpt_tmp->latitude = lat; - wpt_tmp->longitude = -lon; - if ( control ) { - int obase, addrlen, cmtlen; - - /* Somewhere around TopoUSA 6.0, these moved */ - /* This block also seems to get miscompiled - * at -O0 on Linux. I tried rewriting it to - * reduce/eliminate some of the really funky - * pointer math and casting that was here. - */ - if (version >= 11) { - obase = 20; - } else { - obase = 18; - } - - addrlen = le_read16(&record[obase]); - cmtlen = le_read16(&record[obase+2+addrlen]); - - wpt_tmp->shortname = xmalloc(addrlen+1); - wpt_tmp->shortname[addrlen]='\0'; - wpt_tmp->notes = xmalloc(cmtlen+1); - wpt_tmp->notes[cmtlen] = '\0'; - memcpy(wpt_tmp->notes, - record+obase+4+addrlen, - cmtlen ); - memcpy(wpt_tmp->shortname, - record+obase+2, - addrlen ); - } - else { - wpt_tmp->shortname = xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", serial++ ); - } - if ( control == 2 ) { - waypt_add( wpt_tmp ); - } - else { - route_add_wpt(track_head, wpt_tmp); - } - xfree(record); - if (version >= 6 ) { - /* - * two longs of scrap after each record, don't know why - */ - ReadLong(infile); - ReadLong(infile); - } - } else { - Skip(infile, recsize); - /* - * two longs of scrap after each record, don't know why - */ - ReadLong(infile); - ReadLong(infile); - } - count--; - } - /* - * end of route desc records - */ - - /* - * outercount is the number of route segments (start+end+stops+vias-1) - */ - - outercount = ReadLong(infile); - while (outercount) { - - /* - * unknown record (route params?) lives here - */ - ReadShort(infile); - recsize = ReadLong(infile); - Skip(infile, recsize); - - /* - * end of unknown record - */ - - /* - * routing begins here - */ - count = ReadLong(infile); - if ( count ) { - track_head = route_head_alloc(); - if ( timesynth ) { - track_add_head(track_head); - } - else { - route_add_head(track_head); - } - if ( routename && !split ) { - track_head->rte_name = xstrdup( routename ); - } - } - while (count) { - old_track_head = NULL; - ReadShort(infile); - recsize = ReadLong(infile); - record = ReadRecord(infile, recsize); - stringlen = le_read16((gbuint16 *)record); - if ( split && stringlen ) { - if ( track_head->rte_waypt_ct ) { - old_track_head = track_head; - track_head = route_head_alloc(); - if ( timesynth ) { - track_add_head( track_head ); - } - else { - route_add_head( track_head ); - } - } // end if - if ( !track_head->rte_name ) { - track_head->rte_name = - (char *)xmalloc(stringlen+1); - strncpy( track_head->rte_name, - (const char *) record+2, stringlen ); - track_head->rte_name[stringlen] = '\0'; - } - } - - if ( timesynth ) { - seglen = le_read_double( - record + 2 + stringlen + 0x08 ); - starttime = le_read32((gbuint32 *) - (record + 2 + stringlen + 0x30 )); - transittime = le_read32((gbuint32 *) - (record + 2 + stringlen + 0x10 )); - seglen /= 5280*12*2.54/100000; /* to miles */ - } - - coordcount = le_read16((gbuint16 *) - (record + 2 + stringlen + 0x3c)); - latlon = (struct ll *)(record + 2 + stringlen + 0x3c + 2); - count--; - if (count) { - coordcount--; - } - - first = 1; - - while (coordcount) { - double lat; - double lon; - - wpt_tmp = waypt_new(); - - lat = (0x80000000UL - - le_read32(&latlon->lat)) / - (double)(0x800000); - lon = (0x80000000UL - - le_read32(&latlon->lon)) / - (double)(0x800000); - - wpt_tmp->latitude = lat; - wpt_tmp->longitude = -lon; - if ( stringlen && ((coordcount>1) || count)) { - wpt_tmp->shortname = xmalloc(stringlen+1); - wpt_tmp->shortname[stringlen] = '\0'; - memcpy( wpt_tmp->shortname, - ((char *)record)+2, - stringlen ); - } - else { - wpt_tmp->shortname = (char *) xmalloc(7); - sprintf( wpt_tmp->shortname, "\\%5.5x", - serial++ ); - } - if ( timesynth ) { - if ( !first ) { - double dist = radtomiles(gcdist( - RAD(lat), RAD(-lon), - RAD(oldlat), - RAD(-oldlon) )); - totaldist += dist; - if ( totaldist > seglen ) { - totaldist = seglen; - } - wpt_tmp->creation_time = - gpsbabel_time+starttime+ - transittime * totaldist/seglen; - } - else { - wpt_tmp->creation_time = - gpsbabel_time+starttime; - totaldist = 0; - } - oldlat = lat; - oldlon = lon; - } - if ( turns_important && stringlen ) - wpt_tmp->route_priority=1; - if ( !turns_only || stringlen ) { - if ( timesynth ) { - track_add_wpt(track_head,wpt_tmp); - } - else { - route_add_wpt(track_head, wpt_tmp); - } - if ( old_track_head ) { - if ( timesynth ) { - track_add_wpt(old_track_head, - waypt_dupe(wpt_tmp)); - } - else { - route_add_wpt(old_track_head, - waypt_dupe(wpt_tmp)); - } - old_track_head = NULL; - } - } - - latlon++; - coordcount--; - stringlen = 0; - /* the stop point is a "turn" */ - if ( coordcount == 1 && count == 0 ) { - stringlen = 1; - } - first = 0; - } - if ( version > 10 ) { - Skip(infile,2*sizeof(gbuint32)); - } - xfree(record); - } - /* - * end of routing - */ - outercount--; - } - if ( routename ) { - xfree( routename ); - } + gbuint16 version; + gbuint32 count; + gbuint32 outercount; + gbuint32 recsize; + gbuint16 stringlen; + unsigned char *record; + static int serial = 0; + struct ll { + gbint32 lat; + gbint32 lon; + } *latlon; + gbuint16 coordcount; + route_head *track_head = NULL; + route_head *old_track_head = NULL; + waypoint *wpt_tmp; + char *routename = NULL; + double seglen = 0.0; + gbint32 starttime = 0; + gbint32 transittime = 0; + double totaldist = 0.0; + double oldlat = 0; + double oldlon = 0; + int first = 0; + + ReadShort(infile); /* magic */ + version = ReadShort(infile); + + ReadLong(infile); + if (version >= 6) { + ReadLong(infile); + ReadLong(infile); + } + + /* + * end of header + */ + + ReadShort(infile); + recsize = ReadLong(infile); + /* + * the first recsize, oddly, doesn't include the filename string + * but it does include the header. + */ + record = ReadRecord(infile, recsize); + + stringlen = le_read16((gbuint16 *)(record + 0x1a)); + if (stringlen) { + routename = (char *)xmalloc(stringlen + 1); + routename[stringlen] = '\0'; + memcpy(routename, record+0x1c, stringlen); + } + Skip(infile, stringlen - 4); + xfree(record); + + /* + * end of filename record + */ + + /* + * here lie the route description records + */ + if (version < 6 || (control == 1)) { + track_head = route_head_alloc(); + route_add_head(track_head); + if (control) { + track_head->rte_name = xstrdup("control points"); + } else { + track_head->rte_name = xstrdup(routename); + } + } + count = ReadLong(infile); + while (count) { + ReadShort(infile); + recsize = ReadLong(infile); + if (version < 6 || control) { + double lat; + double lon; + + record = ReadRecord(infile, recsize); + latlon = (struct ll *)(record); + + /* These records are backwards for some reason */ + lat = (0x80000000UL - + le_read32(&latlon->lon)) / (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lat)) / (double)(0x800000); + + wpt_tmp = waypt_new(); + wpt_tmp->latitude = lat; + wpt_tmp->longitude = -lon; + if (control) { + int obase, addrlen, cmtlen; + + /* Somewhere around TopoUSA 6.0, these moved */ + /* This block also seems to get miscompiled + * at -O0 on Linux. I tried rewriting it to + * reduce/eliminate some of the really funky + * pointer math and casting that was here. + */ + if (version >= 11) { + obase = 20; + } else { + obase = 18; + } + + addrlen = le_read16(&record[obase]); + cmtlen = le_read16(&record[obase+2+addrlen]); + + wpt_tmp->shortname = xmalloc(addrlen+1); + wpt_tmp->shortname[addrlen]='\0'; + wpt_tmp->notes = xmalloc(cmtlen+1); + wpt_tmp->notes[cmtlen] = '\0'; + memcpy(wpt_tmp->notes, + record+obase+4+addrlen, + cmtlen); + memcpy(wpt_tmp->shortname, + record+obase+2, + addrlen); + } else { + wpt_tmp->shortname = xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5x", serial++); + } + if (control == 2) { + waypt_add(wpt_tmp); + } else { + route_add_wpt(track_head, wpt_tmp); + } + xfree(record); + if (version >= 6) { + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } + } else { + Skip(infile, recsize); + /* + * two longs of scrap after each record, don't know why + */ + ReadLong(infile); + ReadLong(infile); + } + count--; + } + /* + * end of route desc records + */ + + /* + * outercount is the number of route segments (start+end+stops+vias-1) + */ + + outercount = ReadLong(infile); + while (outercount) { + + /* + * unknown record (route params?) lives here + */ + ReadShort(infile); + recsize = ReadLong(infile); + Skip(infile, recsize); + + /* + * end of unknown record + */ + + /* + * routing begins here + */ + count = ReadLong(infile); + if (count) { + track_head = route_head_alloc(); + if (timesynth) { + track_add_head(track_head); + } else { + route_add_head(track_head); + } + if (routename && !split) { + track_head->rte_name = xstrdup(routename); + } + } + while (count) { + old_track_head = NULL; + ReadShort(infile); + recsize = ReadLong(infile); + record = ReadRecord(infile, recsize); + stringlen = le_read16((gbuint16 *)record); + if (split && stringlen) { + if (track_head->rte_waypt_ct) { + old_track_head = track_head; + track_head = route_head_alloc(); + if (timesynth) { + track_add_head(track_head); + } else { + route_add_head(track_head); + } + } // end if + if (!track_head->rte_name) { + track_head->rte_name = + (char *)xmalloc(stringlen+1); + strncpy(track_head->rte_name, + (const char *) record+2, stringlen); + track_head->rte_name[stringlen] = '\0'; + } + } + + if (timesynth) { + seglen = le_read_double( + record + 2 + stringlen + 0x08); + starttime = le_read32((gbuint32 *) + (record + 2 + stringlen + 0x30)); + transittime = le_read32((gbuint32 *) + (record + 2 + stringlen + 0x10)); + seglen /= 5280*12*2.54/100000; /* to miles */ + } + + coordcount = le_read16((gbuint16 *) + (record + 2 + stringlen + 0x3c)); + latlon = (struct ll *)(record + 2 + stringlen + 0x3c + 2); + count--; + if (count) { + coordcount--; + } + + first = 1; + + while (coordcount) { + double lat; + double lon; + + wpt_tmp = waypt_new(); + + lat = (0x80000000UL - + le_read32(&latlon->lat)) / + (double)(0x800000); + lon = (0x80000000UL - + le_read32(&latlon->lon)) / + (double)(0x800000); + + wpt_tmp->latitude = lat; + wpt_tmp->longitude = -lon; + if (stringlen && ((coordcount>1) || count)) { + wpt_tmp->shortname = xmalloc(stringlen+1); + wpt_tmp->shortname[stringlen] = '\0'; + memcpy(wpt_tmp->shortname, + ((char *)record)+2, + stringlen); + } else { + wpt_tmp->shortname = (char *) xmalloc(7); + sprintf(wpt_tmp->shortname, "\\%5.5x", + serial++); + } + if (timesynth) { + if (!first) { + double dist = radtomiles(gcdist( + RAD(lat), RAD(-lon), + RAD(oldlat), + RAD(-oldlon))); + totaldist += dist; + if (totaldist > seglen) { + totaldist = seglen; + } + wpt_tmp->creation_time = + gpsbabel_time+starttime+ + transittime * totaldist/seglen; + } else { + wpt_tmp->creation_time = + gpsbabel_time+starttime; + totaldist = 0; + } + oldlat = lat; + oldlon = lon; + } + if (turns_important && stringlen) { + wpt_tmp->route_priority=1; + } + if (!turns_only || stringlen) { + if (timesynth) { + track_add_wpt(track_head,wpt_tmp); + } else { + route_add_wpt(track_head, wpt_tmp); + } + if (old_track_head) { + if (timesynth) { + track_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } else { + route_add_wpt(old_track_head, + waypt_dupe(wpt_tmp)); + } + old_track_head = NULL; + } + } + + latlon++; + coordcount--; + stringlen = 0; + /* the stop point is a "turn" */ + if (coordcount == 1 && count == 0) { + stringlen = 1; + } + first = 0; + } + if (version > 10) { + Skip(infile,2*sizeof(gbuint32)); + } + xfree(record); + } + /* + * end of routing + */ + outercount--; + } + if (routename) { + xfree(routename); + } } static void wr_init(const char *fname) { - fatal(MYNAME ":Not enough information is known about this format to write it.\n"); + fatal(MYNAME ":Not enough information is known about this format to write it.\n"); } ff_vecs_t saroute_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none}, - rd_init, - wr_init, - rd_deinit, - NULL, - my_read, - NULL, - NULL, - saroute_args, - CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none}, + rd_init, + wr_init, + rd_deinit, + NULL, + my_read, + NULL, + NULL, + saroute_args, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/gpsbabel/sbn.c b/gpsbabel/sbn.c index fcb35eb88..b9da8e998 100644 --- a/gpsbabel/sbn.c +++ b/gpsbabel/sbn.c @@ -29,7 +29,7 @@ static gbfile *file_handle = NULL; static arglist_t sbn_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; @@ -46,7 +46,7 @@ arglist_t sbn_args[] = { #define PID_SBN 41 #define SBN_RECORD_LEN 97 /* 91 plus three two shorts added by Locosys */ - /* V1.3 of the s/w added SDOP and and VSDOP bytes */ +/* V1.3 of the s/w added SDOP and and VSDOP bytes */ #define PID_VISIBLE_LIST 13 #define PID_QRY_INFORMATION 253 #define QRY_INFORMATION_LEN 41 @@ -64,72 +64,74 @@ arglist_t sbn_args[] = { static size_t read_packet(int *type, void *payload, size_t max_len) { - size_t size, data_size; - unsigned char start[4]; - unsigned int checksum_exp, checksum_act; - unsigned char *data; - - if (gbfread(start, sizeof(start), 1, file_handle) != 1) { - if (gbfeof(file_handle)) - return 0; - - fatal(MYNAME ": Format error: No packet start.\n"); - } - - if (start[0] != 0xa0 || start[1] != 0xa2) { - fatal(MYNAME ": Format error: Bad packet start.\n"); - } - - size = be_readu16(start + 2); - - if (size < 1 || max_len < size) { - fatal(MYNAME ": Format error: unexpected size: %d.\n", (int) size); - } - - /* allocate space for checksum and trailing 0xb0b3 */ - data_size = size + 4; - - /* data_size can be up to about 64k */ - data = xmalloc(data_size); - - if (gbfread(data, data_size, 1, file_handle) != 1) { - fatal(MYNAME ": Format error: could not read %d bytes.\n", - (int) data_size); - } - - *type = data[0]; - - checksum_exp = be_readu16(data + size); - checksum_act = navilink_checksum_packet(data, size); - - if (checksum_exp != checksum_act) { - fatal(MYNAME ": Checksum error - expected %x got %x\n", - checksum_exp, checksum_act); - } - - if (data[size + 2] != 0xb0 || data[size + 3] != 0xb3) { - fatal(MYNAME ": Format error: Bad packet trailer\n"); - } - - --size; - - memcpy(payload, data + 1, size); - xfree(data); - - return size; + size_t size, data_size; + unsigned char start[4]; + unsigned int checksum_exp, checksum_act; + unsigned char *data; + + if (gbfread(start, sizeof(start), 1, file_handle) != 1) { + if (gbfeof(file_handle)) { + return 0; + } + + fatal(MYNAME ": Format error: No packet start.\n"); + } + + if (start[0] != 0xa0 || start[1] != 0xa2) { + fatal(MYNAME ": Format error: Bad packet start.\n"); + } + + size = be_readu16(start + 2); + + if (size < 1 || max_len < size) { + fatal(MYNAME ": Format error: unexpected size: %d.\n", (int) size); + } + + /* allocate space for checksum and trailing 0xb0b3 */ + data_size = size + 4; + + /* data_size can be up to about 64k */ + data = xmalloc(data_size); + + if (gbfread(data, data_size, 1, file_handle) != 1) { + fatal(MYNAME ": Format error: could not read %d bytes.\n", + (int) data_size); + } + + *type = data[0]; + + checksum_exp = be_readu16(data + size); + checksum_act = navilink_checksum_packet(data, size); + + if (checksum_exp != checksum_act) { + fatal(MYNAME ": Checksum error - expected %x got %x\n", + checksum_exp, checksum_act); + } + + if (data[size + 2] != 0xb0 || data[size + 3] != 0xb3) { + fatal(MYNAME ": Format error: Bad packet trailer\n"); + } + + --size; + + memcpy(payload, data + 1, size); + xfree(data); + + return size; } #ifdef LOCOSYS_PARSE_FILE_ID static size_t hdrcpy(char *dest, const char *src, size_t max_len) { - size_t i; - - for (i = 0; i < max_len && *src != INFO_SEP; i++) - *dest++ = *src++; - *dest++ = 0; + size_t i; - return ++i; + for (i = 0; i < max_len && *src != INFO_SEP; i++) { + *dest++ = *src++; + } + *dest++ = 0; + + return ++i; } #endif /* LOCOSYS_PARSE_FILE_ID */ @@ -137,141 +139,142 @@ int locosys_decode_file_id(char *header, size_t len) { #ifdef LOCOSYS_PARSE_FILE_ID - /* - * MID_FILE_ID(0xfd) contains the following payload : - * User Name, Serial Number, Log Rate, Firmware Version - * >field separator:"," - * >User Name : MAX CHAR(13) - * >Serial Number : MAX CHAR(8) - * >Log Rate : MAX CHAR 3, 0..255 in seconds - * >Firmware Version : MAX CHAR (13) - */ - - char username[INFO_USERNAME_LEN + 1]; - char serial_num[INFO_SERIAL_NUM_LEN + 1]; - char log_rate[INFO_LOG_RATE_LEN + 1]; - char version[INFO_VERSION_LEN + 1]; - char *p = header; - - p += hdrcpy(username, p, INFO_USERNAME_LEN); - p += hdrcpy(serial_num, p, INFO_SERIAL_NUM_LEN); - p += hdrcpy(log_rate, p, INFO_LOG_RATE_LEN); - p += hdrcpy(version, p, INFO_VERSION_LEN); - - printf(MYNAME ": Username: %s\n", username); - printf(MYNAME ": Serial Number: %s\n", serial_num); - printf(MYNAME ": Log rate (seconds): %s\n", log_rate); - printf(MYNAME ": Firmware version: %s\n", version); + /* + * MID_FILE_ID(0xfd) contains the following payload : + * User Name, Serial Number, Log Rate, Firmware Version + * >field separator:"," + * >User Name : MAX CHAR(13) + * >Serial Number : MAX CHAR(8) + * >Log Rate : MAX CHAR 3, 0..255 in seconds + * >Firmware Version : MAX CHAR (13) + */ + + char username[INFO_USERNAME_LEN + 1]; + char serial_num[INFO_SERIAL_NUM_LEN + 1]; + char log_rate[INFO_LOG_RATE_LEN + 1]; + char version[INFO_VERSION_LEN + 1]; + char *p = header; + + p += hdrcpy(username, p, INFO_USERNAME_LEN); + p += hdrcpy(serial_num, p, INFO_SERIAL_NUM_LEN); + p += hdrcpy(log_rate, p, INFO_LOG_RATE_LEN); + p += hdrcpy(version, p, INFO_VERSION_LEN); + + printf(MYNAME ": Username: %s\n", username); + printf(MYNAME ": Serial Number: %s\n", serial_num); + printf(MYNAME ": Log rate (seconds): %s\n", log_rate); + printf(MYNAME ": Firmware version: %s\n", version); #endif /* LOCOSYS_PARSE_FILE_ID */ - return TRUE; + return TRUE; } static void read_sbn_header(route_head *track) { - char header[QRY_INFORMATION_LEN]; - size_t len; - int type = 0; - - len = read_packet(&type, header, sizeof(header)); - - if (len == 0 || type != PID_QRY_INFORMATION || - !locosys_decode_file_id(header, len)) { - fatal(MYNAME ": Format error: Couldn't read SBN header." - "This probably isn't a SBN file.\n"); - } + char header[QRY_INFORMATION_LEN]; + size_t len; + int type = 0; + + len = read_packet(&type, header, sizeof(header)); + + if (len == 0 || type != PID_QRY_INFORMATION || + !locosys_decode_file_id(header, len)) { + fatal(MYNAME ": Format error: Couldn't read SBN header." + "This probably isn't a SBN file.\n"); + } } static int is_sbn_valid(const unsigned char *buffer) { - /* valid navigation (any bit set implies navigation solution is not - * optimal) */ - return !buffer[0] && !buffer[1]; + /* valid navigation (any bit set implies navigation solution is not + * optimal) */ + return !buffer[0] && !buffer[1]; } static fix_type decode_sbn_mode(const unsigned char *mode) { - static const fix_type fixes[8] = { - fix_none, /* 000 No Nav */ - fix_none, /* 001 1 SV solution */ - fix_none, /* 010 2 SV solution */ - fix_2d, /* 011 3 SV solution (2D) */ - fix_3d, /* 100 4 or more SV solution (3D) */ - fix_2d, /* 101 Least Square 2D solution */ - fix_3d, /* 110 Least Square 3D solution */ - fix_none /* 111 DR solution (no SV) */ - }; - int dgps_correction = *mode & 0x80; - fix_type fix = fixes[*mode & 7]; - - return dgps_correction && fix == fix_3d ? fix_dgps : fix; + static const fix_type fixes[8] = { + fix_none, /* 000 No Nav */ + fix_none, /* 001 1 SV solution */ + fix_none, /* 010 2 SV solution */ + fix_2d, /* 011 3 SV solution (2D) */ + fix_3d, /* 100 4 or more SV solution (3D) */ + fix_2d, /* 101 Least Square 2D solution */ + fix_3d, /* 110 Least Square 3D solution */ + fix_none /* 111 DR solution (no SV) */ + }; + int dgps_correction = *mode & 0x80; + fix_type fix = fixes[*mode & 7]; + + return dgps_correction && fix == fix_3d ? fix_dgps : fix; } static void decode_sbn_datetime(const unsigned char *buffer, waypoint *waypt) { - struct tm tm; - int ms = be_readu16(buffer + 6); - - tm.tm_sec = ms / 1000; - tm.tm_min = buffer[5]; - tm.tm_hour = buffer[4]; - tm.tm_mday = buffer[3]; - tm.tm_mon = buffer[2] - 1; - tm.tm_year = be_readu16(buffer) - 1900; - - waypt->creation_time = mkgmtime(&tm); - waypt->microseconds = (ms % 1000) * 1000; + struct tm tm; + int ms = be_readu16(buffer + 6); + + tm.tm_sec = ms / 1000; + tm.tm_min = buffer[5]; + tm.tm_hour = buffer[4]; + tm.tm_mday = buffer[3]; + tm.tm_mon = buffer[2] - 1; + tm.tm_year = be_readu16(buffer) - 1900; + + waypt->creation_time = mkgmtime(&tm); + waypt->microseconds = (ms % 1000) * 1000; } static void decode_sbn_position(const unsigned char *buffer, waypoint *waypt) { - waypt->latitude = be_read32(buffer + 0) * 0.0000001; - waypt->longitude = be_read32(buffer + 4) * 0.0000001; - waypt->altitude = be_read32(buffer + 12) * 0.01; + waypt->latitude = be_read32(buffer + 0) * 0.0000001; + waypt->longitude = be_read32(buffer + 4) * 0.0000001; + waypt->altitude = be_read32(buffer + 12) * 0.01; } static waypoint * decode_sbn_record(unsigned char *buffer) { - waypoint *waypt = NULL; - waypt = waypt_new(); - - if (is_sbn_valid(buffer)) - waypt->fix = decode_sbn_mode(buffer + 3); - else - waypt->fix = fix_none; - - decode_sbn_datetime(buffer + 10, waypt); - decode_sbn_position(buffer + 22, waypt); - WAYPT_SET(waypt, speed, be_read16(buffer + 39) * 0.01f); - WAYPT_SET(waypt, course, be_read16(buffer + 41) * 0.01f); - waypt->sat = buffer[87]; - waypt->hdop = buffer[88] * 0.2f; - - return waypt; + waypoint *waypt = NULL; + waypt = waypt_new(); + + if (is_sbn_valid(buffer)) { + waypt->fix = decode_sbn_mode(buffer + 3); + } else { + waypt->fix = fix_none; + } + + decode_sbn_datetime(buffer + 10, waypt); + decode_sbn_position(buffer + 22, waypt); + WAYPT_SET(waypt, speed, be_read16(buffer + 39) * 0.01f); + WAYPT_SET(waypt, course, be_read16(buffer + 41) * 0.01f); + waypt->sat = buffer[87]; + waypt->hdop = buffer[88] * 0.2f; + + return waypt; } static void add_logpoints(route_head *track) { - unsigned char buffer[SBN_RECORD_LEN]; - int type = 0; - - while (read_packet(&type, buffer, sizeof(buffer))) { - if (type == PID_SBN) { - track_add_wpt(track, decode_sbn_record(buffer)); - } else if (type == PID_VISIBLE_LIST) { - /* A list of visible SVs, their IDs, azimuths, elevations. - * Not storing this info for now. */ - } else { - warning(MYNAME ": Format error: Unknown packet type 0x%02x.\n", type); - } - } + unsigned char buffer[SBN_RECORD_LEN]; + int type = 0; + + while (read_packet(&type, buffer, sizeof(buffer))) { + if (type == PID_SBN) { + track_add_wpt(track, decode_sbn_record(buffer)); + } else if (type == PID_VISIBLE_LIST) { + /* A list of visible SVs, their IDs, azimuths, elevations. + * Not storing this info for now. */ + } else { + warning(MYNAME ": Format error: Unknown packet type 0x%02x.\n", type); + } + } } /**********************************************************************/ @@ -279,28 +282,28 @@ add_logpoints(route_head *track) static void sbn_rd_init(const char *fname) { - file_handle = gbfopen(fname, "r", MYNAME); + file_handle = gbfopen(fname, "r", MYNAME); } -static void +static void sbn_rd_deinit(void) { - gbfclose(file_handle); + gbfclose(file_handle); } static void sbn_read(void) { - if (global_opts.masked_objective & TRKDATAMASK) { - route_head *track; - - track = route_head_alloc(); - track_add_head(track); + if (global_opts.masked_objective & TRKDATAMASK) { + route_head *track; + + track = route_head_alloc(); + track_add_head(track); - read_sbn_header(track); + read_sbn_header(track); - add_logpoints(track); - } + add_logpoints(track); + } } static void @@ -311,22 +314,22 @@ sbn_exit(void) /**********************************************************************/ ff_vecs_t sbn_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - sbn_rd_init, - NULL, - sbn_rd_deinit, - NULL, - sbn_read, - NULL, - sbn_exit, - sbn_args, - /* Characters are always encoded in ASCII. Even if the unit is set - * to Chinese language, only ASCII characters can be entered. */ - CET_CHARSET_ASCII, 0 + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + sbn_rd_init, + NULL, + sbn_rd_deinit, + NULL, + sbn_read, + NULL, + sbn_exit, + sbn_args, + /* Characters are always encoded in ASCII. Even if the unit is set + * to Chinese language, only ASCII characters can be entered. */ + CET_CHARSET_ASCII, 0 }; /**********************************************************************/ diff --git a/gpsbabel/sbp.c b/gpsbabel/sbp.c index 1ec70597a..1daa00d4a 100644 --- a/gpsbabel/sbp.c +++ b/gpsbabel/sbp.c @@ -30,7 +30,7 @@ static gbfile *file_handle = NULL; static arglist_t sbp_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -40,76 +40,77 @@ arglist_t sbp_args[] = { static void sbp_rd_init(const char *fname) { - file_handle = gbfopen(fname, "r", MYNAME); + file_handle = gbfopen(fname, "r", MYNAME); } -static void +static void sbp_rd_deinit(void) { - gbfclose(file_handle); + gbfclose(file_handle); } static void read_sbp_header(route_head *track) { - /* - * A complete SBP file contains 64 bytes header, - * - * Here is the definition of the SBP header - * BYTE 0 ~1 : true SBP header length - * BYTE 2~63: MID_FILE_ID(0xfd) - * will stuff 0xff for remaining bytes - */ + /* + * A complete SBP file contains 64 bytes header, + * + * Here is the definition of the SBP header + * BYTE 0 ~1 : true SBP header length + * BYTE 2~63: MID_FILE_ID(0xfd) + * will stuff 0xff for remaining bytes + */ #define HEADER_SKIP 7 - int success; - char header[64]; + int success; + char header[64]; - if (gbfread(header, sizeof(header), 1, file_handle) == 1) { - size_t len = le_read16(header) - HEADER_SKIP; - if (len > sizeof(header)) - len = sizeof(header); + if (gbfread(header, sizeof(header), 1, file_handle) == 1) { + size_t len = le_read16(header) - HEADER_SKIP; + if (len > sizeof(header)) { + len = sizeof(header); + } - success = locosys_decode_file_id(header + HEADER_SKIP, len); - } else { - success = FALSE; - } + success = locosys_decode_file_id(header + HEADER_SKIP, len); + } else { + success = FALSE; + } - if (!success) { - fatal(MYNAME ": Format error: Couldn't read SBP header." - "This probably isn't a SBP file.\n"); - } + if (!success) { + fatal(MYNAME ": Format error: Couldn't read SBP header." + "This probably isn't a SBP file.\n"); + } } static waypoint * read_logpoint(void) { - unsigned char buffer[SBP_RECORD_LEN]; + unsigned char buffer[SBP_RECORD_LEN]; - if (gbfread(buffer, sizeof(buffer), 1, file_handle) == 1) { - return navilink_decode_logpoint(buffer); - } + if (gbfread(buffer, sizeof(buffer), 1, file_handle) == 1) { + return navilink_decode_logpoint(buffer); + } - return NULL; + return NULL; } static void sbp_read(void) { - if (global_opts.masked_objective & TRKDATAMASK) { - waypoint *logpoint; - route_head *track; - - track = route_head_alloc(); - track_add_head(track); - - read_sbp_header(track); - - while ((logpoint = read_logpoint())) { - track_add_wpt(track, logpoint); - } - } + if (global_opts.masked_objective & TRKDATAMASK) { + waypoint *logpoint; + route_head *track; + + track = route_head_alloc(); + track_add_head(track); + + read_sbp_header(track); + + while ((logpoint = read_logpoint())) { + track_add_wpt(track, logpoint); + } + } } static void @@ -120,21 +121,21 @@ sbp_exit(void) /**************************************************************************/ ff_vecs_t sbp_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - sbp_rd_init, - NULL, - sbp_rd_deinit, - NULL, - sbp_read, - NULL, - sbp_exit, - sbp_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + sbp_rd_init, + NULL, + sbp_rd_deinit, + NULL, + sbp_read, + NULL, + sbp_exit, + sbp_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/session.c b/gpsbabel/session.c index 0ef0e4396..9c1a3cf87 100644 --- a/gpsbabel/session.c +++ b/gpsbabel/session.c @@ -30,45 +30,47 @@ static void session_free(session_t *s); void session_init(void) { - QUEUE_INIT(&session_list); - session_ct = 0; + QUEUE_INIT(&session_list); + session_ct = 0; } void session_exit(void) { - queue *elem, *tmp; - - QUEUE_FOR_EACH(&session_list, elem, tmp) { - session_t *s = (session_t *)elem; - dequeue(&s->Q); - session_free(s); - } + queue *elem, *tmp; + + QUEUE_FOR_EACH(&session_list, elem, tmp) { + session_t *s = (session_t *)elem; + dequeue(&s->Q); + session_free(s); + } } void start_session(const char *name, const char *filename) { - session_t *s; - - if (session_ct == 0) QUEUE_INIT(&session_list); - session_ct++; - - s = (session_t*) xcalloc(1, sizeof(*s)); - ENQUEUE_TAIL(&session_list, &s->Q); - QUEUE_INIT(&s->category_list); - s->nr = session_ct; - s->name = name; - s->filename = xstrdup(filename); + session_t *s; + + if (session_ct == 0) { + QUEUE_INIT(&session_list); + } + session_ct++; + + s = (session_t*) xcalloc(1, sizeof(*s)); + ENQUEUE_TAIL(&session_list, &s->Q); + QUEUE_INIT(&s->category_list); + s->nr = session_ct; + s->name = name; + s->filename = xstrdup(filename); } session_t * curr_session(void) { - return (session_t *) session_list.prev; + return (session_t *) session_list.prev; } -/* in work +/* in work int session_add_category(const char *name, const int id) @@ -78,24 +80,24 @@ session_add_category(const char *name, const int id) category_t *c; s = curr_session(); - + QUEUE_FOR_EACH(&s->category_list, elem, tmp) { c = (category_t *) elem; if (case_ignore_strcmp(c->name, name) == 0) { if (id >= 0) c->id = id; return c->id; } - + } - + c = xmalloc(sizeof(*c)); c->name = xstrdup(name); if (id < 0) c->id = -(++s->unknown_category_ct); else c->id = id; - + s->category_ct++; ENQUEUE_TAIL(&s->category_list, &c->Q); - + return c->id; } */ @@ -105,12 +107,12 @@ session_add_category(const char *name, const int id) static void session_free(session_t *s) { - queue *elem, *tmp; - QUEUE_FOR_EACH(&s->category_list, elem, tmp) { - category_t *c = (category_t *) elem; - dequeue(&c->Q); - xfree(c); - } - xfree(s->filename); - xfree(s); + queue *elem, *tmp; + QUEUE_FOR_EACH(&s->category_list, elem, tmp) { + category_t *c = (category_t *) elem; + dequeue(&c->Q); + xfree(c); + } + xfree(s->filename); + xfree(s); } diff --git a/gpsbabel/session.h b/gpsbabel/session.h index 85be21fe9..134f0ca21 100644 --- a/gpsbabel/session.h +++ b/gpsbabel/session.h @@ -23,19 +23,19 @@ #define SESSION_H typedef struct { - queue Q; - int id; - char *name; + queue Q; + int id; + char *name; } category_t; typedef struct { - queue Q; - int nr; - const char *name; /* in normal case the name of a format */ - char *filename; /* used file within format */ - int category_ct; - int unknown_category_ct; /* added without id */ - queue category_list; + queue Q; + int nr; + const char *name; /* in normal case the name of a format */ + char *filename; /* used file within format */ + int category_ct; + int unknown_category_ct; /* added without id */ + queue category_list; } session_t; void session_init(void); diff --git a/gpsbabel/shape.c b/gpsbabel/shape.c index 7e14ecec4..e8b6269ae 100644 --- a/gpsbabel/shape.c +++ b/gpsbabel/shape.c @@ -1,5 +1,5 @@ -/* - +/* + ESRI shp/shx shapefiles. Copyright (C) 2003 Robert Lipe, robertlipe@usa.net @@ -41,299 +41,316 @@ static char *opt_url = NULL; static arglist_t shp_args[] = { - {"name", &opt_name, "Index of name field in .dbf", - NULL, ARGTYPE_STRING, "0", NULL }, - {"url", &opt_url, "Index of URL field in .dbf", - NULL, ARGTYPE_INT, "0", NULL }, - ARG_TERMINATOR + { + "name", &opt_name, "Index of name field in .dbf", + NULL, ARGTYPE_STRING, "0", NULL + }, + { + "url", &opt_url, "Index of URL field in .dbf", + NULL, ARGTYPE_INT, "0", NULL + }, + ARG_TERMINATOR }; static void my_rd_init(const char *fname) { - ihandle = SHPOpen(fname, "rb" ); - if (ihandle == NULL) { - fatal(MYNAME ":Cannot open shp file %s for reading\n", fname); - } - - ihandledb = DBFOpen(fname, "rb" ); - if (ihandledb == NULL) { - fatal(MYNAME ":Cannot open dbf file %s for reading\n", fname); - } - - if ( opt_name ) { - if ( opt_name[0] == '?' ) { - int nFields = 0; - int i = 0; - char name[12]; - char *txt = xstrdup(" Database fields\n"); - nFields = DBFGetFieldCount( ihandledb ); - for ( i = 0; i < nFields; i++ ) { - char txtName[50]; - DBFGetFieldInfo( ihandledb, i, name, NULL, NULL); - sprintf( txtName,"%2d %s\n", i, name ); - txt = xstrappend( txt, txtName ); - } - txt = xstrappend( txt, "\n" ); - fatal("%s", txt); - } - if ( strchr(opt_name, '+')) { - nameidx = -2; - } - else if ( opt_name[0] >= '0' && opt_name[0] <= '9' ) { - nameidx = atoi( opt_name ); - } - else { - nameidx = DBFGetFieldIndex( ihandledb, opt_name ); - if (nameidx == -1) { - fatal(MYNAME ":dbf file for %s doesn't have '%s' field.\n", fname, opt_name); - } - } - } - else { - nameidx = DBFGetFieldIndex( ihandledb, "NAME" ); - if (nameidx == -1) { + ihandle = SHPOpen(fname, "rb"); + if (ihandle == NULL) { + fatal(MYNAME ":Cannot open shp file %s for reading\n", fname); + } + + ihandledb = DBFOpen(fname, "rb"); + if (ihandledb == NULL) { + fatal(MYNAME ":Cannot open dbf file %s for reading\n", fname); + } + + if (opt_name) { + if (opt_name[0] == '?') { + int nFields = 0; + int i = 0; + char name[12]; + char *txt = xstrdup(" Database fields\n"); + nFields = DBFGetFieldCount(ihandledb); + for (i = 0; i < nFields; i++) { + char txtName[50]; + DBFGetFieldInfo(ihandledb, i, name, NULL, NULL); + sprintf(txtName,"%2d %s\n", i, name); + txt = xstrappend(txt, txtName); + } + txt = xstrappend(txt, "\n"); + fatal("%s", txt); + } + if (strchr(opt_name, '+')) { + nameidx = -2; + } else if (opt_name[0] >= '0' && opt_name[0] <= '9') { + nameidx = atoi(opt_name); + } else { + nameidx = DBFGetFieldIndex(ihandledb, opt_name); + if (nameidx == -1) { + fatal(MYNAME ":dbf file for %s doesn't have '%s' field.\n", fname, opt_name); + } + } + } else { + nameidx = DBFGetFieldIndex(ihandledb, "NAME"); + if (nameidx == -1) { // fatal(MYNAME ":dbf file for %s doesn't have 'NAME' field.\n Please specify the name index with the 'name' option.\n", fname); - } - } - if ( opt_url ) { - if ( opt_url[0] >= '0' && opt_url[0] <= '9' ) { - urlidx = atoi( opt_url ); - } - else { - urlidx = DBFGetFieldIndex( ihandledb, opt_url ); - } - } - else { - urlidx = DBFGetFieldIndex( ihandledb, "URL" ); - } + } + } + if (opt_url) { + if (opt_url[0] >= '0' && opt_url[0] <= '9') { + urlidx = atoi(opt_url); + } else { + urlidx = DBFGetFieldIndex(ihandledb, opt_url); + } + } else { + urlidx = DBFGetFieldIndex(ihandledb, "URL"); + } } void my_read(void) { - int npts; - char *etype = "unknown"; - - SHPGetInfo(ihandle, &npts, NULL, NULL, NULL); - - while (npts) { - SHPObject *shp; - waypoint *wpt; - const char *name = ""; - const char *url; - char *tmpName = NULL; - char *tmpIndex = opt_name; - - shp = SHPReadObject(ihandle, npts-1); - if ( nameidx >0 ) { - name = DBFReadStringAttribute(ihandledb, npts-1, nameidx); - } - else { - if ( nameidx == -1 ) { - name = ""; - } - else if (nameidx == -2 ) { - tmpName = xstrdup( "" ); - tmpIndex = opt_name; - while ( tmpIndex ) { - char *tmp2 = tmpIndex; - tmpIndex = strchr(tmpIndex,'+'); - if ( tmpIndex ) { - *tmpIndex = '\0'; - tmpIndex++; - } - if( tmp2[0]>='0' && tmp2[0]<='9' ) { - name = DBFReadStringAttribute( - ihandledb, npts-1, atoi(tmp2)); - } - else { - int idx = 0; - idx = DBFGetFieldIndex( ihandledb, tmp2); - if ( idx >= 0 ) { - name = DBFReadStringAttribute( - ihandledb, npts-1, idx); - } - } - - tmpName = xstrappend(tmpName, name ); - if ( tmpIndex ) { - tmpName = xstrappend( tmpName, " / " ); - } - } - name = tmpName; - } - } - if ( urlidx > 0 ) { - url = DBFReadStringAttribute( ihandledb, npts-1, urlidx); - } - else { - url = NULL; - } - switch (shp->nSHPType) { - case SHPT_ARC: { - int j; - route_head *routehead = route_head_alloc(); - routehead->rte_name = xstrdup(name); - route_add_head(routehead); - for (j = 0; j < shp->nVertices; j++) { - wpt = waypt_new(); - wpt->latitude = shp->padfY[j]; - wpt->longitude = shp->padfX[j]; - wpt->altitude = shp->padfZ[j]; - route_add_wpt(routehead, wpt); - } - } - break; - - case SHPT_POINT: - wpt = waypt_new(); - wpt->latitude = shp->dfYMin; - wpt->longitude = shp->dfXMin; - wpt->shortname = xstrdup(name); - if ( url ) { - wpt->url = xstrdup(url); - } - waypt_add(wpt); - break; - case SHPT_POLYGON: etype = "polygon"; goto err; - case SHPT_MULTIPOINT: etype = "multipoint"; goto err; - case SHPT_POINTZ: etype = "pointz" ; goto err; - case SHPT_ARCZ: etype = "arcz" ; goto err; - case SHPT_POLYGONZ: etype = "polygonz" ; goto err; - case SHPT_MULTIPOINTZ: etype = "multipointz" ; goto err; - case SHPT_POINTM: etype = "pointm" ; goto err; - case SHPT_ARCM: etype = "arcm" ; goto err; - case SHPT_POLYGONM: etype = "polygonm" ; goto err; - case SHPT_MULTIPOINTM: etype = "multipointm" ; goto err; - case SHPT_MULTIPATCH: etype = "multipatch" ; goto err; - default: - - err: - warning("This file contains shapefile geometry type %s that does not naturally convert\nCustom programming is likely required.\n", - etype); - break; - } - - SHPDestroyObject(shp); - - npts--; - if ( tmpName ) { - xfree( tmpName ); - tmpName = NULL; - } - } + int npts; + char *etype = "unknown"; + + SHPGetInfo(ihandle, &npts, NULL, NULL, NULL); + + while (npts) { + SHPObject *shp; + waypoint *wpt; + const char *name = ""; + const char *url; + char *tmpName = NULL; + char *tmpIndex = opt_name; + + shp = SHPReadObject(ihandle, npts-1); + if (nameidx >0) { + name = DBFReadStringAttribute(ihandledb, npts-1, nameidx); + } else { + if (nameidx == -1) { + name = ""; + } else if (nameidx == -2) { + tmpName = xstrdup(""); + tmpIndex = opt_name; + while (tmpIndex) { + char *tmp2 = tmpIndex; + tmpIndex = strchr(tmpIndex,'+'); + if (tmpIndex) { + *tmpIndex = '\0'; + tmpIndex++; + } + if (tmp2[0]>='0' && tmp2[0]<='9') { + name = DBFReadStringAttribute( + ihandledb, npts-1, atoi(tmp2)); + } else { + int idx = 0; + idx = DBFGetFieldIndex(ihandledb, tmp2); + if (idx >= 0) { + name = DBFReadStringAttribute( + ihandledb, npts-1, idx); + } + } + + tmpName = xstrappend(tmpName, name); + if (tmpIndex) { + tmpName = xstrappend(tmpName, " / "); + } + } + name = tmpName; + } + } + if (urlidx > 0) { + url = DBFReadStringAttribute(ihandledb, npts-1, urlidx); + } else { + url = NULL; + } + switch (shp->nSHPType) { + case SHPT_ARC: { + int j; + route_head *routehead = route_head_alloc(); + routehead->rte_name = xstrdup(name); + route_add_head(routehead); + for (j = 0; j < shp->nVertices; j++) { + wpt = waypt_new(); + wpt->latitude = shp->padfY[j]; + wpt->longitude = shp->padfX[j]; + wpt->altitude = shp->padfZ[j]; + route_add_wpt(routehead, wpt); + } + } + break; + + case SHPT_POINT: + wpt = waypt_new(); + wpt->latitude = shp->dfYMin; + wpt->longitude = shp->dfXMin; + wpt->shortname = xstrdup(name); + if (url) { + wpt->url = xstrdup(url); + } + waypt_add(wpt); + break; + case SHPT_POLYGON: + etype = "polygon"; + goto err; + case SHPT_MULTIPOINT: + etype = "multipoint"; + goto err; + case SHPT_POINTZ: + etype = "pointz" ; + goto err; + case SHPT_ARCZ: + etype = "arcz" ; + goto err; + case SHPT_POLYGONZ: + etype = "polygonz" ; + goto err; + case SHPT_MULTIPOINTZ: + etype = "multipointz" ; + goto err; + case SHPT_POINTM: + etype = "pointm" ; + goto err; + case SHPT_ARCM: + etype = "arcm" ; + goto err; + case SHPT_POLYGONM: + etype = "polygonm" ; + goto err; + case SHPT_MULTIPOINTM: + etype = "multipointm" ; + goto err; + case SHPT_MULTIPATCH: + etype = "multipatch" ; + goto err; + default: + +err: + warning("This file contains shapefile geometry type %s that does not naturally convert\nCustom programming is likely required.\n", + etype); + break; + } + + SHPDestroyObject(shp); + + npts--; + if (tmpName) { + xfree(tmpName); + tmpName = NULL; + } + } } void my_rd_deinit(void) { - SHPClose (ihandle); + SHPClose(ihandle); } void my_wr_init(const char *fname) { - ofname = fname; + ofname = fname; } void my_wr_deinit(void) { - SHPClose (ohandle); + SHPClose(ohandle); } void my_write_wpt(const waypoint *wpt) { - SHPObject *shpobject; - - shpobject = SHPCreateSimpleObject(SHPT_POINT, 1, - (double *)(void *)&wpt->longitude, - (double *)(void *)&wpt->latitude, - (double *)(void *)&wpt->altitude); - SHPWriteObject(ohandle, -1, shpobject); - SHPDestroyObject(shpobject); + SHPObject *shpobject; + + shpobject = SHPCreateSimpleObject(SHPT_POINT, 1, + (double *)(void *)&wpt->longitude, + (double *)(void *)&wpt->latitude, + (double *)(void *)&wpt->altitude); + SHPWriteObject(ohandle, -1, shpobject); + SHPDestroyObject(shpobject); } void poly_init(const route_head *h) { - int ct = track_waypt_count(); - polybufx = xcalloc(ct, sizeof(double)); - polybufy = xcalloc(ct, sizeof(double)); - polybufz = xcalloc(ct, sizeof(double)); + int ct = track_waypt_count(); + polybufx = xcalloc(ct, sizeof(double)); + polybufy = xcalloc(ct, sizeof(double)); + polybufz = xcalloc(ct, sizeof(double)); } -void +void poly_point(const waypoint *wpt) { - polybufx[poly_count] = wpt->longitude; - polybufy[poly_count] = wpt->latitude; - polybufz[poly_count] = wpt->altitude; - poly_count++; + polybufx[poly_count] = wpt->longitude; + polybufy[poly_count] = wpt->latitude; + polybufz[poly_count] = wpt->altitude; + poly_count++; } void poly_deinit(const route_head *h) { - SHPObject *shpobject; - shpobject = SHPCreateSimpleObject(SHPT_ARC, track_waypt_count(), - polybufx, polybufy, polybufz); - SHPWriteObject(ohandle, -1, shpobject); - SHPDestroyObject(shpobject); - xfree(polybufx); - xfree(polybufy); - xfree(polybufz); - fprintf(stderr, "Done\n"); - poly_count = 0; + SHPObject *shpobject; + shpobject = SHPCreateSimpleObject(SHPT_ARC, track_waypt_count(), + polybufx, polybufy, polybufz); + SHPWriteObject(ohandle, -1, shpobject); + SHPDestroyObject(shpobject); + xfree(polybufx); + xfree(polybufy); + xfree(polybufz); + fprintf(stderr, "Done\n"); + poly_count = 0; } void my_write(void) { - switch(global_opts.objective) { - case wptdata: - ohandle = SHPCreate(ofname, SHPT_POINT); - - if (ohandle == NULL) { - fatal(MYNAME ":Cannot open %s for writing\n", - ofname); - } - waypt_disp_all(my_write_wpt); - break; - case trkdata: - ohandle = SHPCreate(ofname, SHPT_ARC); - - if (ohandle == NULL) { - fatal(MYNAME ":Cannot open %s for writing\n", - ofname); - } - route_disp_all(poly_init, poly_deinit, poly_point); - break; - case rtedata: - fatal(MYNAME ": Routes are not supported\n"); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported\n"); - break; - } + switch (global_opts.objective) { + case wptdata: + ohandle = SHPCreate(ofname, SHPT_POINT); + + if (ohandle == NULL) { + fatal(MYNAME ":Cannot open %s for writing\n", + ofname); + } + waypt_disp_all(my_write_wpt); + break; + case trkdata: + ohandle = SHPCreate(ofname, SHPT_ARC); + + if (ohandle == NULL) { + fatal(MYNAME ":Cannot open %s for writing\n", + ofname); + } + route_disp_all(poly_init, poly_deinit, poly_point); + break; + case rtedata: + fatal(MYNAME ": Routes are not supported\n"); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported\n"); + break; + } } ff_vecs_t shape_vecs = { - ff_type_internal, - FF_CAP_RW_ALL, - my_rd_init, - my_wr_init, - my_rd_deinit, - my_wr_deinit, - my_read, - my_write, - NULL, - shp_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_internal, + FF_CAP_RW_ALL, + my_rd_init, + my_wr_init, + my_rd_deinit, + my_wr_deinit, + my_read, + my_write, + NULL, + shp_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; #endif /* SHAPELIB_ENABLED */ diff --git a/gpsbabel/skyforce.c b/gpsbabel/skyforce.c index 6d6cf3746..e6e7ae37d 100644 --- a/gpsbabel/skyforce.c +++ b/gpsbabel/skyforce.c @@ -32,7 +32,7 @@ static arglist_t skyforce_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static gbfile *fin, *fout; @@ -44,160 +44,194 @@ static const waypoint *prev_wpt; static waypoint * skyforce_parse_coords(const char *str) { - waypoint *wpt; + waypoint *wpt; - if (strlen(str) < 38) fatal(MYNAME ": Incomplete line!\n"); + if (strlen(str) < 38) { + fatal(MYNAME ": Incomplete line!\n"); + } - wpt = waypt_new(); + wpt = waypt_new(); - wpt->latitude = atof(str + 21); - if (str[20] == 'S') wpt->latitude = -wpt->latitude; - wpt->latitude = ddmm2degrees(wpt->latitude); + wpt->latitude = atof(str + 21); + if (str[20] == 'S') { + wpt->latitude = -wpt->latitude; + } + wpt->latitude = ddmm2degrees(wpt->latitude); - wpt->longitude = atof(str + 30); - if (str[29] == 'W') wpt->longitude = -wpt->longitude; - wpt->longitude = ddmm2degrees(wpt->longitude); + wpt->longitude = atof(str + 30); + if (str[29] == 'W') { + wpt->longitude = -wpt->longitude; + } + wpt->longitude = ddmm2degrees(wpt->longitude); - return wpt; + return wpt; } static waypoint * skyforce_parse_wpt(const char *str, int *rte_num) { - waypoint *wpt; + waypoint *wpt; - wpt = skyforce_parse_coords(str); - if (wpt == NULL) return NULL; + wpt = skyforce_parse_coords(str); + if (wpt == NULL) { + return NULL; + } - wpt->shortname = lrtrim(xstrndup(str + 10, 9)); + wpt->shortname = lrtrim(xstrndup(str + 10, 9)); - if (rte_num) *rte_num = atoi(str + 2); + if (rte_num) { + *rte_num = atoi(str + 2); + } - return wpt; + return wpt; } static waypoint * skyforce_parse_trk(const char *str) { - char *cx; - struct tm tm; - char buf[15]; - int len; - - waypoint *wpt; - - wpt = skyforce_parse_coords(str); - if (wpt == NULL) return NULL; - - memset(&tm, 0, sizeof(tm)); - strncpy(buf, str + 2, sizeof(buf) - 1); - buf[14] = 0; - - cx = strptime(buf, "%d%m%y %H%M%S ", &tm); - if ((cx != NULL) && (*cx != '\0')) - fatal(MYNAME ": Could not parse date string (%s - %s).\n", buf, cx); - - wpt->creation_time = mkgmtime(&tm); - - len = strlen(str); - - if (len >= 45) WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(str + 39))); - if (len >= 59) { - wpt->altitude = FEET_TO_METERS(atof(str + 54)); - if (str[53] == '-') wpt->altitude = -wpt->altitude; - } - - return wpt; + char *cx; + struct tm tm; + char buf[15]; + int len; + + waypoint *wpt; + + wpt = skyforce_parse_coords(str); + if (wpt == NULL) { + return NULL; + } + + memset(&tm, 0, sizeof(tm)); + strncpy(buf, str + 2, sizeof(buf) - 1); + buf[14] = 0; + + cx = strptime(buf, "%d%m%y %H%M%S ", &tm); + if ((cx != NULL) && (*cx != '\0')) { + fatal(MYNAME ": Could not parse date string (%s - %s).\n", buf, cx); + } + + wpt->creation_time = mkgmtime(&tm); + + len = strlen(str); + + if (len >= 45) { + WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(str + 39))); + } + if (len >= 59) { + wpt->altitude = FEET_TO_METERS(atof(str + 54)); + if (str[53] == '-') { + wpt->altitude = -wpt->altitude; + } + } + + return wpt; } static void skyforce_head_disp_cb(const route_head *head) { - prev_wpt = NULL; - if (head->rte_waypt_ct <= 0) return; - - wpt_num = 0; - rte_num++; - - if (rte_num > 999) { - if (rte_num == 1000) warning(MYNAME ": Can't store more than 999 routes. Some routes skipped!\n"); - return; - } + prev_wpt = NULL; + if (head->rte_waypt_ct <= 0) { + return; + } + + wpt_num = 0; + rte_num++; + + if (rte_num > 999) { + if (rte_num == 1000) { + warning(MYNAME ": Can't store more than 999 routes. Some routes skipped!\n"); + } + return; + } } static void skyforce_waypt_disp_cb(const waypoint *wpt) { - char buf[75]; /* long enough for all data types */ - double lat, lon; - - - memset(buf, ' ', sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; - - switch(global_opts.objective) { - case wptdata: buf[0] = 'W'; break; - case trkdata: buf[0] = 'L'; break; - case rtedata: buf[0] = 'R'; break; - default: ; /* should never happen */ - } - - if (global_opts.objective == trkdata) { - struct tm tm; - - tm = *gmtime(&wpt->creation_time); - strftime(buf + 2, sizeof(buf) - 2, "%d%m%y %H%M%S ", &tm); - } - else { - char *name; - - if (rte_num > 999) return; - - wpt_num++; - if (wpt_num > 999) { - if (wpt_num == 1000) - warning(MYNAME ": Can't store more than 999 waypoints. Some waypoints skipped!\n"); - return; - } - if (global_opts.synthesize_shortnames) - name = mkshort_from_wpt(short_h, wpt); - else - name = mkshort(short_h, wpt->shortname); - - if (global_opts.objective == rtedata) - snprintf(buf + 2, sizeof(buf) - 2, "%03d ", rte_num); - snprintf(buf + 6, sizeof(buf) - 6, "%03d %-9s ", wpt_num, name); - } - - - lat = degrees2ddmm(wpt->latitude); - buf[20] = (wpt->latitude < 0) ? 'S' : 'N'; - snprintf(&buf[21], sizeof(buf) - 21, "%06.2f ", fabs(lat)); - - lon = degrees2ddmm(wpt->longitude); - buf[29] = (wpt->longitude < 0) ? 'W' : 'E'; - snprintf(&buf[30], sizeof(buf) - 30, "%08.2f ", fabs(lon)); - - if (global_opts.objective == trkdata) { - double alt, speed; - - if (wpt->altitude == unknown_alt) alt = 0; - else alt = METERS_TO_FEET(wpt->altitude); - speed = MPS_TO_KNOTS(waypt_speed(prev_wpt, wpt)); - - snprintf(&buf[39], sizeof(buf) - 39, "%06.2f 000.00 %c%05d", - speed, - alt < 0 ? '-' : '+', si_round(fabs(alt))); - } - - rtrim(buf); - gbfprintf(fout, "%s\n", buf); - - prev_wpt = wpt; + char buf[75]; /* long enough for all data types */ + double lat, lon; + + + memset(buf, ' ', sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; + + switch (global_opts.objective) { + case wptdata: + buf[0] = 'W'; + break; + case trkdata: + buf[0] = 'L'; + break; + case rtedata: + buf[0] = 'R'; + break; + default: ; /* should never happen */ + } + + if (global_opts.objective == trkdata) { + struct tm tm; + + tm = *gmtime(&wpt->creation_time); + strftime(buf + 2, sizeof(buf) - 2, "%d%m%y %H%M%S ", &tm); + } else { + char *name; + + if (rte_num > 999) { + return; + } + + wpt_num++; + if (wpt_num > 999) { + if (wpt_num == 1000) { + warning(MYNAME ": Can't store more than 999 waypoints. Some waypoints skipped!\n"); + } + return; + } + if (global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(short_h, wpt); + } else { + name = mkshort(short_h, wpt->shortname); + } + + if (global_opts.objective == rtedata) { + snprintf(buf + 2, sizeof(buf) - 2, "%03d ", rte_num); + } + snprintf(buf + 6, sizeof(buf) - 6, "%03d %-9s ", wpt_num, name); + } + + + lat = degrees2ddmm(wpt->latitude); + buf[20] = (wpt->latitude < 0) ? 'S' : 'N'; + snprintf(&buf[21], sizeof(buf) - 21, "%06.2f ", fabs(lat)); + + lon = degrees2ddmm(wpt->longitude); + buf[29] = (wpt->longitude < 0) ? 'W' : 'E'; + snprintf(&buf[30], sizeof(buf) - 30, "%08.2f ", fabs(lon)); + + if (global_opts.objective == trkdata) { + double alt, speed; + + if (wpt->altitude == unknown_alt) { + alt = 0; + } else { + alt = METERS_TO_FEET(wpt->altitude); + } + speed = MPS_TO_KNOTS(waypt_speed(prev_wpt, wpt)); + + snprintf(&buf[39], sizeof(buf) - 39, "%06.2f 000.00 %c%05d", + speed, + alt < 0 ? '-' : '+', si_round(fabs(alt))); + } + + rtrim(buf); + gbfprintf(fout, "%s\n", buf); + + prev_wpt = wpt; } /******************************************************************************* @@ -207,148 +241,156 @@ skyforce_waypt_disp_cb(const waypoint *wpt) static void skyforce_rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); } static void skyforce_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void skyforce_read(void) { - char *str; - route_head *rte, *trk; - - wpt_num = 0; - rte = trk = NULL; - rte_num = -1; - - while ((str = gbfgetstr(fin))) { - - waypoint *wpt; - int i; - - str = lrtrim(str); - if (*str == '\0') continue; - - switch(*str) { - - case 'W': - wpt = skyforce_parse_wpt(str, NULL); - if (wpt == NULL) continue; - waypt_add(wpt); - break; - - case 'R': - wpt = skyforce_parse_wpt(str, &i); - if (wpt == NULL) continue; - - if (i != rte_num) { - rte_num = i; - rte = NULL; - } - - if (rte == NULL) { - rte = route_head_alloc(); - route_add_head(rte); - rte->rte_num = rte_num; - } - route_add_wpt(rte, wpt); - break; - - case 'L': - wpt = skyforce_parse_trk(str); - if (wpt == NULL) continue; - if (trk == NULL) { - trk = route_head_alloc(); - track_add_head(trk); - } - track_add_wpt(trk, wpt); - break; - - default: - fatal(MYNAME ": Invalid line marker '%c'!\n", *str); - } - } + char *str; + route_head *rte, *trk; + + wpt_num = 0; + rte = trk = NULL; + rte_num = -1; + + while ((str = gbfgetstr(fin))) { + + waypoint *wpt; + int i; + + str = lrtrim(str); + if (*str == '\0') { + continue; + } + + switch (*str) { + + case 'W': + wpt = skyforce_parse_wpt(str, NULL); + if (wpt == NULL) { + continue; + } + waypt_add(wpt); + break; + + case 'R': + wpt = skyforce_parse_wpt(str, &i); + if (wpt == NULL) { + continue; + } + + if (i != rte_num) { + rte_num = i; + rte = NULL; + } + + if (rte == NULL) { + rte = route_head_alloc(); + route_add_head(rte); + rte->rte_num = rte_num; + } + route_add_wpt(rte, wpt); + break; + + case 'L': + wpt = skyforce_parse_trk(str); + if (wpt == NULL) { + continue; + } + if (trk == NULL) { + trk = route_head_alloc(); + track_add_head(trk); + } + track_add_wpt(trk, wpt); + break; + + default: + fatal(MYNAME ": Invalid line marker '%c'!\n", *str); + } + } } static void skyforce_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); + fout = gbfopen(fname, "w", MYNAME); - short_h = mkshort_new_handle(); + short_h = mkshort_new_handle(); - setshort_length(short_h, 9); - setshort_badchars(short_h, "\r\n\t"); - setshort_mustupper(short_h, 1); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 0); - setshort_repeating_whitespace_ok(short_h, 0); + setshort_length(short_h, 9); + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 1); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 0); + setshort_repeating_whitespace_ok(short_h, 0); - wpt_num = 0; - rte_num = 0; + wpt_num = 0; + rte_num = 0; } static void skyforce_wr_deinit(void) { - mkshort_del_handle(&short_h); - gbfclose(fout); + mkshort_del_handle(&short_h); + gbfclose(fout); } static void skyforce_write(void) { - switch(global_opts.objective) { /* We can only write one data type at a time */ - - case wptdata: - setshort_defname(short_h, "WPT"); - waypt_disp_all(skyforce_waypt_disp_cb); - break; - - case rtedata: - setshort_defname(short_h, "RTE"); - setshort_mustuniq(short_h, 0); - route_disp_all(skyforce_head_disp_cb, NULL, skyforce_waypt_disp_cb); - break; - - case trkdata: - track_disp_all(skyforce_head_disp_cb, NULL, skyforce_waypt_disp_cb); - break; - - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - - default: - fatal(MYNAME ": Unknown data mode!\n"); - } + switch (global_opts.objective) { /* We can only write one data type at a time */ + + case wptdata: + setshort_defname(short_h, "WPT"); + waypt_disp_all(skyforce_waypt_disp_cb); + break; + + case rtedata: + setshort_defname(short_h, "RTE"); + setshort_mustuniq(short_h, 0); + route_disp_all(skyforce_head_disp_cb, NULL, skyforce_waypt_disp_cb); + break; + + case trkdata: + track_disp_all(skyforce_head_disp_cb, NULL, skyforce_waypt_disp_cb); + break; + + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + + default: + fatal(MYNAME ": Unknown data mode!\n"); + } } /**************************************************************************/ ff_vecs_t skyforce_vecs = { - ff_type_file, - FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ - skyforce_rd_init, - skyforce_wr_init, - skyforce_rd_deinit, - skyforce_wr_deinit, - skyforce_read, - skyforce_write, - NULL, - skyforce_args, - CET_CHARSET_ASCII, 1 + ff_type_file, + FF_CAP_RW_ALL, /* read and write waypoints, tracks and routes*/ + skyforce_rd_init, + skyforce_wr_init, + skyforce_rd_deinit, + skyforce_wr_deinit, + skyforce_read, + skyforce_write, + NULL, + skyforce_args, + CET_CHARSET_ASCII, 1 }; /**************************************************************************/ diff --git a/gpsbabel/skytraq.c b/gpsbabel/skytraq.c index bd5362369..9299ed79b 100644 --- a/gpsbabel/skytraq.c +++ b/gpsbabel/skytraq.c @@ -70,150 +70,172 @@ static char *opt_set_location = 0; /* set if the "targetlocation" options was us static arglist_t skytraq_args[] = { - { "erase", &opt_erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "targetlocation", &opt_set_location, "Set location finder target location as lat,lng", - "", ARGTYPE_STRING, "", "" }, - { "baud", &opt_dlbaud, "Baud rate used for download", - "230400", ARGTYPE_INT, "0", "230400" }, - { "initbaud", &opt_initbaud, "Baud rate used to init device (0=autodetect)", - "0", ARGTYPE_INT, "4800", "230400" }, - { "read-at-once", &opt_read_at_once, "Number of sectors to read at once (0=use single sector mode)", - "255", ARGTYPE_INT, "0", "255" }, - { "first-sector", &opt_first_sector, "First sector to be read from the device", - "0", ARGTYPE_INT, "0", "65535" }, - { "last-sector", &opt_last_sector, "Last sector to be read from the device (-1: smart read everything)", - "-1", ARGTYPE_INT, "-1", "65535" }, - { "dump-file", &opt_dump_file, "Dump raw data to this file", - NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX }, - { "no-output", &opt_no_output, "Disable output (useful with erase)", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &opt_erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "targetlocation", &opt_set_location, "Set location finder target location as lat,lng", + "", ARGTYPE_STRING, "", "" + }, + { + "baud", &opt_dlbaud, "Baud rate used for download", + "230400", ARGTYPE_INT, "0", "230400" + }, + { + "initbaud", &opt_initbaud, "Baud rate used to init device (0=autodetect)", + "0", ARGTYPE_INT, "4800", "230400" + }, + { + "read-at-once", &opt_read_at_once, "Number of sectors to read at once (0=use single sector mode)", + "255", ARGTYPE_INT, "0", "255" + }, + { + "first-sector", &opt_first_sector, "First sector to be read from the device", + "0", ARGTYPE_INT, "0", "65535" + }, + { + "last-sector", &opt_last_sector, "Last sector to be read from the device (-1: smart read everything)", + "-1", ARGTYPE_INT, "-1", "65535" + }, + { + "dump-file", &opt_dump_file, "Dump raw data to this file", + NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX + }, + { + "no-output", &opt_no_output, "Disable output (useful with erase)", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static arglist_t skytraq_fargs[] = { - { "first-sector", &opt_first_sector, "First sector to be read from the file", - "0", ARGTYPE_INT, "0", "65535" }, - { "last-sector", &opt_last_sector, "Last sector to be read from the file (-1: read till empty sector)", - "-1", ARGTYPE_INT, "-1", "65535" }, - ARG_TERMINATOR + { + "first-sector", &opt_first_sector, "First sector to be read from the file", + "0", ARGTYPE_INT, "0", "65535" + }, + { + "last-sector", &opt_last_sector, "Last sector to be read from the file (-1: read till empty sector)", + "-1", ARGTYPE_INT, "-1", "65535" + }, + ARG_TERMINATOR }; static void db(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vprintf(msg, ap); - } - va_end(ap); + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); } static void rd_drain(void) { - if (gbser_flush(serial_handle)) { - db(1, MYNAME ": rd_drain(): Comm error\n"); - } + if (gbser_flush(serial_handle)) { + db(1, MYNAME ": rd_drain(): Comm error\n"); + } } static int rd_char(int *errors) { - int c; - while (*errors > 0) { - c = gbser_readc_wait(serial_handle, TIMEOUT); - if (c < 0) { - db(1, MYNAME ": rd_char(): Got error: %d\n", c); - (*errors)--; - } else { - db(4, "rd_char(): Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); - return c; - } - } - fatal(MYNAME ": Too many read errors on serial port\n"); - return -1; + int c; + while (*errors > 0) { + c = gbser_readc_wait(serial_handle, TIMEOUT); + if (c < 0) { + db(1, MYNAME ": rd_char(): Got error: %d\n", c); + (*errors)--; + } else { + db(4, "rd_char(): Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); + return c; + } + } + fatal(MYNAME ": Too many read errors on serial port\n"); + return -1; } static int rd_buf(const gbuint8 *buf, int len) { - int rc, timeout, i; - char dump[16*3+16+2]; - - /* Allow TIMEOUT plus the time needed to actually receive the data bytes: - * baudrate/10 bytes per second (8 data bits, start and stop bit) - * TODO: use dlbaud if selected. - */ - timeout = TIMEOUT + len;//*1000/(skytraq_baud/10); -/*TODO: timeout gets <0 e.g. when len~=250000 --> 32bit signed int is too small. - if (skytraq_baud > 0) timeout = TIMEOUT + (long long int)len*1000*10/(long long int)skytraq_baud; -printf("len=%i skytraq_baud=%i timeout=%i\n", len, skytraq_baud, timeout);*/ - rc = gbser_read_wait(serial_handle, (void*)buf, len, timeout); - if (rc < 0) { - db(1, MYNAME ": rd_buf(): Read error (%d)\n", rc); - return res_ERROR; - } else if (rc < len) { - db(1, MYNAME ": rd_buf(): Read timout\n"); - return res_ERROR; - } - - if (global_opts.debug_level >= 4) { - db(4, "rd_buf(): dump follows:\n"); - dump[sizeof(dump)-1] = 0; - for (i = 0; i < (len+15)/16*16; i++) { // count to next 16-byte boundary - if (i < len) { - snprintf(&dump[(i%16)*3], 4, "%02x ", buf[i]); - snprintf(&dump[3*16+1+(i%16)], 2, "%c", isprint(buf[i]) ? buf[i] : '.'); - } else { - memset(&dump[(i%16)*3], ' ', 3); - dump[3*16+1+(i%16)] = ' '; - } - if ((i+1)%16 == 0) { - dump[16*3] = ' '; // gets overwritten with 0 by snprintf - db(4, "%s\n", dump); - } - } - } - - return res_OK; + int rc, timeout, i; + char dump[16*3+16+2]; + + /* Allow TIMEOUT plus the time needed to actually receive the data bytes: + * baudrate/10 bytes per second (8 data bits, start and stop bit) + * TODO: use dlbaud if selected. + */ + timeout = TIMEOUT + len;//*1000/(skytraq_baud/10); + /*TODO: timeout gets <0 e.g. when len~=250000 --> 32bit signed int is too small. + if (skytraq_baud > 0) timeout = TIMEOUT + (long long int)len*1000*10/(long long int)skytraq_baud; + printf("len=%i skytraq_baud=%i timeout=%i\n", len, skytraq_baud, timeout);*/ + rc = gbser_read_wait(serial_handle, (void*)buf, len, timeout); + if (rc < 0) { + db(1, MYNAME ": rd_buf(): Read error (%d)\n", rc); + return res_ERROR; + } else if (rc < len) { + db(1, MYNAME ": rd_buf(): Read timout\n"); + return res_ERROR; + } + + if (global_opts.debug_level >= 4) { + db(4, "rd_buf(): dump follows:\n"); + dump[sizeof(dump)-1] = 0; + for (i = 0; i < (len+15)/16*16; i++) { // count to next 16-byte boundary + if (i < len) { + snprintf(&dump[(i%16)*3], 4, "%02x ", buf[i]); + snprintf(&dump[3*16+1+(i%16)], 2, "%c", isprint(buf[i]) ? buf[i] : '.'); + } else { + memset(&dump[(i%16)*3], ' ', 3); + dump[3*16+1+(i%16)] = ' '; + } + if ((i+1)%16 == 0) { + dump[16*3] = ' '; // gets overwritten with 0 by snprintf + db(4, "%s\n", dump); + } + } + } + + return res_OK; } static int rd_word(void) { - int errors = 5; /* allow this many errors */ - gbuint8 buffer[2]; + int errors = 5; /* allow this many errors */ + gbuint8 buffer[2]; - buffer[0] = rd_char(&errors); - buffer[1] = rd_char(&errors); -/* if (rd_buf(buffer, 2) != res_OK) { - db(1, MYNAME ": rd_word(): Read error\n"); - return res_ERROR; - }*/ + buffer[0] = rd_char(&errors); + buffer[1] = rd_char(&errors); + /* if (rd_buf(buffer, 2) != res_OK) { + db(1, MYNAME ": rd_word(): Read error\n"); + return res_ERROR; + }*/ - return (buffer[0] << 8) | buffer[1]; + return (buffer[0] << 8) | buffer[1]; } static void wr_char(int c) { - int rc; - db(4, "Sending: %02x '%c'\n", (unsigned)c, isprint(c) ? c : '.'); - if (rc = gbser_writec(serial_handle, c), gbser_OK != rc) { - fatal(MYNAME ": Write error (%d)\n", rc); - } + int rc; + db(4, "Sending: %02x '%c'\n", (unsigned)c, isprint(c) ? c : '.'); + if (rc = gbser_writec(serial_handle, c), gbser_OK != rc) { + fatal(MYNAME ": Write error (%d)\n", rc); + } } static void wr_buf(const unsigned char *str, int len) { - int i; - for (i = 0; i < len; i++) { - wr_char(str[i]); - } + int i; + for (i = 0; i < len; i++) { + wr_char(str[i]); + } } /******************************************************************************* @@ -227,372 +249,373 @@ gbuint8 SECTOR_READ_END[13] = "END\0CHECKSUM="; static int skytraq_calc_checksum(const unsigned char *buf, int len) { - int i, cs = 0; - for (i = 0; i < len; i++) { - cs ^= buf[i]; - } - return cs; + int i, cs = 0; + for (i = 0; i < len; i++) { + cs ^= buf[i]; + } + return cs; } static int skytraq_rd_msg(const void *payload, int len) { - int errors = 5; /* allow this many errors */ - int c, i, state; - int rcv_len, calc_cs, rcv_cs; - - for (i = 0, state = 0; i < RETRIES && state < sizeof(MSG_START); i++) { - c = rd_char(&errors); - if (c == MSG_START[state]) { - state++; - } else if (c == MSG_START[0]) { - state = 1; - } else { - state = 0; - } - } - if (state < sizeof(MSG_START)) { - db(1, MYNAME ": Didn't get message start tag\n"); - return res_ERROR; - } - - if ((rcv_len = rd_word()) < len) { - if (rcv_len >= 0) { /* negative values indicate receive errors */ - db(1, MYNAME ": Received message too short (got %i bytes, expected %i)\n", - rcv_len, len); - return res_PROTOCOL_ERR; - } - return res_ERROR; - } - - db(2, "Receiving message with %i bytes of payload (expected >=%i)\n", rcv_len, len); - rd_buf(payload, MIN(rcv_len, len)); - - calc_cs = skytraq_calc_checksum(payload, MIN(rcv_len, len)); - for (i = 0; i < rcv_len-len; i++) { - c = rd_char(&errors); - calc_cs ^= c; - } - - rcv_cs = rd_char(&errors); - if (rcv_cs != calc_cs) { - fatal(MYNAME ": Checksum error: got 0x%02x, expected 0x%02x\n", rcv_cs, calc_cs); - } - - if (rd_word() != 0x0D0A) { - fatal(MYNAME ": Didn't get message end tag (CR/LF)\n"); - } + int errors = 5; /* allow this many errors */ + int c, i, state; + int rcv_len, calc_cs, rcv_cs; + + for (i = 0, state = 0; i < RETRIES && state < sizeof(MSG_START); i++) { + c = rd_char(&errors); + if (c == MSG_START[state]) { + state++; + } else if (c == MSG_START[0]) { + state = 1; + } else { + state = 0; + } + } + if (state < sizeof(MSG_START)) { + db(1, MYNAME ": Didn't get message start tag\n"); + return res_ERROR; + } + + if ((rcv_len = rd_word()) < len) { + if (rcv_len >= 0) { /* negative values indicate receive errors */ + db(1, MYNAME ": Received message too short (got %i bytes, expected %i)\n", + rcv_len, len); + return res_PROTOCOL_ERR; + } + return res_ERROR; + } + + db(2, "Receiving message with %i bytes of payload (expected >=%i)\n", rcv_len, len); + rd_buf(payload, MIN(rcv_len, len)); + + calc_cs = skytraq_calc_checksum(payload, MIN(rcv_len, len)); + for (i = 0; i < rcv_len-len; i++) { + c = rd_char(&errors); + calc_cs ^= c; + } + + rcv_cs = rd_char(&errors); + if (rcv_cs != calc_cs) { + fatal(MYNAME ": Checksum error: got 0x%02x, expected 0x%02x\n", rcv_cs, calc_cs); + } + + if (rd_word() != 0x0D0A) { + fatal(MYNAME ": Didn't get message end tag (CR/LF)\n"); + } // return MIN(rcv_len, len); - return res_OK; + return res_OK; } static void skytraq_wr_msg(const gbuint8 *payload, int len) { - int cs; + int cs; - rd_drain(); + rd_drain(); - wr_buf(MSG_START, sizeof(MSG_START)); - wr_char((len>>8) & 0x0FF); - wr_char(len & 0x0FF); - wr_buf(payload, len); + wr_buf(MSG_START, sizeof(MSG_START)); + wr_char((len>>8) & 0x0FF); + wr_char(len & 0x0FF); + wr_buf(payload, len); - cs = skytraq_calc_checksum(payload, len); - wr_char(cs); - wr_buf(NL, sizeof(NL)); + cs = skytraq_calc_checksum(payload, len); + wr_char(cs); + wr_buf(NL, sizeof(NL)); } static int skytraq_expect_ack(gbuint8 id) { - gbuint8 ack_msg[2]; - int i/*, rcv_len*/; + gbuint8 ack_msg[2]; + int i/*, rcv_len*/; - for (i = 0; i < MSG_RETRIES; i++) { + for (i = 0; i < MSG_RETRIES; i++) { // rcv_len = skytraq_rd_msg(ack_msg, sizeof(ack_msg)); // if (rcv_len == sizeof(ack_msg)) { - if (skytraq_rd_msg(ack_msg, sizeof(ack_msg)) == res_OK) { - if (ack_msg[0] == 0x83) { - if (ack_msg[1] == id) { - db(3, "Got ACK (id=0x%02x)\n", id); - return res_OK; - } else if (ack_msg[1] == 0) { - /* some (all?) devices first send an ACK with id==0, skip that */ - continue; - } else { - db(1, MYNAME ": Warning: Got unexpected ACK (id=0x%02x)\n", ack_msg[1]); - continue; - } - } else if (ack_msg[0] == 0x84) { - db(3, "Warning: Got NACK (id=0x%02x)\n", ack_msg[1]); - return res_NACK; - } else { - db(3, "Warning: Got unexpected message (id=0x%02x), expected ACK (id=0x%02x)\n", - ack_msg[0], id); - } - } else { - /* payload too short or didn't receive a message at all - -> caller should either resend request or give up. - */ - break; - } - } - - return res_PROTOCOL_ERR; + if (skytraq_rd_msg(ack_msg, sizeof(ack_msg)) == res_OK) { + if (ack_msg[0] == 0x83) { + if (ack_msg[1] == id) { + db(3, "Got ACK (id=0x%02x)\n", id); + return res_OK; + } else if (ack_msg[1] == 0) { + /* some (all?) devices first send an ACK with id==0, skip that */ + continue; + } else { + db(1, MYNAME ": Warning: Got unexpected ACK (id=0x%02x)\n", ack_msg[1]); + continue; + } + } else if (ack_msg[0] == 0x84) { + db(3, "Warning: Got NACK (id=0x%02x)\n", ack_msg[1]); + return res_NACK; + } else { + db(3, "Warning: Got unexpected message (id=0x%02x), expected ACK (id=0x%02x)\n", + ack_msg[0], id); + } + } else { + /* payload too short or didn't receive a message at all + -> caller should either resend request or give up. + */ + break; + } + } + + return res_PROTOCOL_ERR; } static int skytraq_expect_msg(gbuint8 id, const gbuint8 *payload, int len) { - int i, rc; - - for (i = 0; i < MSG_RETRIES; i++) { - rc = skytraq_rd_msg(payload, len); - if (rc < 0) { - return rc; - } - if (payload[0] == id) { - return len; - } - } - - return res_PROTOCOL_ERR; + int i, rc; + + for (i = 0; i < MSG_RETRIES; i++) { + rc = skytraq_rd_msg(payload, len); + if (rc < 0) { + return rc; + } + if (payload[0] == id) { + return len; + } + } + + return res_PROTOCOL_ERR; } static int skytraq_wr_msg_verify(const gbuint8 *payload, int len) { - int i, rc; - - for (i = 0; i < MSG_RETRIES; i++) { - if (i > 0) { - db(1, "resending msg (id=0x%02x)...\n", payload[0]); - } - skytraq_wr_msg(payload, len); - rc = skytraq_expect_ack(payload[0]); - if (rc == res_OK || rc == res_NACK) { - return rc; - } - db(1, MYNAME ": Got neither ACK nor NACK, "); - } - db(1, "aborting (msg id was 0x%02x).\n", payload[0]); - - return res_ERROR; + int i, rc; + + for (i = 0; i < MSG_RETRIES; i++) { + if (i > 0) { + db(1, "resending msg (id=0x%02x)...\n", payload[0]); + } + skytraq_wr_msg(payload, len); + rc = skytraq_expect_ack(payload[0]); + if (rc == res_OK || rc == res_NACK) { + return rc; + } + db(1, MYNAME ": Got neither ACK nor NACK, "); + } + db(1, "aborting (msg id was 0x%02x).\n", payload[0]); + + return res_ERROR; } static int skytraq_system_restart(void) { - gbuint8 MSG_SYSTEM_RESTART[15] = - { 0x01, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + gbuint8 MSG_SYSTEM_RESTART[15] = + { 0x01, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - db(2, "restart system\n"); - return skytraq_wr_msg_verify(MSG_SYSTEM_RESTART, sizeof(MSG_SYSTEM_RESTART)); + db(2, "restart system\n"); + return skytraq_wr_msg_verify(MSG_SYSTEM_RESTART, sizeof(MSG_SYSTEM_RESTART)); } static int skytraq_set_baud(int baud) { - /* Note: according to AN0003_v3.pdf, attrib == 0x00 means write to SRAM only, however - * it seems to write to flash too. The Windows software sends 0x02 so we do here too. - */ - gbuint8 MSG_CONFIGURE_SERIAL_PORT[4] - = { 0x05, 0x00, 0x00, 0x02 }; - int rc; - - db(2, "Setting baud rate to %i\n", baud); - - switch (baud) { - case 4800: - MSG_CONFIGURE_SERIAL_PORT[2] = 0; - break; - case 9600: - MSG_CONFIGURE_SERIAL_PORT[2] = 1; - break; - case 19200: - MSG_CONFIGURE_SERIAL_PORT[2] = 2; - break; - case 38400: - MSG_CONFIGURE_SERIAL_PORT[2] = 3; - break; - case 57600: - MSG_CONFIGURE_SERIAL_PORT[2] = 4; - break; - case 115200: - MSG_CONFIGURE_SERIAL_PORT[2] = 5; - break; - case 230400: - MSG_CONFIGURE_SERIAL_PORT[2] = 6; - break; - default: - fatal(MYNAME ": Unsupported baud rate: %ibd\n", baud); - } - - rc = skytraq_wr_msg_verify(MSG_CONFIGURE_SERIAL_PORT, sizeof(MSG_CONFIGURE_SERIAL_PORT)); - if (rc != res_OK) { - db(2, "Warning: error setting skytraq device baud rate\n"); - return rc; - } - - db(3, "Now setting UART baud rate to %i\n", baud); - rd_drain(); - if (gbser_set_speed(serial_handle, baud) != gbser_OK) { - db(2, "Warning: error setting uart baud rate\n"); - return res_ERROR; - } - - gb_sleep(50); /* allow UART to settle. */ - - return res_OK; + /* Note: according to AN0003_v3.pdf, attrib == 0x00 means write to SRAM only, however + * it seems to write to flash too. The Windows software sends 0x02 so we do here too. + */ + gbuint8 MSG_CONFIGURE_SERIAL_PORT[4] + = { 0x05, 0x00, 0x00, 0x02 }; + int rc; + + db(2, "Setting baud rate to %i\n", baud); + + switch (baud) { + case 4800: + MSG_CONFIGURE_SERIAL_PORT[2] = 0; + break; + case 9600: + MSG_CONFIGURE_SERIAL_PORT[2] = 1; + break; + case 19200: + MSG_CONFIGURE_SERIAL_PORT[2] = 2; + break; + case 38400: + MSG_CONFIGURE_SERIAL_PORT[2] = 3; + break; + case 57600: + MSG_CONFIGURE_SERIAL_PORT[2] = 4; + break; + case 115200: + MSG_CONFIGURE_SERIAL_PORT[2] = 5; + break; + case 230400: + MSG_CONFIGURE_SERIAL_PORT[2] = 6; + break; + default: + fatal(MYNAME ": Unsupported baud rate: %ibd\n", baud); + } + + rc = skytraq_wr_msg_verify(MSG_CONFIGURE_SERIAL_PORT, sizeof(MSG_CONFIGURE_SERIAL_PORT)); + if (rc != res_OK) { + db(2, "Warning: error setting skytraq device baud rate\n"); + return rc; + } + + db(3, "Now setting UART baud rate to %i\n", baud); + rd_drain(); + if (gbser_set_speed(serial_handle, baud) != gbser_OK) { + db(2, "Warning: error setting uart baud rate\n"); + return res_ERROR; + } + + gb_sleep(50); /* allow UART to settle. */ + + return res_OK; } static int skytraq_get_log_buffer_status(gbuint32 *log_wr_ptr, gbuint16 *sectors_free, gbuint16 *sectors_total) { - gbuint8 MSG_LOG_STATUS_CONTROL = 0x17; - struct { - gbuint8 id[1]; - gbuint8 log_wr_ptr[4]; - gbuint8 sectors_free[2]; - gbuint8 sectors_total[2]; - } MSG_LOG_STATUS_OUTPUT; - int rc; - - if ((rc = skytraq_wr_msg_verify(&MSG_LOG_STATUS_CONTROL, 1)) != res_OK) { /* get memory status */ - db(1, MYNAME ": Error sending LOG STATUS CONTROL message (%d)\n", rc); - return res_ERROR; - } - - rc = skytraq_expect_msg(0x94, (gbuint8*)&MSG_LOG_STATUS_OUTPUT, sizeof(MSG_LOG_STATUS_OUTPUT)); - if (rc < sizeof(MSG_LOG_STATUS_OUTPUT)) { - db(1, MYNAME ": Didn't receive expected reply (%d)\n", rc); - return res_ERROR; - } - - *log_wr_ptr = le_readu32(&MSG_LOG_STATUS_OUTPUT.log_wr_ptr); - *sectors_free = le_readu16(&MSG_LOG_STATUS_OUTPUT.sectors_free); - *sectors_total = le_readu16(&MSG_LOG_STATUS_OUTPUT.sectors_total); - - return res_OK; + gbuint8 MSG_LOG_STATUS_CONTROL = 0x17; + struct { + gbuint8 id[1]; + gbuint8 log_wr_ptr[4]; + gbuint8 sectors_free[2]; + gbuint8 sectors_total[2]; + } MSG_LOG_STATUS_OUTPUT; + int rc; + + if ((rc = skytraq_wr_msg_verify(&MSG_LOG_STATUS_CONTROL, 1)) != res_OK) { /* get memory status */ + db(1, MYNAME ": Error sending LOG STATUS CONTROL message (%d)\n", rc); + return res_ERROR; + } + + rc = skytraq_expect_msg(0x94, (gbuint8*)&MSG_LOG_STATUS_OUTPUT, sizeof(MSG_LOG_STATUS_OUTPUT)); + if (rc < sizeof(MSG_LOG_STATUS_OUTPUT)) { + db(1, MYNAME ": Didn't receive expected reply (%d)\n", rc); + return res_ERROR; + } + + *log_wr_ptr = le_readu32(&MSG_LOG_STATUS_OUTPUT.log_wr_ptr); + *sectors_free = le_readu16(&MSG_LOG_STATUS_OUTPUT.sectors_free); + *sectors_total = le_readu16(&MSG_LOG_STATUS_OUTPUT.sectors_total); + + return res_OK; } /* reads 32-bit "middle-endian" fields */ -static unsigned int me_read32(const unsigned char *p) { - return ((unsigned)be_read16(p+2) << 16) | ((unsigned)be_read16(p)); +static unsigned int me_read32(const unsigned char *p) +{ + return ((unsigned)be_read16(p+2) << 16) | ((unsigned)be_read16(p)); } struct read_state { - route_head *route_head; - unsigned wpn, tpn; + route_head *route_head; + unsigned wpn, tpn; - time_t ts; - long x, y, z; + time_t ts; + long x, y, z; }; static void state_init(struct read_state *pst) { - route_head *track; + route_head *track; - track = route_head_alloc(); - track->rte_name = xstrdup("SkyTraq tracklog"); - track->rte_desc = xstrdup("SkyTraq GPS tracklog data"); - track_add_head(track); + track = route_head_alloc(); + track->rte_name = xstrdup("SkyTraq tracklog"); + track->rte_desc = xstrdup("SkyTraq GPS tracklog data"); + track_add_head(track); - pst->route_head = track; - pst->wpn = 0; - pst->tpn = 0; + pst->route_head = track; + pst->wpn = 0; + pst->tpn = 0; - pst->ts = 0; - pst->x = 0; - pst->y = 0; - pst->z = 0; + pst->ts = 0; + pst->x = 0; + pst->y = 0; + pst->z = 0; } static waypoint * make_trackpoint(struct read_state *st, double lat, double lon, double alt) { - waypoint *wpt = waypt_new(); + waypoint *wpt = waypt_new(); - xasprintf(&wpt->shortname, "TP%04d", ++st->tpn); + xasprintf(&wpt->shortname, "TP%04d", ++st->tpn); - wpt->latitude = lat;; - wpt->longitude = lon; - wpt->altitude = alt; - wpt->creation_time = st->ts; - - return wpt; + wpt->latitude = lat;; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->creation_time = st->ts; + + return wpt; } static time_t gpstime_to_timet(int week, int sec) { - /* TODO: make leap second compensation more general - * (the windows software seems to correct by 13). - */ - return (315964800 + (week+1024)*7*SECONDS_PER_DAY + sec - 13); + /* TODO: make leap second compensation more general + * (the windows software seems to correct by 13). + */ + return (315964800 + (week+1024)*7*SECONDS_PER_DAY + sec - 13); } static void ECEF_to_LLA(double x, double y, long z, double *lat, double *lon, double *alt) { -/* constants: */ + /* constants: */ #define CA 6378137.0 #define CB 6356752.31424518 #define CE2 (CA*CA - CB*CB) / (CA*CA) /* =e^2 */ #define CE_2 (CA*CA - CB*CB) / (CB*CB) /* =e'^2 */ -/* auxiliary values: */ + /* auxiliary values: */ #define AP sqrt(x*x + y*y) #define ATHETA atan2(z*CA, AP*CB) #define AN CA / sqrt(1 - CE2 * pow(sin(*lat), 2)) /* must calc *lat before using AN! */ - // latitude (in radians): - *lat = atan2(z + CE_2 * CB * pow(sin(ATHETA), 3), AP - CE2 * CA * pow(cos(ATHETA), 3)); + // latitude (in radians): + *lat = atan2(z + CE_2 * CB * pow(sin(ATHETA), 3), AP - CE2 * CA * pow(cos(ATHETA), 3)); - // longitude (in radians): - *lon = atan2(y, x); + // longitude (in radians): + *lon = atan2(y, x); - // height above ellipsoid (in meters): - *alt = AP/cos(*lat) - AN; + // height above ellipsoid (in meters): + *alt = AP/cos(*lat) - AN; - *lat = *lat /M_PI*180; - *lon = *lon /M_PI*180; + *lat = *lat /M_PI*180; + *lon = *lon /M_PI*180; } typedef struct { - short gps_week; - long gps_sec; - unsigned long x; - unsigned long y; - unsigned long z; + short gps_week; + long gps_sec; + unsigned long x; + unsigned long y; + unsigned long z; } full_item; typedef struct { - short dt; - short dx; - short dy; - short dz; + short dt; + short dx; + short dy; + short dz; } compact_item; struct full_item_frame { - unsigned char ts[4]; - unsigned char x[4]; - unsigned char y[4]; - unsigned char z[4]; + unsigned char ts[4]; + unsigned char x[4]; + unsigned char y[4]; + unsigned char z[4]; }; struct compact_item_frame { - unsigned char dt[2]; /* big endian unsigned short */ - unsigned char dpos[4]; + unsigned char dt[2]; /* big endian unsigned short */ + unsigned char dpos[4]; }; typedef struct { - unsigned char type_and_speed[2]; - union { - struct full_item_frame full; - struct compact_item_frame comp; - }; + unsigned char type_and_speed[2]; + union { + struct full_item_frame full; + struct compact_item_frame comp; + }; } item_frame; #define ITEM_TYPE(item) (item->type_and_speed[0] >> 4) @@ -601,495 +624,505 @@ typedef struct { static int process_data_item(struct read_state *pst, const item_frame *pitem, int len) { - int res = 0; - double lat, lon, alt; - unsigned int ts; - int poi = 0; - full_item f; - compact_item c; - waypoint *tpt = NULL; - - switch (ITEM_TYPE(pitem)) { - case 0x6: /* POI item (same structure as full) */ - poi = 1; - /* fall through: */ - - case 0x4: /* full item */ - if (len < FULL_ITEM_LEN) { - db(1, MYNAME ": Not enough bytes in sector for a full item.\n"); - return res_ERROR; - } - ts = me_read32(pitem->full.ts); - f.gps_week = ts & 0x00000FFF; - f.gps_sec = ts >> 12; - f.x = me_read32(pitem->full.x); - f.y = me_read32(pitem->full.y); - f.z = me_read32(pitem->full.z); - - pst->ts = gpstime_to_timet(f.gps_week, f.gps_sec); - pst->x = f.x; - pst->y = f.y; - pst->z = f.z; - - db(4, "Got %s item: week=%i sec=%i (time_t=%i) x=%i y=%i z=%i speed=%i\n", - poi ? "POI" : "full", - f.gps_week, f.gps_sec, pst->ts, - f.x, f.y, f.z, - ITEM_SPEED(pitem)); - - res = FULL_ITEM_LEN; - break; - - case 0x8: /* compact item */ - if (len < COMPACT_ITEM_LEN) { - db(1, MYNAME ": Not enough bytes in sector for a compact item.\n"); - return res_ERROR; - } - c.dx = (pitem->comp.dpos[1] >> 6) | (pitem->comp.dpos[0] << 2); - c.dy = (pitem->comp.dpos[1] & 0x3F) | ((pitem->comp.dpos[2] & 0xF0) << 2); - c.dz = pitem->comp.dpos[3] | ((pitem->comp.dpos[2] & 0x03) << 8); - if (c.dx > 511) c.dx = 511-c.dx; /* make proper signed values */ - if (c.dy > 511) c.dy = 511-c.dy; - if (c.dz > 511) c.dz = 511-c.dz; - c.dt = (pitem->comp.dt[0] << 8) | pitem->comp.dt[1]; - - db(4, "Got compact item: dt=%i dx=%i dy=%i dz=%i speed=%i uu=%i\n", - c.dt, c.dx, c.dy, c.dz, - ITEM_SPEED(pitem), (pitem->comp.dpos[2] & 0x0F)>>2); - - pst->ts += c.dt; - pst->x += c.dx; - pst->y += c.dy; - pst->z += c.dz; - - res = COMPACT_ITEM_LEN; - break; - - default: - db(1, MYNAME ": Unknown item type encountered: 0x%02x\n", ITEM_TYPE(pitem)); - return 0; - } - - if (res == COMPACT_ITEM_LEN || res == FULL_ITEM_LEN) { - ECEF_to_LLA(pst->x, pst->y, pst->z, &lat, &lon, &alt); + int res = 0; + double lat, lon, alt; + unsigned int ts; + int poi = 0; + full_item f; + compact_item c; + waypoint *tpt = NULL; + + switch (ITEM_TYPE(pitem)) { + case 0x6: /* POI item (same structure as full) */ + poi = 1; + /* fall through: */ + + case 0x4: /* full item */ + if (len < FULL_ITEM_LEN) { + db(1, MYNAME ": Not enough bytes in sector for a full item.\n"); + return res_ERROR; + } + ts = me_read32(pitem->full.ts); + f.gps_week = ts & 0x00000FFF; + f.gps_sec = ts >> 12; + f.x = me_read32(pitem->full.x); + f.y = me_read32(pitem->full.y); + f.z = me_read32(pitem->full.z); + + pst->ts = gpstime_to_timet(f.gps_week, f.gps_sec); + pst->x = f.x; + pst->y = f.y; + pst->z = f.z; + + db(4, "Got %s item: week=%i sec=%i (time_t=%i) x=%i y=%i z=%i speed=%i\n", + poi ? "POI" : "full", + f.gps_week, f.gps_sec, pst->ts, + f.x, f.y, f.z, + ITEM_SPEED(pitem)); + + res = FULL_ITEM_LEN; + break; + + case 0x8: /* compact item */ + if (len < COMPACT_ITEM_LEN) { + db(1, MYNAME ": Not enough bytes in sector for a compact item.\n"); + return res_ERROR; + } + c.dx = (pitem->comp.dpos[1] >> 6) | (pitem->comp.dpos[0] << 2); + c.dy = (pitem->comp.dpos[1] & 0x3F) | ((pitem->comp.dpos[2] & 0xF0) << 2); + c.dz = pitem->comp.dpos[3] | ((pitem->comp.dpos[2] & 0x03) << 8); + if (c.dx > 511) { + c.dx = 511-c.dx; /* make proper signed values */ + } + if (c.dy > 511) { + c.dy = 511-c.dy; + } + if (c.dz > 511) { + c.dz = 511-c.dz; + } + c.dt = (pitem->comp.dt[0] << 8) | pitem->comp.dt[1]; + + db(4, "Got compact item: dt=%i dx=%i dy=%i dz=%i speed=%i uu=%i\n", + c.dt, c.dx, c.dy, c.dz, + ITEM_SPEED(pitem), (pitem->comp.dpos[2] & 0x0F)>>2); + + pst->ts += c.dt; + pst->x += c.dx; + pst->y += c.dy; + pst->z += c.dz; + + res = COMPACT_ITEM_LEN; + break; + + default: + db(1, MYNAME ": Unknown item type encountered: 0x%02x\n", ITEM_TYPE(pitem)); + return 0; + } + + if (res == COMPACT_ITEM_LEN || res == FULL_ITEM_LEN) { + ECEF_to_LLA(pst->x, pst->y, pst->z, &lat, &lon, &alt); // GPS_Math_XYZ_To_WGS84LatLonH(&lat, &lon, &alt, pst->x, pst->y, pst->z); - tpt = make_trackpoint(pst, lat, lon, alt); - WAYPT_SET(tpt, speed, KPH_TO_MPS(ITEM_SPEED(pitem))); /* convert speed to m/s */ + tpt = make_trackpoint(pst, lat, lon, alt); + WAYPT_SET(tpt, speed, KPH_TO_MPS(ITEM_SPEED(pitem))); /* convert speed to m/s */ - if (poi) waypt_add(waypt_dupe(tpt)); + if (poi) { + waypt_add(waypt_dupe(tpt)); + } - if (0 == pst->route_head) { - db(1, MYNAME ": New Track\n"); - pst->route_head = route_head_alloc(); - track_add_head(pst->route_head); - } + if (0 == pst->route_head) { + db(1, MYNAME ": New Track\n"); + pst->route_head = route_head_alloc(); + track_add_head(pst->route_head); + } - track_add_wpt(pst->route_head, tpt); - } + track_add_wpt(pst->route_head, tpt); + } - return res; + return res; } static int /* returns number of bytes processed (terminates on 0xFF i.e. empty or padding bytes) */ process_data_sector(struct read_state *pst, const gbuint8 *buf, int len) { - int plen, ilen; + int plen, ilen; - for (plen = 0; plen < len && buf[plen] != 0xFF; plen += ilen) { - ilen = process_data_item(pst, (item_frame*)&buf[plen], len-plen); - if (ilen <= 0) { - fatal(MYNAME ": Error %i while processing data item #%i (starts at %i)\n", - ilen, pst->tpn, plen); - } - } + for (plen = 0; plen < len && buf[plen] != 0xFF; plen += ilen) { + ilen = process_data_item(pst, (item_frame*)&buf[plen], len-plen); + if (ilen <= 0) { + fatal(MYNAME ": Error %i while processing data item #%i (starts at %i)\n", + ilen, pst->tpn, plen); + } + } - return plen; + return plen; } /* Note: the buffer is being padded with 0xFFs if necessary so there are always SECTOR_SIZE valid bytes */ static int skytraq_read_single_sector(int sector, gbuint8 *buf) { - gbuint8 MSG_LOG_SECTOR_READ_CONTROL[2] = { 0x1B, sector }; - int errors = 5; /* allow this many errors */ - int c, i, j, cs; - gbuint8 buffer[16]; + gbuint8 MSG_LOG_SECTOR_READ_CONTROL[2] = { 0x1B, sector }; + int errors = 5; /* allow this many errors */ + int c, i, j, cs; + gbuint8 buffer[16]; - if (sector < 0 || sector > 0xFF) { - fatal(MYNAME ": Invalid sector number (%i)\n", sector); - } + if (sector < 0 || sector > 0xFF) { + fatal(MYNAME ": Invalid sector number (%i)\n", sector); + } - db(2, "Reading sector #%i...\n", sector); + db(2, "Reading sector #%i...\n", sector); - if (skytraq_wr_msg_verify((gbuint8*)&MSG_LOG_SECTOR_READ_CONTROL, sizeof(MSG_LOG_SECTOR_READ_CONTROL)) != res_OK) { - db(1, MYNAME ": Didn't receive ACK\n"); - return res_ERROR; - } + if (skytraq_wr_msg_verify((gbuint8*)&MSG_LOG_SECTOR_READ_CONTROL, sizeof(MSG_LOG_SECTOR_READ_CONTROL)) != res_OK) { + db(1, MYNAME ": Didn't receive ACK\n"); + return res_ERROR; + } #ifdef READ_SINGLE_CHARS - for (i = 0, j = 0; i-j < SECTOR_SIZE && j < sizeof(SECTOR_READ_END); i++) { - c = rd_char(&errors); - buf[i] = c; - if (c == SECTOR_READ_END[j]) { - j++; - } else if (c == SECTOR_READ_END[0]) { - j = 1; - } else { - j = 0; - } - } - if (j < sizeof(SECTOR_READ_END)) { - db(1, MYNAME ": Didn't get sector end tag\n"); - return res_ERROR; - } - c = rd_char(&errors); /* read checksum byte */ - buf[i] = c; + for (i = 0, j = 0; i-j < SECTOR_SIZE && j < sizeof(SECTOR_READ_END); i++) { + c = rd_char(&errors); + buf[i] = c; + if (c == SECTOR_READ_END[j]) { + j++; + } else if (c == SECTOR_READ_END[0]) { + j = 1; + } else { + j = 0; + } + } + if (j < sizeof(SECTOR_READ_END)) { + db(1, MYNAME ": Didn't get sector end tag\n"); + return res_ERROR; + } + c = rd_char(&errors); /* read checksum byte */ + buf[i] = c; #else - for (i = 0, j = 0; i-j < SECTOR_SIZE && j < sizeof(SECTOR_READ_END); i+=c) { - rd_buf(buffer, 16); - for (c = 0; c < 16 && j < sizeof(SECTOR_READ_END); c++) { - buf[i+c] = buffer[c]; - if (buffer[c] == SECTOR_READ_END[j]) { - j++; - } else if (buffer[c] == SECTOR_READ_END[0]) { - j = 1; - } else { - j = 0; - } - } - } - if (j < sizeof(SECTOR_READ_END)) { - db(1, MYNAME ": Didn't get sector end tag\n"); - return res_ERROR; - } - if (c < 16) { - buf[i] = buffer[c]; - } else { - c = rd_char(&errors); /* read checksum byte */ - buf[i] = c; - } + for (i = 0, j = 0; i-j < SECTOR_SIZE && j < sizeof(SECTOR_READ_END); i+=c) { + rd_buf(buffer, 16); + for (c = 0; c < 16 && j < sizeof(SECTOR_READ_END); c++) { + buf[i+c] = buffer[c]; + if (buffer[c] == SECTOR_READ_END[j]) { + j++; + } else if (buffer[c] == SECTOR_READ_END[0]) { + j = 1; + } else { + j = 0; + } + } + } + if (j < sizeof(SECTOR_READ_END)) { + db(1, MYNAME ": Didn't get sector end tag\n"); + return res_ERROR; + } + if (c < 16) { + buf[i] = buffer[c]; + } else { + c = rd_char(&errors); /* read checksum byte */ + buf[i] = c; + } #endif - i = i-j; - db(3, "Received %i bytes of log data\n", i); + i = i-j; + db(3, "Received %i bytes of log data\n", i); //#define SINGLE_READ_WORKAROUND #ifdef SINGLE_READ_WORKAROUND - gbser_set_speed(serial_handle, skytraq_baud); - rd_char(&errors); - rd_char(&errors); - rd_char(&errors); - rd_char(&errors); - rd_char(&errors); - rd_char(&errors); - skytraq_set_baud(atoi(opt_dlbaud)); + gbser_set_speed(serial_handle, skytraq_baud); + rd_char(&errors); + rd_char(&errors); + rd_char(&errors); + rd_char(&errors); + rd_char(&errors); + rd_char(&errors); + skytraq_set_baud(atoi(opt_dlbaud)); #endif - cs = skytraq_calc_checksum(buf, i); - if (cs != buf[i+sizeof(SECTOR_READ_END)]) { - db(1, MYNAME ": Checksum error while reading sector: got 0x%02x, expected 0x%02x\n", - buf[i+sizeof(SECTOR_READ_END)], cs); - return res_ERROR; - } + cs = skytraq_calc_checksum(buf, i); + if (cs != buf[i+sizeof(SECTOR_READ_END)]) { + db(1, MYNAME ": Checksum error while reading sector: got 0x%02x, expected 0x%02x\n", + buf[i+sizeof(SECTOR_READ_END)], cs); + return res_ERROR; + } - for (; i < SECTOR_SIZE; i++) { - buf[i] = 0xFF; - } + for (; i < SECTOR_SIZE; i++) { + buf[i] = 0xFF; + } - return res_OK; + return res_OK; } static int skytraq_read_multiple_sectors(int first_sector, int sector_count, gbuint8 *buf) { - gbuint8 MSG_LOG_READ_MULTI_SECTORS[5] = { 0x1D }; - gbuint8 *buf_end_tag; - int cs, i, read_result; - - if (first_sector < 0 || first_sector > 0xFFFF) { - fatal(MYNAME ": Invalid sector number (%i)\n", first_sector); - } - be_write16(&MSG_LOG_READ_MULTI_SECTORS[1], first_sector); - if (sector_count < 0 || sector_count > 0xFFFF) { - fatal(MYNAME ": Invalid sector count (%i)\n", sector_count); - } - be_write16(&MSG_LOG_READ_MULTI_SECTORS[3], sector_count); - - db(2, "Reading %i sectors beginning from #%i...\n", sector_count, first_sector); - - read_result = skytraq_wr_msg_verify((gbuint8*)&MSG_LOG_READ_MULTI_SECTORS, sizeof(MSG_LOG_READ_MULTI_SECTORS)); - if (read_result != res_OK) { - return read_result; - } - - for (i = 0; i < sector_count; i++) { - db(2, "Receiving data of sector #%i...\n", first_sector+i); - rd_buf(buf+i*SECTOR_SIZE, SECTOR_SIZE); - } - rd_buf(buf+SECTOR_SIZE*sector_count, sizeof(SECTOR_READ_END)+6); - - buf_end_tag = buf + SECTOR_SIZE*sector_count; - for (i = 0; i < sizeof(SECTOR_READ_END); i++) { - if (buf_end_tag[i] != SECTOR_READ_END[i]) { - db(1, MYNAME ": Wrong end tag: got 0x%02x ('%c'), expected 0x%02x ('%c')\n", - buf_end_tag[i], isprint(buf_end_tag[i]) ? buf_end_tag[i] : '.', - SECTOR_READ_END[i], isprint(SECTOR_READ_END[i]) ? SECTOR_READ_END[i] : '.'); - return res_ERROR; - } - } - - cs = skytraq_calc_checksum(buf, SECTOR_SIZE*sector_count); - if (cs != buf_end_tag[sizeof(SECTOR_READ_END)]) { - db(1, MYNAME ": Checksum error while reading sector: got 0x%02x, expected 0x%02x\n", - buf_end_tag[sizeof(SECTOR_READ_END)], cs); - return res_ERROR; - } - - return res_OK; + gbuint8 MSG_LOG_READ_MULTI_SECTORS[5] = { 0x1D }; + gbuint8 *buf_end_tag; + int cs, i, read_result; + + if (first_sector < 0 || first_sector > 0xFFFF) { + fatal(MYNAME ": Invalid sector number (%i)\n", first_sector); + } + be_write16(&MSG_LOG_READ_MULTI_SECTORS[1], first_sector); + if (sector_count < 0 || sector_count > 0xFFFF) { + fatal(MYNAME ": Invalid sector count (%i)\n", sector_count); + } + be_write16(&MSG_LOG_READ_MULTI_SECTORS[3], sector_count); + + db(2, "Reading %i sectors beginning from #%i...\n", sector_count, first_sector); + + read_result = skytraq_wr_msg_verify((gbuint8*)&MSG_LOG_READ_MULTI_SECTORS, sizeof(MSG_LOG_READ_MULTI_SECTORS)); + if (read_result != res_OK) { + return read_result; + } + + for (i = 0; i < sector_count; i++) { + db(2, "Receiving data of sector #%i...\n", first_sector+i); + rd_buf(buf+i*SECTOR_SIZE, SECTOR_SIZE); + } + rd_buf(buf+SECTOR_SIZE*sector_count, sizeof(SECTOR_READ_END)+6); + + buf_end_tag = buf + SECTOR_SIZE*sector_count; + for (i = 0; i < sizeof(SECTOR_READ_END); i++) { + if (buf_end_tag[i] != SECTOR_READ_END[i]) { + db(1, MYNAME ": Wrong end tag: got 0x%02x ('%c'), expected 0x%02x ('%c')\n", + buf_end_tag[i], isprint(buf_end_tag[i]) ? buf_end_tag[i] : '.', + SECTOR_READ_END[i], isprint(SECTOR_READ_END[i]) ? SECTOR_READ_END[i] : '.'); + return res_ERROR; + } + } + + cs = skytraq_calc_checksum(buf, SECTOR_SIZE*sector_count); + if (cs != buf_end_tag[sizeof(SECTOR_READ_END)]) { + db(1, MYNAME ": Checksum error while reading sector: got 0x%02x, expected 0x%02x\n", + buf_end_tag[sizeof(SECTOR_READ_END)], cs); + return res_ERROR; + } + + return res_OK; } static void skytraq_read_tracks(void) { - struct read_state st; - gbuint32 log_wr_ptr; - gbuint16 sectors_free, sectors_total, /*sectors_used_a, sectors_used_b,*/ sectors_used; - int i, t, s, rc, got_sectors, total_sectors_read = 0; - int read_at_once = MAX(atoi(opt_read_at_once), 1); - int opt_first_sector_val = atoi(opt_first_sector); - int opt_last_sector_val = atoi(opt_last_sector); - int multi_read_supported = 1; - gbuint8 *buffer = NULL; - gbfile *dumpfile = NULL; - - state_init(&st); - - if (skytraq_get_log_buffer_status(&log_wr_ptr, §ors_free, §ors_total) != res_OK) { - fatal(MYNAME ": Can't get log buffer status\n"); - } - - db(1, MYNAME ": Device status: free sectors: %i / total sectors: %i / %i%% used / write ptr: %i\n", - sectors_free, sectors_total, 100 - sectors_free*100 / sectors_total, log_wr_ptr); - - if (opt_first_sector_val >= sectors_total) { - db(1, "Warning: sector# specified by option first-sector (%i) is beyond reported total sector count (%i)", - opt_first_sector_val, sectors_total); - } -/* Workaround: sectors_free is sometimes reported wrong. Tried to use log_wr_ptr as an - indicator for how many sectors are currently used. However this isn't correct in every case too. - The current read logic is aware of that so this shouldn't be necessary anymore. - sectors_used_a = sectors_total - sectors_free; - sectors_used_b = (log_wr_ptr + SECTOR_SIZE - 1) / SECTOR_SIZE; - if (sectors_used_a != sectors_used_b) { - db(1, "Warning: device reported inconsistent number of used sectors (a=%i, b=%i), "\ - "using max=%i\n", sectors_used_a, sectors_used_b, MAX(sectors_used_a, sectors_used_b)); - } - sectors_used = MAX(sectors_used_a, sectors_used_b); -*/ - if (opt_last_sector_val < 0) { - sectors_used = sectors_total - sectors_free + 1 /*+5*/; - if (opt_first_sector_val >= sectors_used) { - sectors_used = opt_first_sector_val + 1; - } - } else { - sectors_used = opt_last_sector_val; - if (opt_last_sector_val >= sectors_total) { - db(1, "Warning: sector# specified by option last-sector (%i) is beyond reported total sector count (%i)", - opt_last_sector_val, sectors_total); - } - } - - buffer = xmalloc(SECTOR_SIZE*read_at_once+sizeof(SECTOR_READ_END)+6); - // m.ad/090930: removed code that tried reducing read_at_once if necessary since doesn't work with xmalloc - - if (opt_dump_file) { - dumpfile = gbfopen(opt_dump_file, "w", MYNAME); - } - - db(1, MYNAME ": Reading log data from device...\n"); - db(1, MYNAME ": start=%d used=%d\n", opt_first_sector_val, sectors_used); - db(1, MYNAME ": opt_last_sector_val=%d\n", opt_last_sector_val); - for (i = opt_first_sector_val; i < sectors_used; i += got_sectors) { - for (t = 0, got_sectors = 0; (t < SECTOR_RETRIES) && (got_sectors <= 0); t++) { - if (atoi(opt_read_at_once) == 0 || multi_read_supported == 0) { - rc = skytraq_read_single_sector(i, buffer); - if (rc == res_OK) got_sectors = 1; - } else { - /* Try to read read_at_once sectors at once. - * If tere aren't any so many interesting ones, read the remainder (sectors_used-i). - * And read at least 1 sector. - */ - read_at_once = MAX(MIN(read_at_once, sectors_used-i), 1); - - rc = skytraq_read_multiple_sectors(i, read_at_once, buffer); - switch (rc) { - case res_OK: - got_sectors = read_at_once; - read_at_once = MIN(read_at_once*2, atoi(opt_read_at_once)); - break; - - case res_NACK: - db(1, MYNAME ": Device doesn't seem to support reading multiple " - "sectors at once, falling back to single read.\n"); - multi_read_supported = 0; - break; - - default: - /* On failure, try with less sectors */ - read_at_once = MAX(read_at_once/2, 1); - } - } - } - if (got_sectors <= 0) { - fatal(MYNAME ": Error reading sector %i\n", i); - } - - total_sectors_read += got_sectors; - - if (dumpfile) { - gbfwrite(buffer, SECTOR_SIZE, got_sectors, dumpfile); - } - - if (*opt_no_output == '1') { - continue; // skip decoding - } - - for (s = 0; s < got_sectors; s++) { - db(4, MYNAME ": Decoding sector #%i...\n", i+s); - rc = process_data_sector(&st, buffer+s*SECTOR_SIZE, SECTOR_SIZE); - if (rc == 0) { - db(1, MYNAME ": Empty sector encountered: apparently only %i sectors are " - "used but device reported %i.\n", - i+s, sectors_used); - i = sectors_used; /* terminate to avoid reading stale data still in the logger */ - break; - } else if (rc >= (4096-FULL_ITEM_LEN) && i+s+1 >= sectors_used && i+s+1 < sectors_total) { - db(1, MYNAME ": Last sector is nearly full, reading one more sector\n"); - sectors_used++; - } - } - } - free(buffer); - db(1, MYNAME ": Got %i trackpoints from %i sectors.\n", st.tpn, total_sectors_read); - - if (dumpfile) { - gbfclose(dumpfile); - } + struct read_state st; + gbuint32 log_wr_ptr; + gbuint16 sectors_free, sectors_total, /*sectors_used_a, sectors_used_b,*/ sectors_used; + int i, t, s, rc, got_sectors, total_sectors_read = 0; + int read_at_once = MAX(atoi(opt_read_at_once), 1); + int opt_first_sector_val = atoi(opt_first_sector); + int opt_last_sector_val = atoi(opt_last_sector); + int multi_read_supported = 1; + gbuint8 *buffer = NULL; + gbfile *dumpfile = NULL; + + state_init(&st); + + if (skytraq_get_log_buffer_status(&log_wr_ptr, §ors_free, §ors_total) != res_OK) { + fatal(MYNAME ": Can't get log buffer status\n"); + } + + db(1, MYNAME ": Device status: free sectors: %i / total sectors: %i / %i%% used / write ptr: %i\n", + sectors_free, sectors_total, 100 - sectors_free*100 / sectors_total, log_wr_ptr); + + if (opt_first_sector_val >= sectors_total) { + db(1, "Warning: sector# specified by option first-sector (%i) is beyond reported total sector count (%i)", + opt_first_sector_val, sectors_total); + } + /* Workaround: sectors_free is sometimes reported wrong. Tried to use log_wr_ptr as an + indicator for how many sectors are currently used. However this isn't correct in every case too. + The current read logic is aware of that so this shouldn't be necessary anymore. + sectors_used_a = sectors_total - sectors_free; + sectors_used_b = (log_wr_ptr + SECTOR_SIZE - 1) / SECTOR_SIZE; + if (sectors_used_a != sectors_used_b) { + db(1, "Warning: device reported inconsistent number of used sectors (a=%i, b=%i), "\ + "using max=%i\n", sectors_used_a, sectors_used_b, MAX(sectors_used_a, sectors_used_b)); + } + sectors_used = MAX(sectors_used_a, sectors_used_b); + */ + if (opt_last_sector_val < 0) { + sectors_used = sectors_total - sectors_free + 1 /*+5*/; + if (opt_first_sector_val >= sectors_used) { + sectors_used = opt_first_sector_val + 1; + } + } else { + sectors_used = opt_last_sector_val; + if (opt_last_sector_val >= sectors_total) { + db(1, "Warning: sector# specified by option last-sector (%i) is beyond reported total sector count (%i)", + opt_last_sector_val, sectors_total); + } + } + + buffer = xmalloc(SECTOR_SIZE*read_at_once+sizeof(SECTOR_READ_END)+6); + // m.ad/090930: removed code that tried reducing read_at_once if necessary since doesn't work with xmalloc + + if (opt_dump_file) { + dumpfile = gbfopen(opt_dump_file, "w", MYNAME); + } + + db(1, MYNAME ": Reading log data from device...\n"); + db(1, MYNAME ": start=%d used=%d\n", opt_first_sector_val, sectors_used); + db(1, MYNAME ": opt_last_sector_val=%d\n", opt_last_sector_val); + for (i = opt_first_sector_val; i < sectors_used; i += got_sectors) { + for (t = 0, got_sectors = 0; (t < SECTOR_RETRIES) && (got_sectors <= 0); t++) { + if (atoi(opt_read_at_once) == 0 || multi_read_supported == 0) { + rc = skytraq_read_single_sector(i, buffer); + if (rc == res_OK) { + got_sectors = 1; + } + } else { + /* Try to read read_at_once sectors at once. + * If tere aren't any so many interesting ones, read the remainder (sectors_used-i). + * And read at least 1 sector. + */ + read_at_once = MAX(MIN(read_at_once, sectors_used-i), 1); + + rc = skytraq_read_multiple_sectors(i, read_at_once, buffer); + switch (rc) { + case res_OK: + got_sectors = read_at_once; + read_at_once = MIN(read_at_once*2, atoi(opt_read_at_once)); + break; + + case res_NACK: + db(1, MYNAME ": Device doesn't seem to support reading multiple " + "sectors at once, falling back to single read.\n"); + multi_read_supported = 0; + break; + + default: + /* On failure, try with less sectors */ + read_at_once = MAX(read_at_once/2, 1); + } + } + } + if (got_sectors <= 0) { + fatal(MYNAME ": Error reading sector %i\n", i); + } + + total_sectors_read += got_sectors; + + if (dumpfile) { + gbfwrite(buffer, SECTOR_SIZE, got_sectors, dumpfile); + } + + if (*opt_no_output == '1') { + continue; // skip decoding + } + + for (s = 0; s < got_sectors; s++) { + db(4, MYNAME ": Decoding sector #%i...\n", i+s); + rc = process_data_sector(&st, buffer+s*SECTOR_SIZE, SECTOR_SIZE); + if (rc == 0) { + db(1, MYNAME ": Empty sector encountered: apparently only %i sectors are " + "used but device reported %i.\n", + i+s, sectors_used); + i = sectors_used; /* terminate to avoid reading stale data still in the logger */ + break; + } else if (rc >= (4096-FULL_ITEM_LEN) && i+s+1 >= sectors_used && i+s+1 < sectors_total) { + db(1, MYNAME ": Last sector is nearly full, reading one more sector\n"); + sectors_used++; + } + } + } + free(buffer); + db(1, MYNAME ": Got %i trackpoints from %i sectors.\n", st.tpn, total_sectors_read); + + if (dumpfile) { + gbfclose(dumpfile); + } } static int skytraq_probe(void) { - int baud_rates[] = { 9600, 230400, 115200, 57600, 4800, 19200, 38400 }; - int baud_rates_count = sizeof(baud_rates)/sizeof(baud_rates[0]); - int initbaud = atoi(opt_initbaud); - gbuint8 MSG_QUERY_SOFTWARE_VERSION[2] = { 0x02, 0x01 }; - struct { - gbuint8 id; - gbuint8 sw_type; - gbuint8 kernel_ver[4]; - gbuint8 odm_ver[4]; - gbuint8 revision[4]; - } MSG_SOFTWARE_VERSION; - int i, rc; - - // TODO: get current serial port baud rate and try that first - // (only sensible if init to 4800 can be disabled...) - - if (initbaud > 0) { - baud_rates[0] = initbaud; - baud_rates_count = 1; - } - - for (i = 0; i < baud_rates_count; i++) { - db(1, MYNAME ": Probing SkyTraq Venus at %ibaud...\n", baud_rates[i]); - - rd_drain(); - if ((rc = gbser_set_speed(serial_handle, baud_rates[i])) != gbser_OK) { - db(1, MYNAME ": Set baud rate to %d failed (%d), retrying...\n", baud_rates[i], rc); - if ((rc = gbser_set_speed(serial_handle, baud_rates[i])) != gbser_OK) { - db(1, MYNAME ": Set baud rate to %d failed (%d)\n", baud_rates[i], rc); - continue; - } - } - - gb_sleep(50); /* allow UART to settle. */ - - skytraq_wr_msg(MSG_QUERY_SOFTWARE_VERSION, /* get firmware version */ - sizeof(MSG_QUERY_SOFTWARE_VERSION)); - if ((rc = skytraq_expect_ack(0x02)) != res_OK) { - db(2, "Didn't receive ACK (%d), retrying...\n", rc); - skytraq_wr_msg(MSG_QUERY_SOFTWARE_VERSION, /* get firmware version */ - sizeof(MSG_QUERY_SOFTWARE_VERSION)); - if ((rc = skytraq_expect_ack(0x02)) != res_OK) { - db(2, "Didn't receive ACK (%d)\n", rc); - continue; - } - } -/* note: _verify retries on errors, probe takes too long. - if (skytraq_wr_msg_verify(MSG_QUERY_SOFTWARE_VERSION, - sizeof(MSG_QUERY_SOFTWARE_VERSION)) != res_OK) - { - continue; - }*/ - rc = skytraq_expect_msg(0x80, (gbuint8*)&MSG_SOFTWARE_VERSION, sizeof(MSG_SOFTWARE_VERSION)); - if (rc < (int)sizeof(MSG_SOFTWARE_VERSION)) { - db(2, "Didn't receive expected reply (%d)\n", rc); - } else { - db(1, MYNAME ": Venus device found: Kernel version = %i.%i.%i, ODM version = %i.%i.%i, "\ - "revision (Y/M/D) = %02i/%02i/%02i\n", - MSG_SOFTWARE_VERSION.kernel_ver[1], MSG_SOFTWARE_VERSION.kernel_ver[2], - MSG_SOFTWARE_VERSION.kernel_ver[3], - MSG_SOFTWARE_VERSION.odm_ver[1], MSG_SOFTWARE_VERSION.odm_ver[2], - MSG_SOFTWARE_VERSION.odm_ver[3], - MSG_SOFTWARE_VERSION.revision[1], MSG_SOFTWARE_VERSION.revision[2], - MSG_SOFTWARE_VERSION.revision[3]); - - return baud_rates[i]; - } - } - - return res_NOTFOUND; + int baud_rates[] = { 9600, 230400, 115200, 57600, 4800, 19200, 38400 }; + int baud_rates_count = sizeof(baud_rates)/sizeof(baud_rates[0]); + int initbaud = atoi(opt_initbaud); + gbuint8 MSG_QUERY_SOFTWARE_VERSION[2] = { 0x02, 0x01 }; + struct { + gbuint8 id; + gbuint8 sw_type; + gbuint8 kernel_ver[4]; + gbuint8 odm_ver[4]; + gbuint8 revision[4]; + } MSG_SOFTWARE_VERSION; + int i, rc; + + // TODO: get current serial port baud rate and try that first + // (only sensible if init to 4800 can be disabled...) + + if (initbaud > 0) { + baud_rates[0] = initbaud; + baud_rates_count = 1; + } + + for (i = 0; i < baud_rates_count; i++) { + db(1, MYNAME ": Probing SkyTraq Venus at %ibaud...\n", baud_rates[i]); + + rd_drain(); + if ((rc = gbser_set_speed(serial_handle, baud_rates[i])) != gbser_OK) { + db(1, MYNAME ": Set baud rate to %d failed (%d), retrying...\n", baud_rates[i], rc); + if ((rc = gbser_set_speed(serial_handle, baud_rates[i])) != gbser_OK) { + db(1, MYNAME ": Set baud rate to %d failed (%d)\n", baud_rates[i], rc); + continue; + } + } + + gb_sleep(50); /* allow UART to settle. */ + + skytraq_wr_msg(MSG_QUERY_SOFTWARE_VERSION, /* get firmware version */ + sizeof(MSG_QUERY_SOFTWARE_VERSION)); + if ((rc = skytraq_expect_ack(0x02)) != res_OK) { + db(2, "Didn't receive ACK (%d), retrying...\n", rc); + skytraq_wr_msg(MSG_QUERY_SOFTWARE_VERSION, /* get firmware version */ + sizeof(MSG_QUERY_SOFTWARE_VERSION)); + if ((rc = skytraq_expect_ack(0x02)) != res_OK) { + db(2, "Didn't receive ACK (%d)\n", rc); + continue; + } + } + /* note: _verify retries on errors, probe takes too long. + if (skytraq_wr_msg_verify(MSG_QUERY_SOFTWARE_VERSION, + sizeof(MSG_QUERY_SOFTWARE_VERSION)) != res_OK) + { + continue; + }*/ + rc = skytraq_expect_msg(0x80, (gbuint8*)&MSG_SOFTWARE_VERSION, sizeof(MSG_SOFTWARE_VERSION)); + if (rc < (int)sizeof(MSG_SOFTWARE_VERSION)) { + db(2, "Didn't receive expected reply (%d)\n", rc); + } else { + db(1, MYNAME ": Venus device found: Kernel version = %i.%i.%i, ODM version = %i.%i.%i, "\ + "revision (Y/M/D) = %02i/%02i/%02i\n", + MSG_SOFTWARE_VERSION.kernel_ver[1], MSG_SOFTWARE_VERSION.kernel_ver[2], + MSG_SOFTWARE_VERSION.kernel_ver[3], + MSG_SOFTWARE_VERSION.odm_ver[1], MSG_SOFTWARE_VERSION.odm_ver[2], + MSG_SOFTWARE_VERSION.odm_ver[3], + MSG_SOFTWARE_VERSION.revision[1], MSG_SOFTWARE_VERSION.revision[2], + MSG_SOFTWARE_VERSION.revision[3]); + + return baud_rates[i]; + } + } + + return res_NOTFOUND; } static int skytraq_erase() { - gbuint8 MSG_LOG_ERASE = 0x19; + gbuint8 MSG_LOG_ERASE = 0x19; - db(1, MYNAME ": Erasing logger memory...\n"); - if (skytraq_wr_msg_verify(&MSG_LOG_ERASE, sizeof(MSG_LOG_ERASE)) != res_OK) { - db(1, MYNAME ": Didn't receive ACK\n"); - return res_ERROR; - } + db(1, MYNAME ": Erasing logger memory...\n"); + if (skytraq_wr_msg_verify(&MSG_LOG_ERASE, sizeof(MSG_LOG_ERASE)) != res_OK) { + db(1, MYNAME ": Didn't receive ACK\n"); + return res_ERROR; + } - return res_OK; + return res_OK; } static void -skytraq_set_location(void) +skytraq_set_location(void) { - double lat, lng; - int i; - gbuint8 MSG_SET_LOCATION[17] = { 0x36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gbuint8 MSG_GET_LOCATION = 0x35; - - db(3, MYNAME ": set_location='%s'\n", opt_set_location); - - sscanf(opt_set_location, "%lf:%lf", &lat, &lng); - le_write_double(&MSG_SET_LOCATION[1], lat); - le_write_double(&MSG_SET_LOCATION[9], lng); - for (i=0; i 0) { - db(4, MYNAME ": Seeking to first-sector index %i\n", opt_first_sector_val*SECTOR_SIZE); - gbfseek(file_handle, opt_first_sector_val*SECTOR_SIZE, SEEK_SET); - } - - db(1, MYNAME ": Reading log data from file...\n"); - sectors_read = 0; - while ((got_bytes = gbfread(buffer, 1, SECTOR_SIZE, file_handle)) > 0) { - db(4, MYNAME ": Decoding sector #%i...\n", sectors_read++); - rc = process_data_sector(&st, buffer, got_bytes); - if (opt_last_sector_val < 0) { - if (rc < (4096-FULL_ITEM_LEN)) { - db(1, MYNAME ": Empty sector encountered, terminating.\n"); - break; - } - } else if (sectors_read-1 >= opt_last_sector_val) { - db(1, MYNAME ": desired last-sector #%i reached, terminating.\n", sectors_read-1); - break; - } - } - xfree(buffer); - db(1, MYNAME ": Got %i trackpoints from %i sectors.\n", st.tpn, sectors_read); + struct read_state st; + int rc, got_bytes; + int opt_first_sector_val = atoi(opt_first_sector); + int opt_last_sector_val = atoi(opt_last_sector); + int sectors_read; + gbuint8 *buffer; + + state_init(&st); + buffer = xmalloc(SECTOR_SIZE); + + if (opt_first_sector_val > 0) { + db(4, MYNAME ": Seeking to first-sector index %i\n", opt_first_sector_val*SECTOR_SIZE); + gbfseek(file_handle, opt_first_sector_val*SECTOR_SIZE, SEEK_SET); + } + + db(1, MYNAME ": Reading log data from file...\n"); + sectors_read = 0; + while ((got_bytes = gbfread(buffer, 1, SECTOR_SIZE, file_handle)) > 0) { + db(4, MYNAME ": Decoding sector #%i...\n", sectors_read++); + rc = process_data_sector(&st, buffer, got_bytes); + if (opt_last_sector_val < 0) { + if (rc < (4096-FULL_ITEM_LEN)) { + db(1, MYNAME ": Empty sector encountered, terminating.\n"); + break; + } + } else if (sectors_read-1 >= opt_last_sector_val) { + db(1, MYNAME ": desired last-sector #%i reached, terminating.\n", sectors_read-1); + break; + } + } + xfree(buffer); + db(1, MYNAME ": Got %i trackpoints from %i sectors.\n", st.tpn, sectors_read); } /**************************************************************************/ @@ -1205,39 +1238,39 @@ file_read(void) // capabilities below means: we can only read tracks ff_vecs_t skytraq_vecs = { - ff_type_serial, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - skytraq_rd_init, - NULL, - skytraq_rd_deinit, - NULL, - skytraq_read, - NULL, - NULL, - skytraq_args, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ + ff_type_serial, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + skytraq_rd_init, + NULL, + skytraq_rd_deinit, + NULL, + skytraq_read, + NULL, + NULL, + skytraq_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ }; ff_vecs_t skytraq_fvecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - file_init, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - skytraq_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + skytraq_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ }; /**************************************************************************/ /* @@ -1255,94 +1288,98 @@ static char *opt_set_poi_boat = NULL; /* set if a "poi" option was used */ static char *opt_set_poi_heart = NULL; /* set if a "poi" option was used */ static char *opt_set_poi_bar = NULL; /* set if a "poi" option was used */ arglist_t miniHomer_args[] = { - { "baud", &opt_dlbaud, "Baud rate used for download", "115200", ARGTYPE_INT, "0", "115200" }, - { "dump-file", &opt_dump_file, "Dump raw data to this file", NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX }, - { "erase", &opt_erase, "Erase device data after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "first-sector", &opt_first_sector, "First sector to be read from the device", "0", ARGTYPE_INT, "0", "65535" }, - { "initbaud", &opt_initbaud, "Baud rate used to init device (0=autodetect)", "38400", ARGTYPE_INT, "38400", "38400" }, - { "last-sector", &opt_last_sector, "Last sector to be read from the device (-1: smart read everything)", "-1", ARGTYPE_INT, "-1", "65535" }, - { "no-output", &opt_no_output, "Disable output (useful with erase)", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - { "read-at-once", &opt_read_at_once, "Number of sectors to read at once (0=use single sector mode)", "255", ARGTYPE_INT, "0", "255" }, - { "Home", &opt_set_poi_home, "POI for Home Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, - { "Car", &opt_set_poi_car, "POI for Car Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, - { "Boat", &opt_set_poi_boat, "POI for Boat Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, - { "Heart", &opt_set_poi_heart, "POI for Heart Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, - { "Bar", &opt_set_poi_bar, "POI for Bar Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, - ARG_TERMINATOR + { "baud", &opt_dlbaud, "Baud rate used for download", "115200", ARGTYPE_INT, "0", "115200" }, + { "dump-file", &opt_dump_file, "Dump raw data to this file", NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX }, + { "erase", &opt_erase, "Erase device data after download", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + { "first-sector", &opt_first_sector, "First sector to be read from the device", "0", ARGTYPE_INT, "0", "65535" }, + { "initbaud", &opt_initbaud, "Baud rate used to init device (0=autodetect)", "38400", ARGTYPE_INT, "38400", "38400" }, + { "last-sector", &opt_last_sector, "Last sector to be read from the device (-1: smart read everything)", "-1", ARGTYPE_INT, "-1", "65535" }, + { "no-output", &opt_no_output, "Disable output (useful with erase)", "0", ARGTYPE_BOOL, ARG_NOMINMAX }, + { "read-at-once", &opt_read_at_once, "Number of sectors to read at once (0=use single sector mode)", "255", ARGTYPE_INT, "0", "255" }, + { "Home", &opt_set_poi_home, "POI for Home Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, + { "Car", &opt_set_poi_car, "POI for Car Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, + { "Boat", &opt_set_poi_boat, "POI for Boat Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, + { "Heart", &opt_set_poi_heart, "POI for Heart Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, + { "Bar", &opt_set_poi_bar, "POI for Bar Symbol as lat:lng[:alt]", NULL, ARGTYPE_STRING, "", "" }, + ARG_TERMINATOR }; /* * Names of the POIs on miniHomer */ static char *poinames[] = { - "Home", "Car", "Boat", "Heart", "Bar" + "Home", "Car", "Boat", "Heart", "Bar" }; #define NUMPOI (sizeof poinames/sizeof poinames[0]) -int getPoiByName(char *name) { - int i; - for (i=0; i>8)&0xff; - MSG_GET_POI[2]=(poi)&0xff; - if (skytraq_wr_msg_verify((gbuint8*)&MSG_GET_POI, sizeof(MSG_GET_POI)) != res_OK) { - warning(MYNAME ": cannot read poi %d '%s'\n", poi, poinames[poi]); - } - skytraq_rd_msg(buf, 25); - ecef_x=be_read_double(buf+1); - ecef_y=be_read_double(buf+9); - ecef_z=be_read_double(buf+17); - - // todo - how to determine not-set POIs ? - if (ecef_x < 100.0 && ecef_y < 100.0 && ecef_z < 100.0) { - db(2, MYNAME" : skipped poi %d for X=%f, y=%f, Z=%f\n", ecef_x, ecef_y, ecef_z); - } else { - ECEF_to_LLA (ecef_x, ecef_y, ecef_z, &lat, &lng, &alt); - - wpt = waypt_new(); - xasprintf(&wpt->shortname, "POI_%s", poinames[poi]); - xasprintf(&wpt->description, "miniHomer points to this coordinates if the %s symbol is on", poi, poinames[poi]); - wpt->latitude = lat; - wpt->longitude = lng; - wpt->altitude = alt; - waypt_add(wpt); - db(1, MYNAME ": got POI[%s]='%f %f %f/%f %f %f'\n", poinames[poi], lat, lng, alt, ecef_x, ecef_y, ecef_z); - } - } + gbuint8 MSG_GET_POI[3] = { 0x4D, 0, 0}; + gbuint8 buf[32]; + int poi; + double lat, lng, alt; + double ecef_x, ecef_y, ecef_z; + waypoint *wpt; + + for (poi=0; poi>8)&0xff; + MSG_GET_POI[2]=(poi)&0xff; + if (skytraq_wr_msg_verify((gbuint8*)&MSG_GET_POI, sizeof(MSG_GET_POI)) != res_OK) { + warning(MYNAME ": cannot read poi %d '%s'\n", poi, poinames[poi]); + } + skytraq_rd_msg(buf, 25); + ecef_x=be_read_double(buf+1); + ecef_y=be_read_double(buf+9); + ecef_z=be_read_double(buf+17); + + // todo - how to determine not-set POIs ? + if (ecef_x < 100.0 && ecef_y < 100.0 && ecef_z < 100.0) { + db(2, MYNAME" : skipped poi %d for X=%f, y=%f, Z=%f\n", ecef_x, ecef_y, ecef_z); + } else { + ECEF_to_LLA(ecef_x, ecef_y, ecef_z, &lat, &lng, &alt); + + wpt = waypt_new(); + xasprintf(&wpt->shortname, "POI_%s", poinames[poi]); + xasprintf(&wpt->description, "miniHomer points to this coordinates if the %s symbol is on", poi, poinames[poi]); + wpt->latitude = lat; + wpt->longitude = lng; + wpt->altitude = alt; + waypt_add(wpt); + db(1, MYNAME ": got POI[%s]='%f %f %f/%f %f %f'\n", poinames[poi], lat, lng, alt, ecef_x, ecef_y, ecef_z); + } + } } /* * set lla (lat/lng/alt) specified as :[: to flash, 0->ro sram) - }; - int n, result; - double lat, lng, alt; - double ecef_x, ecef_y, ecef_z; - - - result=0; // result will be 0 if opt_poi isn't set - if (opt_poi) { // first check opt_poi - if (*opt_poi) { - lat=lng=alt=0.0; - /* - * parse format of :[:alt] - * we assume at least two elements in the value string - */ - n = sscanf(opt_poi, "%lf:%lf:%lf", &lat, &lng, &alt); - if (n >= 2) { - db(3, "found %d elems '%s':poi=%s@%d, lat=%f, lng=%f, alt=%f over=%s\n", n, opt_poi, poinames[poinum], poinum, lat, lng, alt); - lla2ecef(lat, lng, alt, &ecef_x, &ecef_y, &ecef_z); - db(1, MYNAME ": set POI[%s]='%f %f %f/%f %f %f'\n", poinames[poinum], lat, lng, alt, ecef_x, ecef_y, ecef_z); - be_write16(MSG_SET_POI+1, poinum); - be_write_double(MSG_SET_POI+3, ecef_x); - be_write_double(MSG_SET_POI+11, ecef_y); - be_write_double(MSG_SET_POI+19, ecef_z); - MSG_SET_POI[27]=0; - if (skytraq_wr_msg_verify((gbuint8*)&MSG_SET_POI, sizeof(MSG_SET_POI)) == res_OK) { - result=1; - } else { - warning(MYNAME ": cannot set poi %d '%s'\n", poinum, poinames[poinum]); - result=-1; - } - } else { - warning(MYNAME ": argument to %s needs to be like :[:]\n", poinames[poinum]); - result=-1; - } - } + gbuint8 MSG_SET_POI[MSG_SET_POI_SIZE] = { + 0x4C, 0, 0, // cmd + poi (u16) + 0, 0, 0, 0, 0, 0, 0, 0, //lat (double ecef) + 0, 0, 0, 0, 0, 0, 0, 0, //lng (double ecef) + 0, 0, 0, 0, 0, 0, 0, 0, //alt (double ecef) + 0 // attr (u8, 1-> to flash, 0->ro sram) + }; + int n, result; + double lat, lng, alt; + double ecef_x, ecef_y, ecef_z; + + + result=0; // result will be 0 if opt_poi isn't set + if (opt_poi) { // first check opt_poi + if (*opt_poi) { + lat=lng=alt=0.0; + /* + * parse format of :[:alt] + * we assume at least two elements in the value string + */ + n = sscanf(opt_poi, "%lf:%lf:%lf", &lat, &lng, &alt); + if (n >= 2) { + db(3, "found %d elems '%s':poi=%s@%d, lat=%f, lng=%f, alt=%f over=%s\n", n, opt_poi, poinames[poinum], poinum, lat, lng, alt); + lla2ecef(lat, lng, alt, &ecef_x, &ecef_y, &ecef_z); + db(1, MYNAME ": set POI[%s]='%f %f %f/%f %f %f'\n", poinames[poinum], lat, lng, alt, ecef_x, ecef_y, ecef_z); + be_write16(MSG_SET_POI+1, poinum); + be_write_double(MSG_SET_POI+3, ecef_x); + be_write_double(MSG_SET_POI+11, ecef_y); + be_write_double(MSG_SET_POI+19, ecef_z); + MSG_SET_POI[27]=0; + if (skytraq_wr_msg_verify((gbuint8*)&MSG_SET_POI, sizeof(MSG_SET_POI)) == res_OK) { + result=1; + } else { + warning(MYNAME ": cannot set poi %d '%s'\n", poinum, poinames[poinum]); + result=-1; + } + } else { + warning(MYNAME ": argument to %s needs to be like :[:]\n", poinames[poinum]); + result=-1; + } } - return result; + } + return result; } static const char *mhport; static void miniHomer_rd_init(const char *fname) { - opt_set_location=""; // otherwise it will lead to bus error - skytraq_rd_init(fname); // sets global var serial_handle - mhport=fname; + opt_set_location=""; // otherwise it will lead to bus error + skytraq_rd_init(fname); // sets global var serial_handle + mhport=fname; } -static void +static void miniHomer_rd_deinit(void) { - skytraq_rd_deinit(); + skytraq_rd_deinit(); } #define SETPOI(poinum, poiname) if (opt_set_poi_##poiname ) {miniHomer_set_poi(poinum, opt_set_poi_##poiname);} static void miniHomer_read(void) { - int npoi=0; - /* - * read tracks and POI from miniHomer - */ - if (miniHomer_set_poi (0, opt_set_poi_home) > 0) npoi++; - if (miniHomer_set_poi (1, opt_set_poi_car) > 0) npoi++; - if (miniHomer_set_poi (2, opt_set_poi_boat) > 0) npoi++; - if (miniHomer_set_poi (3, opt_set_poi_heart) > 0) npoi++; - if (miniHomer_set_poi (4, opt_set_poi_bar) > 0) npoi++; - if (npoi == 0) { // do not read if POIs are set (consider set & read distinct operations) - skytraq_read(); // first read tracks (if not supressed by cmd line params) - // we need this call it initialized waypoint list etc... - skytraq_rd_deinit(); // skytraq_read called system_reset, which changes the baud rate. - - skytraq_rd_init(mhport); // Lets start from scratch and re-init the port - miniHomer_get_poi(); // add POI as waypoints to the waypoints of the track - } + int npoi=0; + /* + * read tracks and POI from miniHomer + */ + if (miniHomer_set_poi(0, opt_set_poi_home) > 0) { + npoi++; + } + if (miniHomer_set_poi(1, opt_set_poi_car) > 0) { + npoi++; + } + if (miniHomer_set_poi(2, opt_set_poi_boat) > 0) { + npoi++; + } + if (miniHomer_set_poi(3, opt_set_poi_heart) > 0) { + npoi++; + } + if (miniHomer_set_poi(4, opt_set_poi_bar) > 0) { + npoi++; + } + if (npoi == 0) { // do not read if POIs are set (consider set & read distinct operations) + skytraq_read(); // first read tracks (if not supressed by cmd line params) + // we need this call it initialized waypoint list etc... + skytraq_rd_deinit(); // skytraq_read called system_reset, which changes the baud rate. + + skytraq_rd_init(mhport); // Lets start from scratch and re-init the port + miniHomer_get_poi(); // add POI as waypoints to the waypoints of the track + } } ff_vecs_t miniHomer_vecs = { - ff_type_serial, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - miniHomer_rd_init, - NULL, - miniHomer_rd_deinit, - NULL, - miniHomer_read, - NULL, - NULL, - miniHomer_args, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ + ff_type_serial, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + miniHomer_rd_init, + NULL, + miniHomer_rd_deinit, + NULL, + miniHomer_read, + NULL, + NULL, + miniHomer_args, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything */ }; diff --git a/gpsbabel/smplrout.c b/gpsbabel/smplrout.c index 53ac245c2..db184a0f1 100644 --- a/gpsbabel/smplrout.c +++ b/gpsbabel/smplrout.c @@ -1,5 +1,5 @@ /* - Route / track simplification filter + Route / track simplification filter Copyright (C) 2002 Robert Lipe, robertlipe@usa.net @@ -22,24 +22,24 @@ /* The following comments are from an email I wrote to Paul Fox in November * 2005 in an attempt to explain how the cross track error minimization method * works (RLP 2005): - * - * It's pretty simple, really: for each triplet of vertices A-B-C, we compute - * how much cross-track error we'd introduce by going straight from A to C - * (the maximum cross-track error for that segment is the height of the - * triangle ABC, measured between vertex B and edge AC.) If we need to remove - * 40 points, we just sort the points by that metric and remove the 40 + * + * It's pretty simple, really: for each triplet of vertices A-B-C, we compute + * how much cross-track error we'd introduce by going straight from A to C + * (the maximum cross-track error for that segment is the height of the + * triangle ABC, measured between vertex B and edge AC.) If we need to remove + * 40 points, we just sort the points by that metric and remove the 40 * smallest ones. - * - * It's actually a little more complicated than that, because removing a - * point changes the result for its two nearest neighbors. When we remove - * one, we recompute the neighbors and then sort them back into the list + * + * It's actually a little more complicated than that, because removing a + * point changes the result for its two nearest neighbors. When we remove + * one, we recompute the neighbors and then sort them back into the list * at their new locations. - * - * As you can see, this hasn't been shown to be an optimal algorithm. After - * all, removing one high-xte point might create two very low-xte neighbors - * that more than make up for the high xte of the original point. I believe - * the optimal algorithm would be NP-complete, but I haven't proven it. This - * is really more of a heuristic than anything, but it seems to work well for + * + * As you can see, this hasn't been shown to be an optimal algorithm. After + * all, removing one high-xte point might create two very low-xte neighbors + * that more than make up for the high xte of the original point. I believe + * the optimal algorithm would be NP-complete, but I haven't proven it. This + * is really more of a heuristic than anything, but it seems to work well for * the routes I've fed it. * * Not in that email was an explanation of how the pathlength-based calculation @@ -73,42 +73,52 @@ static char *erroropt; static char *xteopt; static char *lenopt; static char *relopt; -void (*waypt_del_fnp) (route_head *rte, waypoint *wpt); +void (*waypt_del_fnp)(route_head *rte, waypoint *wpt); static arglist_t routesimple_args[] = { - {"count", &countopt, "Maximum number of points in route", - NULL, ARGTYPE_INT | ARGTYPE_BEGIN_REQ | ARGTYPE_BEGIN_EXCL, "1", NULL}, - {"error", &erroropt, "Maximum error", NULL, - ARGTYPE_STRING | ARGTYPE_END_REQ | ARGTYPE_END_EXCL, "0", NULL}, - {"crosstrack", &xteopt, "Use cross-track error (default)", NULL, - ARGTYPE_BOOL | ARGTYPE_BEGIN_EXCL, ARG_NOMINMAX }, - {"length", &lenopt, "Use arclength error", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, - {"relative", &relopt, "Use relative error", NULL, - ARGTYPE_BOOL | ARGTYPE_END_EXCL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "count", &countopt, "Maximum number of points in route", + NULL, ARGTYPE_INT | ARGTYPE_BEGIN_REQ | ARGTYPE_BEGIN_EXCL, "1", NULL + }, + { + "error", &erroropt, "Maximum error", NULL, + ARGTYPE_STRING | ARGTYPE_END_REQ | ARGTYPE_END_EXCL, "0", NULL + }, + { + "crosstrack", &xteopt, "Use cross-track error (default)", NULL, + ARGTYPE_BOOL | ARGTYPE_BEGIN_EXCL, ARG_NOMINMAX + }, + { + "length", &lenopt, "Use arclength error", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "relative", &relopt, "Use relative error", NULL, + ARGTYPE_BOOL | ARGTYPE_END_EXCL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; struct xte_intermed; struct xte { - double distance; - int ordinal; - struct xte_intermed *intermed; + double distance; + int ordinal; + struct xte_intermed *intermed; }; struct xte_intermed { - struct xte *xte_rec; - struct xte_intermed *next; - struct xte_intermed *prev; - const waypoint *wpt; + struct xte *xte_rec; + struct xte_intermed *next; + struct xte_intermed *prev; + const waypoint *wpt; }; void -free_xte( struct xte *xte_rec ) +free_xte(struct xte *xte_rec) { - xfree(xte_rec->intermed); + xfree(xte_rec->intermed); } #define HUGEVAL 2000000000 @@ -118,268 +128,288 @@ static int xte_count = 0; static const route_head *cur_rte = NULL; static struct xte *xte_recs = NULL; -void -routesimple_waypt_pr( const waypoint *wpt ) +void +routesimple_waypt_pr(const waypoint *wpt) { - if ( !cur_rte ) return; - xte_recs[xte_count].ordinal=xte_count; - xte_recs[xte_count].intermed = (struct xte_intermed *) xmalloc( sizeof(struct xte_intermed)); - xte_recs[xte_count].intermed->wpt = wpt; - xte_recs[xte_count].intermed->xte_rec = xte_recs+xte_count; - xte_recs[xte_count].intermed->next = NULL; - xte_recs[xte_count].intermed->prev = tmpprev; - if ( tmpprev ) { - tmpprev->next = xte_recs[xte_count].intermed; - } - tmpprev = xte_recs[xte_count].intermed; - xte_count++; + if (!cur_rte) { + return; + } + xte_recs[xte_count].ordinal=xte_count; + xte_recs[xte_count].intermed = (struct xte_intermed *) xmalloc(sizeof(struct xte_intermed)); + xte_recs[xte_count].intermed->wpt = wpt; + xte_recs[xte_count].intermed->xte_rec = xte_recs+xte_count; + xte_recs[xte_count].intermed->next = NULL; + xte_recs[xte_count].intermed->prev = tmpprev; + if (tmpprev) { + tmpprev->next = xte_recs[xte_count].intermed; + } + tmpprev = xte_recs[xte_count].intermed; + xte_count++; } void -compute_xte( struct xte *xte_rec ) { - const waypoint *wpt3 = xte_rec->intermed->wpt; - const waypoint *wpt1 = NULL; - const waypoint *wpt2 = NULL; - double frac, reslat, reslon; - /* if no previous, this is an endpoint and must be preserved. */ - if ( !xte_rec->intermed->prev ) { - xte_rec->distance = HUGEVAL; - return; - } - wpt1 = xte_rec->intermed->prev->wpt; - - /* if no next, this is an endpoint and must be preserved. */ - if ( !xte_rec->intermed->next ) { - xte_rec->distance = HUGEVAL; - return; - } - wpt2 = xte_rec->intermed->next->wpt; - - if ( xteopt ) { - xte_rec->distance = radtomiles(linedist( - wpt1->latitude, wpt1->longitude, - wpt2->latitude, wpt2->longitude, - wpt3->latitude, wpt3->longitude )); - } - else if ( lenopt ) { - xte_rec->distance = radtomiles( - gcdist( wpt1->latitude, wpt1->longitude, - wpt3->latitude, wpt3->longitude ) + - gcdist( wpt3->latitude, wpt3->longitude, - wpt2->latitude, wpt2->longitude ) - - gcdist( wpt1->latitude, wpt1->longitude, - wpt2->latitude, wpt2->longitude )); - } - else if ( relopt ) { - if ( wpt3->hdop == 0 ) { - fatal( MYNAME ": relative needs hdop information.\n"); - } - // if timestamps exist, distance to interpolated point - if ( wpt1->creation_time != wpt2->creation_time ) { - frac = (double)(wpt3->creation_time - wpt1->creation_time) / - (wpt2->creation_time - wpt1->creation_time); - linepart( wpt1->latitude, wpt1->longitude, - wpt2->latitude, wpt2->longitude, - frac, &reslat, &reslon); - xte_rec->distance = radtometers(gcdist( - wpt3->latitude, wpt3->longitude, - reslat, reslon )); - } else { // else distance to connecting line - xte_rec->distance = radtometers(linedist( - wpt1->latitude, wpt1->longitude, - wpt2->latitude, wpt2->longitude, - wpt3->latitude, wpt3->longitude )); - } - // error relative to horizontal precision - xte_rec->distance /= (6 * wpt3->hdop); - // (hdop->meters following to J. Person at ) - - } +compute_xte(struct xte *xte_rec) +{ + const waypoint *wpt3 = xte_rec->intermed->wpt; + const waypoint *wpt1 = NULL; + const waypoint *wpt2 = NULL; + double frac, reslat, reslon; + /* if no previous, this is an endpoint and must be preserved. */ + if (!xte_rec->intermed->prev) { + xte_rec->distance = HUGEVAL; + return; + } + wpt1 = xte_rec->intermed->prev->wpt; + + /* if no next, this is an endpoint and must be preserved. */ + if (!xte_rec->intermed->next) { + xte_rec->distance = HUGEVAL; + return; + } + wpt2 = xte_rec->intermed->next->wpt; + + if (xteopt) { + xte_rec->distance = radtomiles(linedist( + wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude, + wpt3->latitude, wpt3->longitude)); + } else if (lenopt) { + xte_rec->distance = radtomiles( + gcdist(wpt1->latitude, wpt1->longitude, + wpt3->latitude, wpt3->longitude) + + gcdist(wpt3->latitude, wpt3->longitude, + wpt2->latitude, wpt2->longitude) - + gcdist(wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude)); + } else if (relopt) { + if (wpt3->hdop == 0) { + fatal(MYNAME ": relative needs hdop information.\n"); + } + // if timestamps exist, distance to interpolated point + if (wpt1->creation_time != wpt2->creation_time) { + frac = (double)(wpt3->creation_time - wpt1->creation_time) / + (wpt2->creation_time - wpt1->creation_time); + linepart(wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude, + frac, &reslat, &reslon); + xte_rec->distance = radtometers(gcdist( + wpt3->latitude, wpt3->longitude, + reslat, reslon)); + } else { // else distance to connecting line + xte_rec->distance = radtometers(linedist( + wpt1->latitude, wpt1->longitude, + wpt2->latitude, wpt2->longitude, + wpt3->latitude, wpt3->longitude)); + } + // error relative to horizontal precision + xte_rec->distance /= (6 * wpt3->hdop); + // (hdop->meters following to J. Person at ) + + } } int -compare_xte( const void *a, const void *b ) +compare_xte(const void *a, const void *b) { - double distdiff = ((struct xte *)a)->distance - - ((struct xte *)b)->distance; - int priodiff = ((struct xte *)a)->intermed->wpt->route_priority - - ((struct xte *)b)->intermed->wpt->route_priority; - - if (HUGEVAL == ((struct xte *)a)->distance) - return -1; - - if (HUGEVAL == ((struct xte *)b)->distance) - return 1; - - if ( priodiff < 0 ) return 1; - if ( priodiff > 0 ) return -1; - if ( distdiff < 0 ) return 1; - if ( distdiff > 0 ) return -1; - return 0; + double distdiff = ((struct xte *)a)->distance - + ((struct xte *)b)->distance; + int priodiff = ((struct xte *)a)->intermed->wpt->route_priority - + ((struct xte *)b)->intermed->wpt->route_priority; + + if (HUGEVAL == ((struct xte *)a)->distance) { + return -1; + } + + if (HUGEVAL == ((struct xte *)b)->distance) { + return 1; + } + + if (priodiff < 0) { + return 1; + } + if (priodiff > 0) { + return -1; + } + if (distdiff < 0) { + return 1; + } + if (distdiff > 0) { + return -1; + } + return 0; } -void -routesimple_head( const route_head *rte ) +void +routesimple_head(const route_head *rte) { - cur_rte = NULL; - /* build array of XTE/wpt xref records */ - xte_count = 0; - tmpprev = NULL; - totalerror = 0; - - /* short-circuit if we already have fewer than the max points */ - if ( countopt && count >= rte->rte_waypt_ct) return; - - /* short-circuit if the route is impossible to simplify, too. */ - if ( 2 >= rte->rte_waypt_ct ) return; - - xte_recs = (struct xte *) xcalloc( rte->rte_waypt_ct, sizeof (struct xte)); - cur_rte = rte; - + cur_rte = NULL; + /* build array of XTE/wpt xref records */ + xte_count = 0; + tmpprev = NULL; + totalerror = 0; + + /* short-circuit if we already have fewer than the max points */ + if (countopt && count >= rte->rte_waypt_ct) { + return; + } + + /* short-circuit if the route is impossible to simplify, too. */ + if (2 >= rte->rte_waypt_ct) { + return; + } + + xte_recs = (struct xte *) xcalloc(rte->rte_waypt_ct, sizeof(struct xte)); + cur_rte = rte; + } void -shuffle_xte( struct xte *xte_rec ) +shuffle_xte(struct xte *xte_rec) { - struct xte tmp_xte; - while ( xte_rec > xte_recs && compare_xte(xte_rec, xte_rec-1) < 0 ) { - tmp_xte.distance = xte_rec->distance; - tmp_xte.ordinal = xte_rec->ordinal; - tmp_xte.intermed = xte_rec->intermed; - xte_rec->distance = xte_rec[-1].distance; - xte_rec->ordinal = xte_rec[-1].ordinal; - xte_rec->intermed = xte_rec[-1].intermed; - xte_rec->intermed->xte_rec = xte_rec; - xte_rec--; - xte_rec->distance = tmp_xte.distance; - xte_rec->ordinal = tmp_xte.ordinal; - xte_rec->intermed = tmp_xte.intermed; - xte_rec->intermed->xte_rec = xte_rec; - } - while ( xte_rec - xte_recs < xte_count-2 && - compare_xte( xte_rec, xte_rec+1) > 0 ) { - tmp_xte.distance = xte_rec->distance; - tmp_xte.ordinal = xte_rec->ordinal; - tmp_xte.intermed = xte_rec->intermed; - xte_rec->distance = xte_rec[1].distance; - xte_rec->ordinal = xte_rec[1].ordinal; - xte_rec->intermed = xte_rec[1].intermed; - xte_rec->intermed->xte_rec = xte_rec; - xte_rec++; - xte_rec->distance = tmp_xte.distance; - xte_rec->ordinal = tmp_xte.ordinal; - xte_rec->intermed = tmp_xte.intermed; - xte_rec->intermed->xte_rec = xte_rec; - } + struct xte tmp_xte; + while (xte_rec > xte_recs && compare_xte(xte_rec, xte_rec-1) < 0) { + tmp_xte.distance = xte_rec->distance; + tmp_xte.ordinal = xte_rec->ordinal; + tmp_xte.intermed = xte_rec->intermed; + xte_rec->distance = xte_rec[-1].distance; + xte_rec->ordinal = xte_rec[-1].ordinal; + xte_rec->intermed = xte_rec[-1].intermed; + xte_rec->intermed->xte_rec = xte_rec; + xte_rec--; + xte_rec->distance = tmp_xte.distance; + xte_rec->ordinal = tmp_xte.ordinal; + xte_rec->intermed = tmp_xte.intermed; + xte_rec->intermed->xte_rec = xte_rec; + } + while (xte_rec - xte_recs < xte_count-2 && + compare_xte(xte_rec, xte_rec+1) > 0) { + tmp_xte.distance = xte_rec->distance; + tmp_xte.ordinal = xte_rec->ordinal; + tmp_xte.intermed = xte_rec->intermed; + xte_rec->distance = xte_rec[1].distance; + xte_rec->ordinal = xte_rec[1].ordinal; + xte_rec->intermed = xte_rec[1].intermed; + xte_rec->intermed->xte_rec = xte_rec; + xte_rec++; + xte_rec->distance = tmp_xte.distance; + xte_rec->ordinal = tmp_xte.ordinal; + xte_rec->intermed = tmp_xte.intermed; + xte_rec->intermed->xte_rec = xte_rec; + } } -void -routesimple_tail( const route_head *rte ) +void +routesimple_tail(const route_head *rte) { - int i; - if ( !cur_rte ) return; - - /* compute all distances */ - for (i = 0; i < xte_count ; i++ ) { - compute_xte( xte_recs+i ); - } - - - /* sort XTE array, lowest XTE last */ - qsort( xte_recs, xte_count, sizeof( struct xte ), compare_xte ); - - for (i = 0; i < xte_count; i++ ) { - xte_recs[i].intermed->xte_rec = xte_recs+i; - } - /* while we still have too many records... */ - while ( (xte_count) && ((countopt && count < xte_count) || (erroropt && totalerror < error))) { - i = xte_count - 1; - /* remove the record with the lowest XTE */ - if ( erroropt ) { - if ( xteopt || relopt ) { - if ( i > 1 ) { - totalerror = xte_recs[i-1].distance; - } - else { - totalerror = xte_recs[i].distance; - } - } - if ( lenopt ) { - totalerror += xte_recs[i].distance; - } - } - (*waypt_del_fnp)( (route_head *)(void *)rte, - (waypoint *)(void *)(xte_recs[i].intermed->wpt)); - waypt_free((waypoint *)(void *)(xte_recs[i].intermed->wpt)); - - if ( xte_recs[i].intermed->prev ) { - xte_recs[i].intermed->prev->next = xte_recs[i].intermed->next; - compute_xte(xte_recs[i].intermed->prev->xte_rec); - shuffle_xte(xte_recs[i].intermed->prev->xte_rec); - } - if ( xte_recs[i].intermed->next ) { - xte_recs[i].intermed->next->prev = xte_recs[i].intermed->prev; - compute_xte(xte_recs[i].intermed->next->xte_rec); - shuffle_xte(xte_recs[i].intermed->next->xte_rec); - } - xte_count--; - free_xte( xte_recs+xte_count); - /* end of loop */ - } - if ( xte_count ) { - do { - xte_count--; - free_xte( xte_recs+xte_count ); - } while(xte_count); - } - xfree( xte_recs ); + int i; + if (!cur_rte) { + return; + } + + /* compute all distances */ + for (i = 0; i < xte_count ; i++) { + compute_xte(xte_recs+i); + } + + + /* sort XTE array, lowest XTE last */ + qsort(xte_recs, xte_count, sizeof(struct xte), compare_xte); + + for (i = 0; i < xte_count; i++) { + xte_recs[i].intermed->xte_rec = xte_recs+i; + } + /* while we still have too many records... */ + while ((xte_count) && ((countopt && count < xte_count) || (erroropt && totalerror < error))) { + i = xte_count - 1; + /* remove the record with the lowest XTE */ + if (erroropt) { + if (xteopt || relopt) { + if (i > 1) { + totalerror = xte_recs[i-1].distance; + } else { + totalerror = xte_recs[i].distance; + } + } + if (lenopt) { + totalerror += xte_recs[i].distance; + } + } + (*waypt_del_fnp)((route_head *)(void *)rte, + (waypoint *)(void *)(xte_recs[i].intermed->wpt)); + waypt_free((waypoint *)(void *)(xte_recs[i].intermed->wpt)); + + if (xte_recs[i].intermed->prev) { + xte_recs[i].intermed->prev->next = xte_recs[i].intermed->next; + compute_xte(xte_recs[i].intermed->prev->xte_rec); + shuffle_xte(xte_recs[i].intermed->prev->xte_rec); + } + if (xte_recs[i].intermed->next) { + xte_recs[i].intermed->next->prev = xte_recs[i].intermed->prev; + compute_xte(xte_recs[i].intermed->next->xte_rec); + shuffle_xte(xte_recs[i].intermed->next->xte_rec); + } + xte_count--; + free_xte(xte_recs+xte_count); + /* end of loop */ + } + if (xte_count) { + do { + xte_count--; + free_xte(xte_recs+xte_count); + } while (xte_count); + } + xfree(xte_recs); } -void -routesimple_process( void ) +void +routesimple_process(void) { - waypt_del_fnp = route_del_wpt; - route_disp_all( routesimple_head, routesimple_tail, routesimple_waypt_pr ); + waypt_del_fnp = route_del_wpt; + route_disp_all(routesimple_head, routesimple_tail, routesimple_waypt_pr); - waypt_del_fnp = track_del_wpt; - track_disp_all( routesimple_head, routesimple_tail, routesimple_waypt_pr ); + waypt_del_fnp = track_del_wpt; + track_disp_all(routesimple_head, routesimple_tail, routesimple_waypt_pr); } void -routesimple_init(const char *args) { - count = 0; - - if ( !!countopt == !!erroropt ) { - fatal( MYNAME ": You must specify either count or error, but not both.\n"); - } - if ( (!!xteopt + !!lenopt + !!relopt) > 1 ) { - fatal( MYNAME ": You may specify only one of crosstrack, length, or relative.\n"); - } - if ( !xteopt && !lenopt && !relopt) { - xteopt = ""; - } - - if (countopt) { - count = atol(countopt); - } - if (erroropt) { - int res = parse_distance(erroropt, &error, 1.0, MYNAME); - if (res == 0) error = 0; - else if (res == 2) /* parameter with unit */ - error = METERS_TO_MILES(error); - } +routesimple_init(const char *args) +{ + count = 0; + + if (!!countopt == !!erroropt) { + fatal(MYNAME ": You must specify either count or error, but not both.\n"); + } + if ((!!xteopt + !!lenopt + !!relopt) > 1) { + fatal(MYNAME ": You may specify only one of crosstrack, length, or relative.\n"); + } + if (!xteopt && !lenopt && !relopt) { + xteopt = ""; + } + + if (countopt) { + count = atol(countopt); + } + if (erroropt) { + int res = parse_distance(erroropt, &error, 1.0, MYNAME); + if (res == 0) { + error = 0; + } else if (res == 2) { /* parameter with unit */ + error = METERS_TO_MILES(error); + } + } } void -routesimple_deinit(void) { - /* do nothing */ +routesimple_deinit(void) +{ + /* do nothing */ } filter_vecs_t routesimple_vecs = { - routesimple_init, - routesimple_process, - routesimple_deinit, - NULL, - routesimple_args + routesimple_init, + routesimple_process, + routesimple_deinit, + NULL, + routesimple_args }; diff --git a/gpsbabel/sort.c b/gpsbabel/sort.c index cac8669e5..b3c526340 100644 --- a/gpsbabel/sort.c +++ b/gpsbabel/sort.c @@ -24,11 +24,11 @@ #if FILTERS_ENABLED typedef enum { - sm_unknown = 0, - sm_gcid, - sm_shortname, - sm_description, - sm_time + sm_unknown = 0, + sm_gcid, + sm_shortname, + sm_description, + sm_time } sort_mode_; sort_mode_ sort_mode = sm_shortname; /* How are we sorting these? */ @@ -37,56 +37,74 @@ static char *opt_sm_gcid, *opt_sm_shortname, *opt_sm_description, *opt_sm_time; static arglist_t sort_args[] = { - {"gcid", &opt_sm_gcid, "Sort by numeric geocache ID", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"shortname", &opt_sm_shortname, "Sort by waypoint short name", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"description", &opt_sm_description, "Sort by waypoint description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"time", &opt_sm_time, "Sort by time", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "gcid", &opt_sm_gcid, "Sort by numeric geocache ID", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "shortname", &opt_sm_shortname, "Sort by waypoint short name", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "description", &opt_sm_description, "Sort by waypoint description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "time", &opt_sm_time, "Sort by time", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static int sort_comp(const queue * a, const queue * b) { - const waypoint *x1 = (waypoint *)a; - const waypoint *x2 = (waypoint *)b; + const waypoint *x1 = (waypoint *)a; + const waypoint *x2 = (waypoint *)b; - switch (sort_mode) { - case sm_gcid: return x1->gc_data->id - x2->gc_data->id; - case sm_shortname: return strcmp (x1->shortname, x2->shortname); - case sm_description: return strcmp (x1->description, x2->description); - case sm_time: return x1->creation_time - x2->creation_time; - default: abort(); return 0; /* Internal caller error. */ - } + switch (sort_mode) { + case sm_gcid: + return x1->gc_data->id - x2->gc_data->id; + case sm_shortname: + return strcmp(x1->shortname, x2->shortname); + case sm_description: + return strcmp(x1->description, x2->description); + case sm_time: + return x1->creation_time - x2->creation_time; + default: + abort(); + return 0; /* Internal caller error. */ + } } -void +void sort_process(void) { - sortqueue(&waypt_head, sort_comp); + sortqueue(&waypt_head, sort_comp); } void -sort_init(const char *args) +sort_init(const char *args) { - if (opt_sm_gcid) - sort_mode = sm_gcid; - if (opt_sm_shortname) - sort_mode = sm_shortname; - if (opt_sm_description) - sort_mode = sm_description; - if (opt_sm_time) - sort_mode = sm_time; + if (opt_sm_gcid) { + sort_mode = sm_gcid; + } + if (opt_sm_shortname) { + sort_mode = sm_shortname; + } + if (opt_sm_description) { + sort_mode = sm_description; + } + if (opt_sm_time) { + sort_mode = sm_time; + } } filter_vecs_t sort_vecs = { - sort_init, - sort_process, - NULL, - NULL, - sort_args + sort_init, + sort_process, + NULL, + NULL, + sort_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/stackfilter.c b/gpsbabel/stackfilter.c index e8bbf71e6..826a71456 100644 --- a/gpsbabel/stackfilter.c +++ b/gpsbabel/stackfilter.c @@ -40,211 +40,225 @@ static int swapdepth = 0; static arglist_t stackfilt_args[] = { - {"push", &opt_push, "Push waypoint list onto stack", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"pop", &opt_pop, "Pop waypoint list from stack", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX}, - {"swap", &opt_swap, "Swap waypoint list with item on stack", - NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"copy", &opt_copy, "(push) Copy waypoint list", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX}, - {"append", &opt_append, "(pop) Append list", NULL, - ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"discard", &opt_discard, "(pop) Discard top of stack", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"replace", &opt_replace, "(pop) Replace list (default)", - NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX}, - {"depth", &opt_depth, "(swap) Item to use (default=1)", - NULL, ARGTYPE_INT, "0", NULL}, - {"nowarn", &nowarn, "Suppress cleanup warning", NULL, - ARGTYPE_BOOL | ARGTYPE_HIDDEN, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "push", &opt_push, "Push waypoint list onto stack", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BEGIN_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "pop", &opt_pop, "Pop waypoint list from stack", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "swap", &opt_swap, "Swap waypoint list with item on stack", + NULL, ARGTYPE_END_EXCL | ARGTYPE_END_REQ | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "copy", &opt_copy, "(push) Copy waypoint list", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "append", &opt_append, "(pop) Append list", NULL, + ARGTYPE_BEGIN_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "discard", &opt_discard, "(pop) Discard top of stack", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "replace", &opt_replace, "(pop) Replace list (default)", + NULL, ARGTYPE_END_EXCL | ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "depth", &opt_depth, "(swap) Item to use (default=1)", + NULL, ARGTYPE_INT, "0", NULL + }, + { + "nowarn", &nowarn, "Suppress cleanup warning", NULL, + ARGTYPE_BOOL | ARGTYPE_HIDDEN, ARG_NOMINMAX + }, + ARG_TERMINATOR }; struct stack_elt { - queue waypts; - queue routes; - queue tracks; - unsigned int waypt_ct; - int route_count; - int track_count; - struct stack_elt *next; + queue waypts; + queue routes; + queue tracks; + unsigned int waypt_ct; + int route_count; + int track_count; + struct stack_elt *next; } *stack = NULL; -void +void stackfilt_process(void) { - struct stack_elt *tmp_elt = NULL; - queue *elem = NULL; - queue *tmp = NULL; - queue tmp_queue; - unsigned int tmp_count; - - if ( opt_push ) { - tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt)); - - QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); - tmp_elt->waypt_ct = waypt_count(); - set_waypt_count(0); - tmp_elt->next = stack; - stack = tmp_elt; - if ( opt_copy ) { - QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { - waypt_add( waypt_dupe((waypoint *)elem)); - } - } - - tmp = NULL; - route_backup( &(tmp_elt->route_count), &tmp ); - QUEUE_MOVE( &(tmp_elt->routes), tmp ); - xfree( tmp ); - if ( !opt_copy ) { - route_flush_all_routes(); - } - - tmp = NULL; - track_backup( &(tmp_elt->track_count), &tmp ); - QUEUE_MOVE( &(tmp_elt->tracks), tmp ); - xfree( tmp ); - if ( !opt_copy ) { - route_flush_all_tracks(); - } - - } - else if ( opt_pop ) { - tmp_elt = stack; - if ( !tmp_elt ) { - fatal( MYNAME ": stack empty\n"); - } - if ( opt_append ) { - QUEUE_FOR_EACH( &(stack->waypts), elem, tmp ) { - waypt_add( (waypoint *)elem); - } - route_append( &(stack->routes)); - route_flush( &(stack->routes)); - track_append( &(stack->tracks)); - route_flush( &(stack->tracks)); - } - else if ( opt_discard ) { - waypt_flush( &(stack->waypts)); - route_flush( &(stack->routes)); - route_flush( &(stack->tracks)); - } - else { - waypt_flush( &waypt_head ); - QUEUE_MOVE(&(waypt_head), &(stack->waypts) ); - set_waypt_count(stack->waypt_ct); - - route_restore( &(stack->routes)); - track_restore( &(stack->tracks)); - } - - stack = tmp_elt->next; - xfree( tmp_elt ); - } - else if ( opt_swap ) { - tmp_elt = stack; - while ( swapdepth > 1 ) { - if ( !tmp_elt->next ) { - fatal (MYNAME ": swap with nonexistent element\n"); - } - tmp_elt = tmp_elt->next; - swapdepth--; - } - QUEUE_MOVE(&tmp_queue, &(tmp_elt->waypts) ); - QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head ); - QUEUE_MOVE(&waypt_head, &tmp_queue ); - - QUEUE_MOVE(&tmp_queue, &(tmp_elt->routes)); - tmp = NULL; - route_backup( &(tmp_elt->route_count), &tmp); - QUEUE_MOVE(&(tmp_elt->routes), tmp ); - xfree( tmp ); - route_restore( &tmp_queue ); - - QUEUE_MOVE(&tmp_queue, &(tmp_elt->tracks)); - tmp = NULL; - track_backup( &(tmp_elt->track_count), &tmp); - QUEUE_MOVE(&(tmp_elt->tracks), tmp ); - xfree( tmp ); - track_restore( &tmp_queue ); - - tmp_count = waypt_count(); - set_waypt_count( tmp_elt->waypt_ct ); - tmp_elt->waypt_ct = tmp_count; - } + struct stack_elt *tmp_elt = NULL; + queue *elem = NULL; + queue *tmp = NULL; + queue tmp_queue; + unsigned int tmp_count; + + if (opt_push) { + tmp_elt = (struct stack_elt *)xmalloc(sizeof(struct stack_elt)); + + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); + tmp_elt->waypt_ct = waypt_count(); + set_waypt_count(0); + tmp_elt->next = stack; + stack = tmp_elt; + if (opt_copy) { + QUEUE_FOR_EACH(&(stack->waypts), elem, tmp) { + waypt_add(waypt_dupe((waypoint *)elem)); + } + } + + tmp = NULL; + route_backup(&(tmp_elt->route_count), &tmp); + QUEUE_MOVE(&(tmp_elt->routes), tmp); + xfree(tmp); + if (!opt_copy) { + route_flush_all_routes(); + } + + tmp = NULL; + track_backup(&(tmp_elt->track_count), &tmp); + QUEUE_MOVE(&(tmp_elt->tracks), tmp); + xfree(tmp); + if (!opt_copy) { + route_flush_all_tracks(); + } + + } else if (opt_pop) { + tmp_elt = stack; + if (!tmp_elt) { + fatal(MYNAME ": stack empty\n"); + } + if (opt_append) { + QUEUE_FOR_EACH(&(stack->waypts), elem, tmp) { + waypt_add((waypoint *)elem); + } + route_append(&(stack->routes)); + route_flush(&(stack->routes)); + track_append(&(stack->tracks)); + route_flush(&(stack->tracks)); + } else if (opt_discard) { + waypt_flush(&(stack->waypts)); + route_flush(&(stack->routes)); + route_flush(&(stack->tracks)); + } else { + waypt_flush(&waypt_head); + QUEUE_MOVE(&(waypt_head), &(stack->waypts)); + set_waypt_count(stack->waypt_ct); + + route_restore(&(stack->routes)); + track_restore(&(stack->tracks)); + } + + stack = tmp_elt->next; + xfree(tmp_elt); + } else if (opt_swap) { + tmp_elt = stack; + while (swapdepth > 1) { + if (!tmp_elt->next) { + fatal(MYNAME ": swap with nonexistent element\n"); + } + tmp_elt = tmp_elt->next; + swapdepth--; + } + QUEUE_MOVE(&tmp_queue, &(tmp_elt->waypts)); + QUEUE_MOVE(&(tmp_elt->waypts), &waypt_head); + QUEUE_MOVE(&waypt_head, &tmp_queue); + + QUEUE_MOVE(&tmp_queue, &(tmp_elt->routes)); + tmp = NULL; + route_backup(&(tmp_elt->route_count), &tmp); + QUEUE_MOVE(&(tmp_elt->routes), tmp); + xfree(tmp); + route_restore(&tmp_queue); + + QUEUE_MOVE(&tmp_queue, &(tmp_elt->tracks)); + tmp = NULL; + track_backup(&(tmp_elt->track_count), &tmp); + QUEUE_MOVE(&(tmp_elt->tracks), tmp); + xfree(tmp); + track_restore(&tmp_queue); + + tmp_count = waypt_count(); + set_waypt_count(tmp_elt->waypt_ct); + tmp_elt->waypt_ct = tmp_count; + } } void -stackfilt_init(const char *args) { - - int invalid = 0; - - if ( nowarn ) { - warnings_enabled = 0; - } - - if ( opt_depth ) { - swapdepth = atoi( opt_depth ); - } - if ( opt_push ) { - if ( opt_pop || opt_append || opt_discard || opt_replace || - opt_swap || opt_depth ) { - invalid = 1; - } - } - else if ( opt_pop ) { - if ( opt_push || opt_copy || opt_swap || opt_depth ) { - invalid = 1; - } - if ( !!opt_append + !!opt_discard + !!opt_replace > 1 ) { - invalid = 1; - } - } - else if ( opt_swap ) { - if ( opt_push || opt_copy || opt_pop || opt_append || - opt_discard || opt_replace ) { - invalid = 1; - } - } - else { - invalid = 1; - } - - if ( invalid ) { - fatal (MYNAME ": invalid combination of options\n"); - } - +stackfilt_init(const char *args) +{ + + int invalid = 0; + + if (nowarn) { + warnings_enabled = 0; + } + + if (opt_depth) { + swapdepth = atoi(opt_depth); + } + if (opt_push) { + if (opt_pop || opt_append || opt_discard || opt_replace || + opt_swap || opt_depth) { + invalid = 1; + } + } else if (opt_pop) { + if (opt_push || opt_copy || opt_swap || opt_depth) { + invalid = 1; + } + if (!!opt_append + !!opt_discard + !!opt_replace > 1) { + invalid = 1; + } + } else if (opt_swap) { + if (opt_push || opt_copy || opt_pop || opt_append || + opt_discard || opt_replace) { + invalid = 1; + } + } else { + invalid = 1; + } + + if (invalid) { + fatal(MYNAME ": invalid combination of options\n"); + } + } void -stackfilt_deinit(void) { - swapdepth = 0; +stackfilt_deinit(void) +{ + swapdepth = 0; } void -stackfilt_exit( void ) { - struct stack_elt *tmp_elt = NULL; - - if ( warnings_enabled && stack ) { - warning( MYNAME " Warning: leftover stack entries; " - "check command line for mistakes\n" ); - } - while ( stack ) { - waypt_flush( &(stack->waypts) ); - tmp_elt = stack; - stack = stack->next; - xfree(tmp_elt); - } +stackfilt_exit(void) +{ + struct stack_elt *tmp_elt = NULL; + + if (warnings_enabled && stack) { + warning(MYNAME " Warning: leftover stack entries; " + "check command line for mistakes\n"); + } + while (stack) { + waypt_flush(&(stack->waypts)); + tmp_elt = stack; + stack = stack->next; + xfree(tmp_elt); + } } filter_vecs_t stackfilt_vecs = { - stackfilt_init, - stackfilt_process, - stackfilt_deinit, - stackfilt_exit, - stackfilt_args + stackfilt_init, + stackfilt_process, + stackfilt_deinit, + stackfilt_exit, + stackfilt_args }; #endif // FILTERS_ENABLED diff --git a/gpsbabel/stmsdf.c b/gpsbabel/stmsdf.c index db9881303..6991f89d9 100644 --- a/gpsbabel/stmsdf.c +++ b/gpsbabel/stmsdf.c @@ -23,7 +23,7 @@ 2006/04/05: initial release (not published in GPSBbabel) 2006/07/19: finished reader and writer for type 4,5,28 of ver. 1 2006/10/31: remove wptdata from case statement (data_write) - + ToDo: Ascending/Descending */ @@ -48,10 +48,10 @@ #define ALT(a) (a->altitude != unknown_alt) ? a->altitude : 0 typedef enum { - sdf_unknown, - sdf_header, - sdf_points, - sdf_custom + sdf_unknown, + sdf_header, + sdf_points, + sdf_custom } sdf_section_e; static gbfile *fin, *fout; @@ -96,9 +96,11 @@ static int opt_route_index_value; static arglist_t stmsdf_args[] = { - { "index", &opt_route_index, - "Index of route (if more than one in source)", "1", ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR + { + "index", &opt_route_index, + "Index of route (if more than one in source)", "1", ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; @@ -107,227 +109,250 @@ arglist_t stmsdf_args[] = { static void parse_header(char *line) { - char *str; - char *key = NULL; - char *prod = NULL; - int column = -1; - - while ((str = csv_lineparse(line, "=", "", lineno))) - { - line = NULL; - column++; - - switch(column) { - case 0: - key = xstrdup(str); - break; - case 1: - if (case_ignore_strcmp(key, "DATUM") == 0) datum = GPS_Lookup_Datum_Index(str); - else if (case_ignore_strcmp(key, "FILEVERSION") == 0) { - int ver = atoi(str); - is_fatal( (ver != 1), - MYNAME ": This version '%d' is not yet supported. Please report!", ver); - } - else if (case_ignore_strcmp(key, "NAME") == 0) rte_name = xstrdup(str); - else if (case_ignore_strcmp(key, "NOTES") == 0) /* ToDo */; - else if (case_ignore_strcmp(key, "SOURCE") == 0) rte_desc = xstrdup(str); - else if (case_ignore_strcmp(key, "TYPE") == 0) { - filetype = atoi(str); - switch(filetype) { - case 4: /* M9 TrackLog (Suunto Sail Manager) */ - case 5: /* route */ - case 28: /* X9 TrackLog (Suunto Trek Manager */ - break; - - case 78: prod = "S6 SkiChrono"; - case 79: prod = "S6 Skilog"; - - default: - if (prod == NULL) prod = "unknown"; - fatal(MYNAME ": Unsupported file type (%s, type %d)!\n", prod, filetype); - } - } - break; - } - } - if (key) xfree(key); - + char *str; + char *key = NULL; + char *prod = NULL; + int column = -1; + + while ((str = csv_lineparse(line, "=", "", lineno))) { + line = NULL; + column++; + + switch (column) { + case 0: + key = xstrdup(str); + break; + case 1: + if (case_ignore_strcmp(key, "DATUM") == 0) { + datum = GPS_Lookup_Datum_Index(str); + } else if (case_ignore_strcmp(key, "FILEVERSION") == 0) { + int ver = atoi(str); + is_fatal((ver != 1), + MYNAME ": This version '%d' is not yet supported. Please report!", ver); + } else if (case_ignore_strcmp(key, "NAME") == 0) { + rte_name = xstrdup(str); + } else if (case_ignore_strcmp(key, "NOTES") == 0) /* ToDo */; + else if (case_ignore_strcmp(key, "SOURCE") == 0) { + rte_desc = xstrdup(str); + } else if (case_ignore_strcmp(key, "TYPE") == 0) { + filetype = atoi(str); + switch (filetype) { + case 4: /* M9 TrackLog (Suunto Sail Manager) */ + case 5: /* route */ + case 28: /* X9 TrackLog (Suunto Trek Manager */ + break; + + case 78: + prod = "S6 SkiChrono"; + case 79: + prod = "S6 Skilog"; + + default: + if (prod == NULL) { + prod = "unknown"; + } + fatal(MYNAME ": Unsupported file type (%s, type %d)!\n", prod, filetype); + } + } + break; + } + } + if (key) { + xfree(key); + } + } static int track_qsort_cb(const void *a, const void *b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; - - return wa->creation_time - wb->creation_time; + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; + + return wa->creation_time - wb->creation_time; } static void finalize_tracks(void) { - waypoint **list; - int count = 0; - queue *elem, *tmp; - int index; - route_head *track = NULL; - int trackno = 0; - - count = 0; - QUEUE_FOR_EACH(&trackpts, elem, tmp) { count++; }; - if (count == 0) return; - - list = (void *)xmalloc(count * sizeof(*list)); - - index = 0; - QUEUE_FOR_EACH(&trackpts, elem, tmp) { - list[index] = (waypoint *)elem; - dequeue(elem); - index++; - } - - qsort(list, count, sizeof(*list), track_qsort_cb); - - for (index = 0; index < count; index++) { - waypoint *wpt = list[index]; - if (wpt->microseconds == 2) { /* log continued */ - track = NULL; - } - if (track == NULL) { - track = route_head_alloc(); - track_add_head(track); - trackno++; - if (rte_name != NULL) { - if (trackno > 1) - xasprintf(&track->rte_name, "%s (%d)", rte_name, trackno); - else - track->rte_name = xstrdup(rte_name); - } - if (rte_desc != NULL) - track->rte_desc = xstrdup(rte_desc); - } - track_add_wpt(track, wpt); - if (wpt->microseconds == 1) { /* log pause */ - track = NULL; - } - wpt->microseconds = 0; - } - - xfree(list); + waypoint **list; + int count = 0; + queue *elem, *tmp; + int index; + route_head *track = NULL; + int trackno = 0; + + count = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { + count++; + }; + if (count == 0) { + return; + } + + list = (void *)xmalloc(count * sizeof(*list)); + + index = 0; + QUEUE_FOR_EACH(&trackpts, elem, tmp) { + list[index] = (waypoint *)elem; + dequeue(elem); + index++; + } + + qsort(list, count, sizeof(*list), track_qsort_cb); + + for (index = 0; index < count; index++) { + waypoint *wpt = list[index]; + if (wpt->microseconds == 2) { /* log continued */ + track = NULL; + } + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + trackno++; + if (rte_name != NULL) { + if (trackno > 1) { + xasprintf(&track->rte_name, "%s (%d)", rte_name, trackno); + } else { + track->rte_name = xstrdup(rte_name); + } + } + if (rte_desc != NULL) { + track->rte_desc = xstrdup(rte_desc); + } + } + track_add_wpt(track, wpt); + if (wpt->microseconds == 1) { /* log pause */ + track = NULL; + } + wpt->microseconds = 0; + } + + xfree(list); } static void parse_point(char *line) { - char *str; - int column = -1; - int what = -1; /* -1 = unknown, 0 = tp, 1 = mp, 2 = wp, 3 = ap */ - waypoint *wpt = NULL; - char *cx; - int hour, min, sec, day, month, year; - - year = hour = -1; - - while ((str = csv_lineparse(line, ",", "", lineno))) - { - - line = NULL; - column++; - - switch(column) { - - case 0: - if (strcmp(str, "\"TP\"") == 0) { - what = 0; - column++; /* skip name */ - } - else if (strcmp(str, "\"MP\"") == 0) what = 1; - else if (strcmp(str, "\"WP\"") == 0) what = 2; - else if (strcmp(str, "\"AP\"") == 0) what = 3; - else { - warning(MYNAME ": Unknown point type %s at line %d!\n", str, lineno); - return; - } - wpt = waypt_new(); - break; - - case 1: - wpt->shortname = csv_stringclean(str, "\""); - if ((what == 2) || (what == 3)) column += 2; /* doesn't have date and time */ - break; - case 2: - sscanf(str, "%d.%d.%d", &day, &month, &year); - break; - case 3: - while ((cx = strchr(str, '.'))) *cx = ':'; - sscanf(str, "%d:%d:%d", &hour, &min, &sec); - break; - case 4: - wpt->latitude = atof(str); - break; - case 5: - wpt->longitude = atof(str); - break; - case 6: - wpt->altitude = atof(str); - break; - case 7: - switch(what) { - case 0: - WAYPT_SET(wpt, speed, atof(str) * 3.6); break; - case 3: - WAYPT_SET(wpt, proximity, atof(str)); - xasprintf(&wpt->notes, "Alarm point: radius=%s", str); - break; - } - break; - case 8: - if (what == 0) WAYPT_SET(wpt, course, atof(str)); - break; - case 9: - case 10: - break; - case 11: - if (what == 1) wpt->microseconds = atoi(str); /* memory point type */ - break; - } - } - - if ((year > -1) && (hour > -1)) { - struct tm tm; - - memset(&tm, 0, sizeof(tm)); - - tm.tm_year = year - 1900; - tm.tm_mon = month - 1; - tm.tm_mday = day; - tm.tm_hour = hour; - tm.tm_min = min; - tm.tm_sec = sec; - - wpt->creation_time = mklocaltime(&tm); - } - - if (datum != DATUM_WGS84) { - double ht; - GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0, - &wpt->latitude, &wpt->longitude, &ht, datum); - } - - switch(what) { - case 0: - case 1: - ENQUEUE_TAIL(&trackpts, &wpt->Q); - break; - case 2: - case 3: - if (route == NULL) { - route = route_head_alloc(); - route_add_head(route); - } - route_add_wpt(route, wpt); - break; - } + char *str; + int column = -1; + int what = -1; /* -1 = unknown, 0 = tp, 1 = mp, 2 = wp, 3 = ap */ + waypoint *wpt = NULL; + char *cx; + int hour, min, sec, day, month, year; + + year = hour = -1; + + while ((str = csv_lineparse(line, ",", "", lineno))) { + + line = NULL; + column++; + + switch (column) { + + case 0: + if (strcmp(str, "\"TP\"") == 0) { + what = 0; + column++; /* skip name */ + } else if (strcmp(str, "\"MP\"") == 0) { + what = 1; + } else if (strcmp(str, "\"WP\"") == 0) { + what = 2; + } else if (strcmp(str, "\"AP\"") == 0) { + what = 3; + } else { + warning(MYNAME ": Unknown point type %s at line %d!\n", str, lineno); + return; + } + wpt = waypt_new(); + break; + + case 1: + wpt->shortname = csv_stringclean(str, "\""); + if ((what == 2) || (what == 3)) { + column += 2; /* doesn't have date and time */ + } + break; + case 2: + sscanf(str, "%d.%d.%d", &day, &month, &year); + break; + case 3: + while ((cx = strchr(str, '.'))) { + *cx = ':'; + } + sscanf(str, "%d:%d:%d", &hour, &min, &sec); + break; + case 4: + wpt->latitude = atof(str); + break; + case 5: + wpt->longitude = atof(str); + break; + case 6: + wpt->altitude = atof(str); + break; + case 7: + switch (what) { + case 0: + WAYPT_SET(wpt, speed, atof(str) * 3.6); + break; + case 3: + WAYPT_SET(wpt, proximity, atof(str)); + xasprintf(&wpt->notes, "Alarm point: radius=%s", str); + break; + } + break; + case 8: + if (what == 0) { + WAYPT_SET(wpt, course, atof(str)); + } + break; + case 9: + case 10: + break; + case 11: + if (what == 1) { + wpt->microseconds = atoi(str); /* memory point type */ + } + break; + } + } + + if ((year > -1) && (hour > -1)) { + struct tm tm; + + memset(&tm, 0, sizeof(tm)); + + tm.tm_year = year - 1900; + tm.tm_mon = month - 1; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = min; + tm.tm_sec = sec; + + wpt->creation_time = mklocaltime(&tm); + } + + if (datum != DATUM_WGS84) { + double ht; + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0, + &wpt->latitude, &wpt->longitude, &ht, datum); + } + + switch (what) { + case 0: + case 1: + ENQUEUE_TAIL(&trackpts, &wpt->Q); + break; + case 2: + case 3: + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, wpt); + break; + } } /* ----------------------------------------------------------- */ @@ -335,403 +360,453 @@ parse_point(char *line) static void rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); - - lineno = 0; - route = NULL; - datum = DATUM_WGS84; - filetype = 28; - rte_name = rte_desc = NULL; - - QUEUE_INIT(&trackpts); + fin = gbfopen(fname, "r", MYNAME); + + lineno = 0; + route = NULL; + datum = DATUM_WGS84; + filetype = 28; + rte_name = rte_desc = NULL; + + QUEUE_INIT(&trackpts); } static void rd_deinit(void) { - gbfclose(fin); - if (rte_name) xfree(rte_name); - if (rte_desc) xfree(rte_desc); + gbfclose(fin); + if (rte_name) { + xfree(rte_name); + } + if (rte_desc) { + xfree(rte_desc); + } } static void data_read(void) { - char *buf; - sdf_section_e section = sdf_unknown; - - while ((buf = gbfgetstr(fin))) - { - char *cin = lrtrim(buf); - if ((lineno++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - if (*cin == '\0') continue; - - if (*cin == '[') - { - char *cend = strchr(++cin, ']'); - - if (cend != NULL) - { - *cend = '\0'; - cin = lrtrim(cin); - } - if ((*cin == '\0') || (cend == NULL)) - fatal(MYNAME ": Invalid section header!\n"); - - if (case_ignore_strcmp(cin, "HEADER") == 0) section = sdf_header; - else if (case_ignore_strcmp(cin, "POINTS") == 0) section = sdf_points; - else if (case_ignore_strncmp(cin, "CUSTOM", 6) == 0) section = sdf_custom; - else { - warning(MYNAME ": Unknown section \"%s\". Please report.\n", cin); - section = sdf_unknown; - } - } - else switch(section) - { - case sdf_header: - parse_header(cin); - break; - case sdf_points: - parse_point(cin); - break; - case sdf_custom: - case sdf_unknown: break; - } - } - finalize_tracks(); /* memory points can be at the end of all trackpoints */ + char *buf; + sdf_section_e section = sdf_unknown; + + while ((buf = gbfgetstr(fin))) { + char *cin = lrtrim(buf); + if ((lineno++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + if (*cin == '\0') { + continue; + } + + if (*cin == '[') { + char *cend = strchr(++cin, ']'); + + if (cend != NULL) { + *cend = '\0'; + cin = lrtrim(cin); + } + if ((*cin == '\0') || (cend == NULL)) { + fatal(MYNAME ": Invalid section header!\n"); + } + + if (case_ignore_strcmp(cin, "HEADER") == 0) { + section = sdf_header; + } else if (case_ignore_strcmp(cin, "POINTS") == 0) { + section = sdf_points; + } else if (case_ignore_strncmp(cin, "CUSTOM", 6) == 0) { + section = sdf_custom; + } else { + warning(MYNAME ": Unknown section \"%s\". Please report.\n", cin); + section = sdf_unknown; + } + } else switch (section) { + case sdf_header: + parse_header(cin); + break; + case sdf_points: + parse_point(cin); + break; + case sdf_custom: + case sdf_unknown: + break; + } + } + finalize_tracks(); /* memory points can be at the end of all trackpoints */ } static void -calculate(const waypoint *wpt, double *dist, double *speed, double *course, - double *asc, double *desc) +calculate(const waypoint *wpt, double *dist, double *speed, double *course, + double *asc, double *desc) { - if (trkpt_out != NULL) { - - time_t time; - - *course = heading_true_degrees( - RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), - RAD(wpt->latitude), RAD(wpt->longitude)); - - *dist = radtometers(gcdist( - RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), - RAD(wpt->latitude), RAD(wpt->longitude))); - if (*dist < 0.1) *dist = 0; /* calc. diffs on 32- and 64-bit hosts */ - - time = wpt->creation_time - trkpt_out->creation_time; - if (time == 0) - *speed = 0; - else - *speed = *dist / (double)time; - - if (asc && desc && (trkpt_out->altitude != unknown_alt) && (wpt->altitude != unknown_alt)) { - double dh = wpt->altitude - trkpt_out->altitude; - if (dh > 0) - *asc += dh; - else - *desc -= dh; - } - } - else { - *speed = 0; - *dist = 0; - *course = 0; - if (asc) *asc = 0; - if (desc) *desc = 0; - } - if WAYPT_HAS(wpt, speed) *speed = wpt->speed / 3.6; /* -> meters per second */ - if WAYPT_HAS(wpt, course) *course = wpt->course; - + if (trkpt_out != NULL) { + + time_t time; + + *course = heading_true_degrees( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude)); + + *dist = radtometers(gcdist( + RAD(trkpt_out->latitude), RAD(trkpt_out->longitude), + RAD(wpt->latitude), RAD(wpt->longitude))); + if (*dist < 0.1) { + *dist = 0; /* calc. diffs on 32- and 64-bit hosts */ + } + + time = wpt->creation_time - trkpt_out->creation_time; + if (time == 0) { + *speed = 0; + } else { + *speed = *dist / (double)time; + } + + if (asc && desc && (trkpt_out->altitude != unknown_alt) && (wpt->altitude != unknown_alt)) { + double dh = wpt->altitude - trkpt_out->altitude; + if (dh > 0) { + *asc += dh; + } else { + *desc -= dh; + } + } + } else { + *speed = 0; + *dist = 0; + *course = 0; + if (asc) { + *asc = 0; + } + if (desc) { + *desc = 0; + } + } + if WAYPT_HAS(wpt, speed) { + *speed = wpt->speed / 3.6; /* -> meters per second */ + } + if WAYPT_HAS(wpt, course) { + *course = wpt->course; + } + } /* pre-calculation callbacks */ -static void +static void any_hdr_calc_cb(const route_head *trk) { - - trkpt_out = NULL; - this_distance = 0; - this_time = 0; - this_points = 0; - - this_index++; - this_valid = ((opt_route_index_value < 1) || (opt_route_index_value == this_index)); - if (! this_valid) return; - - if (!rte_name && trk->rte_name) { - rte_name = trk->rte_name; - rte_desc = trk->rte_desc; - } - - trk_out = (route_head *)trk; + + trkpt_out = NULL; + this_distance = 0; + this_time = 0; + this_points = 0; + + this_index++; + this_valid = ((opt_route_index_value < 1) || (opt_route_index_value == this_index)); + if (! this_valid) { + return; + } + + if (!rte_name && trk->rte_name) { + rte_name = trk->rte_name; + rte_desc = trk->rte_desc; + } + + trk_out = (route_head *)trk; } -static void +static void any_waypt_calc_cb(const waypoint *wpt) { - double speed, course, dist; - - /* we can only write ONE route */ - if (! this_valid) return; - - if ((all_points == 0) && (this_points == 0)) start_time = wpt->creation_time; - - this_points++; - - if ((wpt->altitude != unknown_alt) && (wpt->altitude < minalt)) minalt = wpt->altitude; - if ((wpt->altitude != unknown_alt) && (wpt->altitude > maxalt)) maxalt = wpt->altitude; - calculate(wpt, &dist, &speed, &course, &all_asc, &all_desc); - if (speed > maxspeed) maxspeed = speed; - - this_distance = this_distance + dist; - if (trkpt_out != NULL) - this_time += (wpt->creation_time - trkpt_out->creation_time); - - trkpt_out = (waypoint *)wpt; + double speed, course, dist; + + /* we can only write ONE route */ + if (! this_valid) { + return; + } + + if ((all_points == 0) && (this_points == 0)) { + start_time = wpt->creation_time; + } + + this_points++; + + if ((wpt->altitude != unknown_alt) && (wpt->altitude < minalt)) { + minalt = wpt->altitude; + } + if ((wpt->altitude != unknown_alt) && (wpt->altitude > maxalt)) { + maxalt = wpt->altitude; + } + calculate(wpt, &dist, &speed, &course, &all_asc, &all_desc); + if (speed > maxspeed) { + maxspeed = speed; + } + + this_distance = this_distance + dist; + if (trkpt_out != NULL) { + this_time += (wpt->creation_time - trkpt_out->creation_time); + } + + trkpt_out = (waypoint *)wpt; } -static void +static void any_tlr_calc_cb(const route_head *trk) { - if (! this_valid) return; - - all_dist += this_distance; - all_time += this_time; - all_points += this_points; + if (! this_valid) { + return; + } + + all_dist += this_distance; + all_time += this_time; + all_points += this_points; } /* write callbacks */ -static void +static void track_disp_hdr_cb(const route_head *trk) { - track_index++; - track_points = 0; - trk_out = (route_head *)trk; - trkpt_out = NULL; + track_index++; + track_points = 0; + trk_out = (route_head *)trk; + trkpt_out = NULL; } -static void +static void track_disp_wpt_cb(const waypoint *wpt) { - struct tm tm; - char tbuf[32]; - double course, speed, dist; - int flag = 0; - - track_points++; - all_track_points++; - - tm = *localtime(&wpt->creation_time); - strftime(tbuf, sizeof(tbuf), "%d.%m.%Y,%H:%M.%S", &tm); - - calculate(wpt, &dist, &speed, &course, NULL, NULL); - trkpt_dist = trkpt_dist + dist; - - if (track_points == trk_out->rte_waypt_ct) { /* I'm the last in that list */ - if (all_track_points != saved_track_points) { /* but not the overall latest */ - flag = 1; - } - } - else if (track_points == 1) { /* I'm the first in that list */ - if (all_track_points > 1) { /* but not the first ever seen */ - flag = 2; - } - } - - if (flag == 1) { - char *name = wpt->shortname; - if (name == NULL) name = "Log paused"; - gbfprintf(fout, "\"MP\",\"%s\"", name); - } - else if (flag == 2) { - char *name = wpt->shortname; - if (name == NULL) name = "Log continued"; - gbfprintf(fout, "\"MP\",\"%s\"", name); - } - else - gbfprintf(fout, "\"TP\""); - - gbfprintf(fout, ",%s,%.6lf,%.6lf,%.f,%.2f", - tbuf, - wpt->latitude, wpt->longitude, ALT(wpt), speed); - if (flag) - gbfprintf(fout, ",0,0,%d", flag); /* press, temperature, memory point type */ - else - gbfprintf(fout, ",%.1f", course); - - if (trkpt_dist != 0) - gbfprintf(fout, ",%.6f\n", trkpt_dist); - else - gbfprintf(fout, ",0\n"); - - trkpt_out = (waypoint *)wpt; + struct tm tm; + char tbuf[32]; + double course, speed, dist; + int flag = 0; + + track_points++; + all_track_points++; + + tm = *localtime(&wpt->creation_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y,%H:%M.%S", &tm); + + calculate(wpt, &dist, &speed, &course, NULL, NULL); + trkpt_dist = trkpt_dist + dist; + + if (track_points == trk_out->rte_waypt_ct) { /* I'm the last in that list */ + if (all_track_points != saved_track_points) { /* but not the overall latest */ + flag = 1; + } + } else if (track_points == 1) { /* I'm the first in that list */ + if (all_track_points > 1) { /* but not the first ever seen */ + flag = 2; + } + } + + if (flag == 1) { + char *name = wpt->shortname; + if (name == NULL) { + name = "Log paused"; + } + gbfprintf(fout, "\"MP\",\"%s\"", name); + } else if (flag == 2) { + char *name = wpt->shortname; + if (name == NULL) { + name = "Log continued"; + } + gbfprintf(fout, "\"MP\",\"%s\"", name); + } else { + gbfprintf(fout, "\"TP\""); + } + + gbfprintf(fout, ",%s,%.6lf,%.6lf,%.f,%.2f", + tbuf, + wpt->latitude, wpt->longitude, ALT(wpt), speed); + if (flag) { + gbfprintf(fout, ",0,0,%d", flag); /* press, temperature, memory point type */ + } else { + gbfprintf(fout, ",%.1f", course); + } + + if (trkpt_dist != 0) { + gbfprintf(fout, ",%.6f\n", trkpt_dist); + } else { + gbfprintf(fout, ",0\n"); + } + + trkpt_out = (waypoint *)wpt; } -static void +static void track_disp_tlr_cb(const route_head *rte) { - trkpt_out = NULL; + trkpt_out = NULL; } static void route_disp_hdr_cb(const route_head *rte) { - route_index++; - this_route_valid = ((opt_route_index_value < 1) || (opt_route_index_value == track_index)); + route_index++; + this_route_valid = ((opt_route_index_value < 1) || (opt_route_index_value == track_index)); } static void route_disp_wpt_cb(const waypoint *wpt) { - if (this_route_valid) { - char *sn; - - if (global_opts.synthesize_shortnames) - sn = mkshort_from_wpt(short_h, wpt); - else - sn = mkshort(short_h, wpt->shortname); - gbfprintf(fout, "\"WP\",\"%s\",%.8lf,%.8lf,%.f\n", - sn, wpt->latitude, wpt->longitude, ALT(wpt)); - xfree(sn); - } + if (this_route_valid) { + char *sn; + + if (global_opts.synthesize_shortnames) { + sn = mkshort_from_wpt(short_h, wpt); + } else { + sn = mkshort(short_h, wpt->shortname); + } + gbfprintf(fout, "\"WP\",\"%s\",%.8lf,%.8lf,%.f\n", + sn, wpt->latitude, wpt->longitude, ALT(wpt)); + xfree(sn); + } } static void track_disp_custom_cb(const waypoint *wpt) { - if (wpt->creation_time && (wpt->altitude != unknown_alt)) { - gbfprintf(fout, "%d,%.f\n", (int)(wpt->creation_time - start_time), wpt->altitude); - } + if (wpt->creation_time && (wpt->altitude != unknown_alt)) { + gbfprintf(fout, "%d,%.f\n", (int)(wpt->creation_time - start_time), wpt->altitude); + } } static void wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); - short_h = mkshort_new_handle(); + fout = gbfopen(fname, "w", MYNAME); + short_h = mkshort_new_handle(); } static void wr_deinit(void) { - mkshort_del_handle(&short_h); - gbfclose(fout); + mkshort_del_handle(&short_h); + gbfclose(fout); } static void data_write(void) { - gbfprintf(fout, "[HEADER]\n"); - gbfprintf(fout, "FILEVERSION=1\n"); - gbfprintf(fout, "SOURCE=FILE\n"); - gbfprintf(fout, "DATUM=WGS84\n"); - - rte_name = NULL; - rte_desc = NULL; - trkpt_out = NULL; - opt_route_index_value = -1; /* take all tracks from data pool */ - track_index = 0; - minalt = -unknown_alt; - maxalt = unknown_alt; - maxspeed = 0; - all_dist = 0; - all_time = 0; - all_asc = 0; - all_desc = 0; - all_points = 0; - start_time = 0; - - setshort_length(short_h, 100); - setshort_badchars(short_h, "\r\n"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 0); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - - switch(global_opts.objective) - { - case wptdata: - break; - - case rtedata: - gbfprintf(fout, "TYPE=5\n"); - - opt_route_index_value = atoi(opt_route_index); - route_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); - gbfprintf(fout, "DISTANCE=%.f\n", all_dist); - if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); - gbfprintf(fout, "[POINTS]\n"); - if (route_points > 0) { - track_index = 0; - route_disp_all(route_disp_hdr_cb, NULL, route_disp_wpt_cb); - } - break; - - case trkdata: - gbfprintf(fout, "TYPE=28\n"); - - track_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); - if (all_track_points > 0) { - if (rte_name) gbfprintf(fout, "NAME=%s\n", rte_name); - if (minalt != -unknown_alt) gbfprintf(fout, "MINALT=%.f\n", minalt); - if (maxalt != unknown_alt) gbfprintf(fout, "MAXALT=%.f\n", maxalt); - gbfprintf(fout, "MAXSPEED=%.2f\n", maxspeed); - gbfprintf(fout, "DISTANCE=%.f\n", all_dist); - gbfprintf(fout, "DURATION=%lu\n", all_time); + gbfprintf(fout, "[HEADER]\n"); + gbfprintf(fout, "FILEVERSION=1\n"); + gbfprintf(fout, "SOURCE=FILE\n"); + gbfprintf(fout, "DATUM=WGS84\n"); + + rte_name = NULL; + rte_desc = NULL; + trkpt_out = NULL; + opt_route_index_value = -1; /* take all tracks from data pool */ + track_index = 0; + minalt = -unknown_alt; + maxalt = unknown_alt; + maxspeed = 0; + all_dist = 0; + all_time = 0; + all_asc = 0; + all_desc = 0; + all_points = 0; + start_time = 0; + + setshort_length(short_h, 100); + setshort_badchars(short_h, "\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 0); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + + switch (global_opts.objective) { + case wptdata: + break; + + case rtedata: + gbfprintf(fout, "TYPE=5\n"); + + opt_route_index_value = atoi(opt_route_index); + route_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + if (rte_name) { + gbfprintf(fout, "NAME=%s\n", rte_name); + } + gbfprintf(fout, "[POINTS]\n"); + if (route_points > 0) { + track_index = 0; + route_disp_all(route_disp_hdr_cb, NULL, route_disp_wpt_cb); + } + break; + + case trkdata: + gbfprintf(fout, "TYPE=28\n"); + + track_disp_all(any_hdr_calc_cb, any_tlr_calc_cb, any_waypt_calc_cb); + if (all_track_points > 0) { + if (rte_name) { + gbfprintf(fout, "NAME=%s\n", rte_name); + } + if (minalt != -unknown_alt) { + gbfprintf(fout, "MINALT=%.f\n", minalt); + } + if (maxalt != unknown_alt) { + gbfprintf(fout, "MAXALT=%.f\n", maxalt); + } + gbfprintf(fout, "MAXSPEED=%.2f\n", maxspeed); + gbfprintf(fout, "DISTANCE=%.f\n", all_dist); + gbfprintf(fout, "DURATION=%lu\n", all_time); // gbfprintf(fout, "TOTASC=%.f\n", all_asc); // gbfprintf(fout, "TOTDSC=%.f\n", all_desc); - if (start_time) { - struct tm tm; - char tbuf[32]; - - tm = *localtime(&start_time); - strftime(tbuf, sizeof(tbuf), "%d.%m.%Y %H:%M.%S", &tm); - gbfprintf(fout, "DATE=%s\n", tbuf); - } - if (all_time) gbfprintf(fout, "AVGSPEED=%.2f\n", all_dist / (double)all_time); - } - gbfprintf(fout, "[POINTS]\n"); - if (all_track_points > 0) { - - trkpt_dist = 0; - saved_track_points = all_track_points; - all_track_points = 0; - track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); - - if (start_time) { - gbfprintf(fout, "[CUSTOM1]\n"); - track_index = 0; - track_disp_all(NULL, NULL, track_disp_custom_cb); - } - } - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + if (start_time) { + struct tm tm; + char tbuf[32]; + + tm = *localtime(&start_time); + strftime(tbuf, sizeof(tbuf), "%d.%m.%Y %H:%M.%S", &tm); + gbfprintf(fout, "DATE=%s\n", tbuf); + } + if (all_time) { + gbfprintf(fout, "AVGSPEED=%.2f\n", all_dist / (double)all_time); + } + } + gbfprintf(fout, "[POINTS]\n"); + if (all_track_points > 0) { + + trkpt_dist = 0; + saved_track_points = all_track_points; + all_track_points = 0; + track_disp_all(track_disp_hdr_cb, track_disp_tlr_cb, track_disp_wpt_cb); + + if (start_time) { + gbfprintf(fout, "[CUSTOM1]\n"); + track_index = 0; + track_disp_all(NULL, NULL, track_disp_custom_cb); + } + } + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } /* ------------------------------------------------------------------ */ ff_vecs_t stmsdf_vecs = { - ff_type_file, - { ff_cap_none, - ff_cap_read | ff_cap_write, - ff_cap_read | ff_cap_write }, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - stmsdf_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + { + ff_cap_none, + ff_cap_read | ff_cap_write, + ff_cap_read | ff_cap_write + }, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + stmsdf_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; /* ================================================================== */ diff --git a/gpsbabel/stmwpp.c b/gpsbabel/stmwpp.c index 14be1f683..b7a3794e9 100644 --- a/gpsbabel/stmwpp.c +++ b/gpsbabel/stmwpp.c @@ -1,23 +1,23 @@ - /* +/* - Support for "Suunto Trek Manager" (STM) WaypointPlus files, - see homepage "http://www.suunto.fi" for more details, + Support for "Suunto Trek Manager" (STM) WaypointPlus files, + see homepage "http://www.suunto.fi" for more details, - Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org + Copyright (C) 2005,2007 Olaf Klein, o.b.klein@gpsbabel.org - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ @@ -49,282 +49,289 @@ static int what; static char *index_opt = NULL; static -arglist_t stmwpp_args[] = -{ - {"index", &index_opt, "Index of route/track to write (if more than one in source)", - NULL, ARGTYPE_INT, "1", NULL }, - ARG_TERMINATOR +arglist_t stmwpp_args[] = { + { + "index", &index_opt, "Index of route/track to write (if more than one in source)", + NULL, ARGTYPE_INT, "1", NULL + }, + ARG_TERMINATOR }; static void stmwpp_rd_init(const char *fname) { - fin = gbfopen(fname, "rb", MYNAME); - track = NULL; - route = NULL; - wpt = NULL; + fin = gbfopen(fname, "rb", MYNAME); + track = NULL; + route = NULL; + wpt = NULL; } static void stmwpp_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void stmwpp_data_read(void) { - char *buff; - int line = 0; - - what = STM_NOTHING; - buff = gbfgetstr(fin); - buff = (buff == NULL) ? "" : buff; - - if (case_ignore_strncmp(buff, "Datum,WGS 84,WGS 84,", 20) != 0) - fatal(MYNAME ": Invalid GPS datum or not \"WaypointPlus\"\" file!\n"); - - while ((buff = gbfgetstr(fin))) - { - char *c; - int column = -1; - struct tm time; - - if ((line++ == 0) && fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - buff = lrtrim(buff); - if (*buff == '\0') continue; - - wpt = NULL; - memset(&time, 0, sizeof(time)); - - while ((c = csv_lineparse(buff, ",", "", column++))) - { - int new_what; - int fracsec; - - buff = NULL; - - switch(column) - { - case 0: - if (case_ignore_strcmp(c, "WP") == 0) - { - new_what = STM_WAYPT; - } - else if (case_ignore_strcmp(c, "TP") == 0) - { - new_what = STM_TRKPT; - } - else - fatal(MYNAME ": Unknown feature \"%s\"!\n", c); - - if ((what != STM_NOTHING) && (new_what != what)) - fatal(MYNAME ": Only one feature (route or track) is supported by STM!\n"); - - what = new_what; - wpt = waypt_new(); - break; - - case 1: - if (what == STM_TRKPT) column++; /* no name -> skip column two */ - break; - - case 2: - wpt->shortname = xstrdup(c); - break; - - case 3: - wpt->latitude = atof(c); - break; - - case 4: - wpt->longitude = atof(c); - break; - - case 5: - sscanf(c, "%d/%d/%d", &time.tm_mon, &time.tm_mday, &time.tm_year); - break; - - case 6: - sscanf(c, "%d:%d:%d.%d", &time.tm_hour, &time.tm_min, &time.tm_sec, &fracsec); - wpt->microseconds = MILLI_TO_MICRO(fracsec); - /* makes sense only for recorded trackpoints */ - if (what != STM_TRKPT) wpt->microseconds = 0; - break; - - default: - break; - } - } - if (wpt != NULL) - { - time.tm_year -= 1900; - time.tm_mon--; - wpt->creation_time = mkgmtime(&time); - - switch(what) - { - case STM_WAYPT: - waypt_add(wpt); - if (global_opts.objective == rtedata) { - if (route == NULL) { - route = route_head_alloc(); - route_add_head(route); - } - route_add_wpt(route, waypt_dupe(wpt)); - } - break; - - case STM_TRKPT: - if (track == NULL) - { - track = route_head_alloc(); - track_add_head(track); - } - track_add_wpt(track, wpt); - break; - } - wpt = NULL; - } - } + char *buff; + int line = 0; + + what = STM_NOTHING; + buff = gbfgetstr(fin); + buff = (buff == NULL) ? "" : buff; + + if (case_ignore_strncmp(buff, "Datum,WGS 84,WGS 84,", 20) != 0) { + fatal(MYNAME ": Invalid GPS datum or not \"WaypointPlus\"\" file!\n"); + } + + while ((buff = gbfgetstr(fin))) { + char *c; + int column = -1; + struct tm time; + + if ((line++ == 0) && fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + buff = lrtrim(buff); + if (*buff == '\0') { + continue; + } + + wpt = NULL; + memset(&time, 0, sizeof(time)); + + while ((c = csv_lineparse(buff, ",", "", column++))) { + int new_what; + int fracsec; + + buff = NULL; + + switch (column) { + case 0: + if (case_ignore_strcmp(c, "WP") == 0) { + new_what = STM_WAYPT; + } else if (case_ignore_strcmp(c, "TP") == 0) { + new_what = STM_TRKPT; + } else { + fatal(MYNAME ": Unknown feature \"%s\"!\n", c); + } + + if ((what != STM_NOTHING) && (new_what != what)) { + fatal(MYNAME ": Only one feature (route or track) is supported by STM!\n"); + } + + what = new_what; + wpt = waypt_new(); + break; + + case 1: + if (what == STM_TRKPT) { + column++; /* no name -> skip column two */ + } + break; + + case 2: + wpt->shortname = xstrdup(c); + break; + + case 3: + wpt->latitude = atof(c); + break; + + case 4: + wpt->longitude = atof(c); + break; + + case 5: + sscanf(c, "%d/%d/%d", &time.tm_mon, &time.tm_mday, &time.tm_year); + break; + + case 6: + sscanf(c, "%d:%d:%d.%d", &time.tm_hour, &time.tm_min, &time.tm_sec, &fracsec); + wpt->microseconds = MILLI_TO_MICRO(fracsec); + /* makes sense only for recorded trackpoints */ + if (what != STM_TRKPT) { + wpt->microseconds = 0; + } + break; + + default: + break; + } + } + if (wpt != NULL) { + time.tm_year -= 1900; + time.tm_mon--; + wpt->creation_time = mkgmtime(&time); + + switch (what) { + case STM_WAYPT: + waypt_add(wpt); + if (global_opts.objective == rtedata) { + if (route == NULL) { + route = route_head_alloc(); + route_add_head(route); + } + route_add_wpt(route, waypt_dupe(wpt)); + } + break; + + case STM_TRKPT: + if (track == NULL) { + track = route_head_alloc(); + track_add_head(track); + } + track_add_wpt(track, wpt); + break; + } + wpt = NULL; + } + } } static void stmwpp_rw_init(const char *fname) { - fout = gbfopen(fname, "wb", MYNAME); - short_h = mkshort_new_handle(); + fout = gbfopen(fname, "wb", MYNAME); + short_h = mkshort_new_handle(); } static void stmwpp_rw_deinit(void) { - mkshort_del_handle(&short_h); - gbfclose(fout); + mkshort_del_handle(&short_h); + gbfclose(fout); } static void stmwpp_track_hdr(const route_head *track) { - track_num++; + track_num++; } static void stmwpp_write_double(const double val) { - char buff[64]; - char *c; - - c = buff + snprintf(buff, sizeof(buff), "%3.7f", val); - while (*--c == '0') *c = '\0'; - if (*c == '.') *++c = '0'; - gbfprintf(fout, "%s,", buff); + char buff[64]; + char *c; + + c = buff + snprintf(buff, sizeof(buff), "%3.7f", val); + while (*--c == '0') { + *c = '\0'; + } + if (*c == '.') { + *++c = '0'; + } + gbfprintf(fout, "%s,", buff); } static void stmwpp_waypt_cb(const waypoint *wpt) { - char cdate[16], ctime[16]; - struct tm tm; - - if (track_index != track_num) return; - - tm = *gmtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon++; - - snprintf(cdate, sizeof(cdate), "%02d/%02d/%04d", tm.tm_mon, tm.tm_mday, tm.tm_year); - snprintf(ctime, sizeof(ctime), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); - - switch(what) - { - char *sn; - - case STM_WAYPT: - case STM_RTEPT: - if (global_opts.synthesize_shortnames) - sn = mkshort_from_wpt(short_h, wpt); - else - sn = mkshort(short_h, wpt->shortname); - gbfprintf(fout, "WP,D,%s,", sn); - xfree(sn); - break; - - case STM_TRKPT: - gbfprintf(fout, "TP,D,"); - break; - } - stmwpp_write_double(wpt->latitude); - stmwpp_write_double(wpt->longitude); - gbfprintf(fout, "%s,%s", cdate, ctime); - switch(what) - { - case STM_WAYPT: - case STM_RTEPT: - gbfprintf(fout, ".%02d", 0); - break; - case STM_TRKPT: - gbfprintf(fout, ".%03d", MICRO_TO_MILLI(wpt->microseconds)); - break; - } - gbfprintf(fout, ",\r\n"); + char cdate[16], ctime[16]; + struct tm tm; + + if (track_index != track_num) { + return; + } + + tm = *gmtime(&wpt->creation_time); + tm.tm_year += 1900; + tm.tm_mon++; + + snprintf(cdate, sizeof(cdate), "%02d/%02d/%04d", tm.tm_mon, tm.tm_mday, tm.tm_year); + snprintf(ctime, sizeof(ctime), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + + switch (what) { + char *sn; + + case STM_WAYPT: + case STM_RTEPT: + if (global_opts.synthesize_shortnames) { + sn = mkshort_from_wpt(short_h, wpt); + } else { + sn = mkshort(short_h, wpt->shortname); + } + gbfprintf(fout, "WP,D,%s,", sn); + xfree(sn); + break; + + case STM_TRKPT: + gbfprintf(fout, "TP,D,"); + break; + } + stmwpp_write_double(wpt->latitude); + stmwpp_write_double(wpt->longitude); + gbfprintf(fout, "%s,%s", cdate, ctime); + switch (what) { + case STM_WAYPT: + case STM_RTEPT: + gbfprintf(fout, ".%02d", 0); + break; + case STM_TRKPT: + gbfprintf(fout, ".%03d", MICRO_TO_MILLI(wpt->microseconds)); + break; + } + gbfprintf(fout, ",\r\n"); } static void stmwpp_data_write(void) { - setshort_length(short_h, 100); - setshort_badchars(short_h, ",\r\n"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 0); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - - track_num = 0; - if (index_opt != NULL) - track_index = atoi(index_opt); - else - track_index = 1; - - gbfprintf(fout, "Datum,WGS 84,WGS 84,0,0,0,0,0\r\n"); - - switch(global_opts.objective) - { - case wptdata: - what = STM_WAYPT; - track_index = track_num; /* disable filter */ - setshort_defname(short_h, "WPT"); - waypt_disp_all(stmwpp_waypt_cb); - break; - case rtedata: - what = STM_RTEPT; - setshort_defname(short_h, "RPT"); - route_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); - break; - case trkdata: - what = STM_TRKPT; - track_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - break; - } + setshort_length(short_h, 100); + setshort_badchars(short_h, ",\r\n"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 0); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + + track_num = 0; + if (index_opt != NULL) { + track_index = atoi(index_opt); + } else { + track_index = 1; + } + + gbfprintf(fout, "Datum,WGS 84,WGS 84,0,0,0,0,0\r\n"); + + switch (global_opts.objective) { + case wptdata: + what = STM_WAYPT; + track_index = track_num; /* disable filter */ + setshort_defname(short_h, "WPT"); + waypt_disp_all(stmwpp_waypt_cb); + break; + case rtedata: + what = STM_RTEPT; + setshort_defname(short_h, "RPT"); + route_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); + break; + case trkdata: + what = STM_TRKPT; + track_disp_all(stmwpp_track_hdr, NULL, stmwpp_waypt_cb); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + break; + } } ff_vecs_t stmwpp_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - stmwpp_rd_init, - stmwpp_rw_init, - stmwpp_rd_deinit, - stmwpp_rw_deinit, - stmwpp_data_read, - stmwpp_data_write, - NULL, - stmwpp_args, - CET_CHARSET_MS_ANSI, 0 + ff_type_file, + FF_CAP_RW_ALL, + stmwpp_rd_init, + stmwpp_rw_init, + stmwpp_rd_deinit, + stmwpp_rw_deinit, + stmwpp_data_read, + stmwpp_data_write, + NULL, + stmwpp_args, + CET_CHARSET_MS_ANSI, 0 }; #endif /* CSVFMTS_ENABLED */ diff --git a/gpsbabel/strptime.c b/gpsbabel/strptime.c index 7d56a1539..4647a00bd 100644 --- a/gpsbabel/strptime.c +++ b/gpsbabel/strptime.c @@ -52,15 +52,16 @@ # else /* Approximate localtime_r as best we can in its absence. */ # define localtime_r my_localtime_r -static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm *localtime_r __P((const time_t *, struct tm *)); static struct tm * -localtime_r (t, tp) - const time_t *t; - struct tm *tp; +localtime_r(t, tp) +const time_t *t; +struct tm *tp; { - struct tm *l = localtime (t); - if (! l) + struct tm *l = localtime(t); + if (! l) { return 0; + } *tp = *l; return tp; } @@ -84,15 +85,15 @@ static int case_ignore_strncmp(const char *s1, const char *s2, int n) { - int rv = 0; - - while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) - && *s1) { - s1++; - s2++; - n--; - } - return rv; + int rv = 0; + + while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) + && *s1) { + s1++; + s2++; + n--; + } + return rv; } #endif /* We intentionally do not use isdigit() for testing because this will @@ -188,25 +189,21 @@ extern const unsigned short int __mon_yday[2][13]; # define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) #else -static char const weekday_name[][10] = - { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }; -static char const ab_weekday_name[][4] = - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; -static char const month_name[][10] = - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }; -static char const ab_month_name[][4] = - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; +static char const weekday_name[][10] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; +static char const ab_weekday_name[][4] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" +}; +static char const month_name[][10] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" +}; +static char const ab_month_name[][4] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; # define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" # define HERE_D_FMT "%m/%d/%y" # define HERE_AM_STR "AM" @@ -214,13 +211,12 @@ static char const ab_month_name[][4] = # define HERE_T_FMT_AMPM "%I:%M:%S %p" # define HERE_T_FMT "%H:%M:%S" -const unsigned short int __mon_yday[2][13] = - { - /* Normal years. */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years. */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } - }; +const unsigned short int __mon_yday[2][13] = { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; #endif /* Status of lookup: do we use the locale data or the raw data? */ @@ -236,47 +232,47 @@ enum locale_status { not, loc, raw }; /* Compute the day of the week. */ static void -day_of_the_week (struct tm *tm) +day_of_the_week(struct tm *tm) { /* We know that January 1st 1970 was a Thursday (= 4). Compute the the difference between this data in the one on TM and so determine the weekday. */ int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); int wday = (-473 - + (365 * (tm->tm_year - 70)) - + (corr_year / 4) - - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) - + (((corr_year / 4) / 25) / 4) - + __mon_yday[0][tm->tm_mon] - + tm->tm_mday - 1); + + (365 * (tm->tm_year - 70)) + + (corr_year / 4) + - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) + + (((corr_year / 4) / 25) / 4) + + __mon_yday[0][tm->tm_mon] + + tm->tm_mday - 1); tm->tm_wday = ((wday % 7) + 7) % 7; } /* Compute the day of the year. */ static void -day_of_the_year (struct tm *tm) +day_of_the_year(struct tm *tm) { - tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] - + (tm->tm_mday - 1)); + tm->tm_yday = (__mon_yday[__isleap(1900 + tm->tm_year)][tm->tm_mon] + + (tm->tm_mday - 1)); } static char * #ifdef _LIBC internal_function #endif -strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, - enum locale_status *decided, int era_cnt)); +strptime_internal __P((const char *rp, const char *fmt, struct tm *tm, + enum locale_status *decided, int era_cnt)); static char * #ifdef _LIBC internal_function #endif -strptime_internal (rp, fmt, tm, decided, era_cnt) - const char *rp; - const char *fmt; - struct tm *tm; - enum locale_status *decided; - int era_cnt; +strptime_internal(rp, fmt, tm, decided, era_cnt) +const char *rp; +const char *fmt; +struct tm *tm; +enum locale_status *decided; +int era_cnt; { const char *rp_backup; int cnt; @@ -300,715 +296,705 @@ strptime_internal (rp, fmt, tm, decided, era_cnt) have_wday = want_xday = have_yday = have_mon = have_mday = 0; - while (*fmt != '\0') - { - /* A white space in the format string matches 0 more or white - space in the input string. */ - if (isspace (*fmt)) - { - while (isspace (*rp)) - ++rp; - ++fmt; - continue; - } - - /* Any character but `%' must be matched by the same character - in the iput string. */ - if (*fmt != '%') - { - match_char (*fmt++, *rp++); - continue; - } - + while (*fmt != '\0') { + /* A white space in the format string matches 0 more or white + space in the input string. */ + if (isspace(*fmt)) { + while (isspace(*rp)) { + ++rp; + } ++fmt; + continue; + } + + /* Any character but `%' must be matched by the same character + in the iput string. */ + if (*fmt != '%') { + match_char(*fmt++, *rp++); + continue; + } + + ++fmt; #ifndef _NL_CURRENT - /* We need this for handling the `E' modifier. */ - start_over: + /* We need this for handling the `E' modifier. */ +start_over: #endif - /* Make back up of current processing pointer. */ - rp_backup = rp; - - switch (*fmt++) - { - case '%': - /* Match the `%' character itself. */ - match_char ('%', *rp++); - break; - case 'a': - case 'A': - /* Match day of week. */ - for (cnt = 0; cnt < 7; ++cnt) - { + /* Make back up of current processing pointer. */ + rp_backup = rp; + + switch (*fmt++) { + case '%': + /* Match the `%' character itself. */ + match_char('%', *rp++); + break; + case 'a': + case 'A': + /* Match day of week. */ + for (cnt = 0; cnt < 7; ++cnt) { #ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), - weekday_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), - ab_weekday_name[cnt])) - *decided = loc; - break; - } - } + if (*decided !=raw) { + if (match_string(_NL_CURRENT(LC_TIME, DAY_1 + cnt), rp)) { + if (*decided == not + && strcmp(_NL_CURRENT(LC_TIME, DAY_1 + cnt), + weekday_name[cnt])) { + *decided = loc; + } + break; + } + if (match_string(_NL_CURRENT(LC_TIME, ABDAY_1 + cnt), rp)) { + if (*decided == not + && strcmp(_NL_CURRENT(LC_TIME, ABDAY_1 + cnt), + ab_weekday_name[cnt])) { + *decided = loc; + } + break; + } + } #endif - if (*decided != loc - && (match_string (weekday_name[cnt], rp) - || match_string (ab_weekday_name[cnt], rp))) - { - *decided = raw; - break; - } - } - if (cnt == 7) - /* Does not match a weekday name. */ - return NULL; - tm->tm_wday = cnt; - have_wday = 1; - break; - case 'b': - case 'B': - case 'h': - /* Match month name. */ - for (cnt = 0; cnt < 12; ++cnt) - { + if (*decided != loc + && (match_string(weekday_name[cnt], rp) + || match_string(ab_weekday_name[cnt], rp))) { + *decided = raw; + break; + } + } + if (cnt == 7) + /* Does not match a weekday name. */ + { + return NULL; + } + tm->tm_wday = cnt; + have_wday = 1; + break; + case 'b': + case 'B': + case 'h': + /* Match month name. */ + for (cnt = 0; cnt < 12; ++cnt) { #ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), - month_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), - ab_month_name[cnt])) - *decided = loc; - break; - } - } + if (*decided !=raw) { + if (match_string(_NL_CURRENT(LC_TIME, MON_1 + cnt), rp)) { + if (*decided == not + && strcmp(_NL_CURRENT(LC_TIME, MON_1 + cnt), + month_name[cnt])) { + *decided = loc; + } + break; + } + if (match_string(_NL_CURRENT(LC_TIME, ABMON_1 + cnt), rp)) { + if (*decided == not + && strcmp(_NL_CURRENT(LC_TIME, ABMON_1 + cnt), + ab_month_name[cnt])) { + *decided = loc; + } + break; + } + } #endif - if (match_string (month_name[cnt], rp) - || match_string (ab_month_name[cnt], rp)) - { - *decided = raw; - break; - } - } - if (cnt == 12) - /* Does not match a month name. */ - return NULL; - tm->tm_mon = cnt; - want_xday = 1; - break; - case 'c': - /* Match locale's date and time format. */ + if (match_string(month_name[cnt], rp) + || match_string(ab_month_name[cnt], rp)) { + *decided = raw; + break; + } + } + if (cnt == 12) + /* Does not match a month name. */ + { + return NULL; + } + tm->tm_mon = cnt; + want_xday = 1; + break; + case 'c': + /* Match locale's date and time format. */ #ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } + if (*decided != raw) { + if (!recursive(_NL_CURRENT(LC_TIME, D_T_FMT))) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (*decided == not && + strcmp(_NL_CURRENT(LC_TIME, D_T_FMT), HERE_D_T_FMT)) { + *decided = loc; + } + want_xday = 1; + break; + } + *decided = raw; + } #endif - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - /* Match century number. */ + if (!recursive(HERE_D_T_FMT)) { + return NULL; + } + want_xday = 1; + break; + case 'C': + /* Match century number. */ #ifdef _NL_CURRENT - match_century: +match_century: #endif - get_number (0, 99, 2); - century = val; - want_xday = 1; - break; - case 'd': - case 'e': - /* Match day of month. */ - get_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'F': - if (!recursive ("%Y-%m-%d")) - return NULL; - want_xday = 1; - break; - case 'x': + get_number(0, 99, 2); + century = val; + want_xday = 1; + break; + case 'd': + case 'e': + /* Match day of month. */ + get_number(1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'F': + if (!recursive("%Y-%m-%d")) { + return NULL; + } + want_xday = 1; + break; + case 'x': #ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } + if (*decided != raw) { + if (!recursive(_NL_CURRENT(LC_TIME, D_FMT))) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (*decided == not + && strcmp(_NL_CURRENT(LC_TIME, D_FMT), HERE_D_FMT)) { + *decided = loc; + } + want_xday = 1; + break; + } + *decided = raw; + } #endif - /* Fall through. */ - case 'D': - /* Match standard day format. */ - if (!recursive (HERE_D_FMT)) - return NULL; - want_xday = 1; - break; - case 'k': - case 'H': - /* Match hour in 24-hour clock. */ - get_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock. */ - get_number (1, 12, 2); - tm->tm_hour = val % 12; - have_I = 1; - break; - case 'j': - /* Match day number of year. */ - get_number (1, 366, 3); - tm->tm_yday = val - 1; - have_yday = 1; - break; - case 'm': - /* Match number of month. */ - get_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minute. */ - get_number (0, 59, 2); - tm->tm_min = val; - break; - case 'n': - case 't': - /* Match any white space. */ - while (isspace (*rp)) - ++rp; - break; - case 'p': - /* Match locale's equivalent of AM/PM. */ + /* Fall through. */ + case 'D': + /* Match standard day format. */ + if (!recursive(HERE_D_FMT)) { + return NULL; + } + want_xday = 1; + break; + case 'k': + case 'H': + /* Match hour in 24-hour clock. */ + get_number(0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock. */ + get_number(1, 12, 2); + tm->tm_hour = val % 12; + have_I = 1; + break; + case 'j': + /* Match day number of year. */ + get_number(1, 366, 3); + tm->tm_yday = val - 1; + have_yday = 1; + break; + case 'm': + /* Match number of month. */ + get_number(1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minute. */ + get_number(0, 59, 2); + tm->tm_min = val; + break; + case 'n': + case 't': + /* Match any white space. */ + while (isspace(*rp)) { + ++rp; + } + break; + case 'p': + /* Match locale's equivalent of AM/PM. */ #ifdef _NL_CURRENT - if (*decided != raw) - { - if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) - *decided = loc; - is_pm = 1; - break; - } - *decided = raw; - } + if (*decided != raw) { + if (match_string(_NL_CURRENT(LC_TIME, AM_STR), rp)) { + if (strcmp(_NL_CURRENT(LC_TIME, AM_STR), HERE_AM_STR)) { + *decided = loc; + } + break; + } + if (match_string(_NL_CURRENT(LC_TIME, PM_STR), rp)) { + if (strcmp(_NL_CURRENT(LC_TIME, PM_STR), HERE_PM_STR)) { + *decided = loc; + } + is_pm = 1; + break; + } + *decided = raw; + } #endif - if (!match_string (HERE_AM_STR, rp)) { - if (match_string (HERE_PM_STR, rp)) { - is_pm = 1; - } else { - return NULL; - } - } - break; - case 'r': + if (!match_string(HERE_AM_STR, rp)) { + if (match_string(HERE_PM_STR, rp)) { + is_pm = 1; + } else { + return NULL; + } + } + break; + case 'r': #ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), - HERE_T_FMT_AMPM)) - *decided = loc; - break; - } - *decided = raw; - } + if (*decided != raw) { + if (!recursive(_NL_CURRENT(LC_TIME, T_FMT_AMPM))) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (*decided == not && + strcmp(_NL_CURRENT(LC_TIME, T_FMT_AMPM), + HERE_T_FMT_AMPM)) { + *decided = loc; + } + break; + } + *decided = raw; + } #endif - if (!recursive (HERE_T_FMT_AMPM)) - return NULL; - break; - case 'R': - if (!recursive ("%H:%M")) - return NULL; - break; - case 's': - { - /* The number of seconds may be very high so we cannot use - the `get_number' macro. Instead read the number - character for character and construct the result while - doing this. */ - time_t secs = 0; - if (*rp < '0' || *rp > '9') - /* We need at least one digit. */ - return NULL; - - do - { - secs *= 10; - secs += *rp++ - '0'; - } - while (*rp >= '0' && *rp <= '9'); - - if (localtime_r (&secs, tm) == NULL) - /* Error in function. */ - return NULL; - } - break; - case 'S': - get_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'X': + if (!recursive(HERE_T_FMT_AMPM)) { + return NULL; + } + break; + case 'R': + if (!recursive("%H:%M")) { + return NULL; + } + break; + case 's': { + /* The number of seconds may be very high so we cannot use + the `get_number' macro. Instead read the number + character for character and construct the result while + doing this. */ + time_t secs = 0; + if (*rp < '0' || *rp > '9') + /* We need at least one digit. */ + { + return NULL; + } + + do { + secs *= 10; + secs += *rp++ - '0'; + } while (*rp >= '0' && *rp <= '9'); + + if (localtime_r(&secs, tm) == NULL) + /* Error in function. */ + { + return NULL; + } + } + break; + case 'S': + get_number(0, 61, 2); + tm->tm_sec = val; + break; + case 'X': #ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } + if (*decided != raw) { + if (!recursive(_NL_CURRENT(LC_TIME, T_FMT))) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (strcmp(_NL_CURRENT(LC_TIME, T_FMT), HERE_T_FMT)) { + *decided = loc; + } + break; + } + *decided = raw; + } #endif - /* Fall through. */ - case 'T': - if (!recursive (HERE_T_FMT)) - return NULL; - break; - case 'u': - get_number (1, 7, 1); - tm->tm_wday = val % 7; - have_wday = 1; - break; - case 'g': - get_number (0, 99, 2); - /* XXX This cannot determine any field in TM. */ - break; - case 'G': - if (*rp < '0' || *rp > '9') - return NULL; - /* XXX Ignore the number since we would need some more - information to compute a real date. */ - do - ++rp; - while (*rp >= '0' && *rp <= '9'); - break; - case 'U': - case 'V': - case 'W': - get_number (0, 53, 2); - /* XXX This cannot determine any field in TM without some - information. */ - break; - case 'w': - /* Match number of weekday. */ - get_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': + /* Fall through. */ + case 'T': + if (!recursive(HERE_T_FMT)) { + return NULL; + } + break; + case 'u': + get_number(1, 7, 1); + tm->tm_wday = val % 7; + have_wday = 1; + break; + case 'g': + get_number(0, 99, 2); + /* XXX This cannot determine any field in TM. */ + break; + case 'G': + if (*rp < '0' || *rp > '9') { + return NULL; + } + /* XXX Ignore the number since we would need some more + information to compute a real date. */ + do { + ++rp; + } while (*rp >= '0' && *rp <= '9'); + break; + case 'U': + case 'V': + case 'W': + get_number(0, 53, 2); + /* XXX This cannot determine any field in TM without some + information. */ + break; + case 'w': + /* Match number of weekday. */ + get_number(0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': #ifdef _NL_CURRENT - match_year_in_century: +match_year_in_century: #endif - /* Match year within century. */ - get_number (0, 99, 2); - /* The "Year 2000: The Millennium Rollover" paper suggests that - values in the range 69-99 refer to the twentieth century. */ - tm->tm_year = val >= 69 ? val : val + 100; - /* Indicate that we want to use the century, if specified. */ - want_century = 1; - want_xday = 1; - break; - case 'Y': - /* Match year including century number. */ - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'Z': - /* XXX How to handle this? */ - break; - case 'E': + /* Match year within century. */ + get_number(0, 99, 2); + /* The "Year 2000: The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; + /* Indicate that we want to use the century, if specified. */ + want_century = 1; + want_xday = 1; + break; + case 'Y': + /* Match year including century number. */ + get_number(0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'Z': + /* XXX How to handle this? */ + break; + case 'E': #ifdef _NL_CURRENT - switch (*fmt++) - { - case 'c': - /* Match locale's alternate date and time format. */ - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - if (*decided != raw) - { - if (era_cnt >= 0) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - else - return NULL; - } - else - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - } - else - break; - } - - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - goto match_century; - case 'y': - if (*decided == raw) - goto match_year_in_century; - - get_number(0, 9999, 4); - tm->tm_year = val; - want_era = 1; - want_xday = 1; - break; - case 'Y': - if (*decided != raw) - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (recursive (era->era_format)) - break; - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - *decided = loc; - era_cnt = -1; - break; - } - - *decided = raw; - } - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'x': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_D_FMT)) - return NULL; - break; - case 'X': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_T_FMT)) - return NULL; - break; - default: - return NULL; - } - break; + switch (*fmt++) { + case 'c': + /* Match locale's alternate date and time format. */ + if (*decided != raw) { + const char *fmt = _NL_CURRENT(LC_TIME, ERA_D_T_FMT); + + if (*fmt == '\0') { + fmt = _NL_CURRENT(LC_TIME, D_T_FMT); + } + + if (!recursive(fmt)) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (strcmp(fmt, HERE_D_T_FMT)) { + *decided = loc; + } + want_xday = 1; + break; + } + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + if (!recursive(HERE_D_T_FMT)) { + return NULL; + } + want_xday = 1; + break; + case 'C': + if (*decided != raw) { + if (era_cnt >= 0) { + era = _nl_select_era_entry(era_cnt); + if (match_string(era->era_name, rp)) { + *decided = loc; + break; + } else { + return NULL; + } + } else { + num_eras = _NL_CURRENT_WORD(LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) { + era = _nl_select_era_entry(era_cnt); + if (match_string(era->era_name, rp)) { + *decided = loc; + break; + } + } + if (era_cnt == (int) num_eras) { + era_cnt = -1; + if (*decided == loc) { + return NULL; + } + } else { + break; + } + } + + *decided = raw; + } + /* The C locale has no era information, so use the + normal representation. */ + goto match_century; + case 'y': + if (*decided == raw) { + goto match_year_in_century; + } + + get_number(0, 9999, 4); + tm->tm_year = val; + want_era = 1; + want_xday = 1; + break; + case 'Y': + if (*decided != raw) { + num_eras = _NL_CURRENT_WORD(LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + for (era_cnt = 0; era_cnt < (int) num_eras; + ++era_cnt, rp = rp_backup) { + era = _nl_select_era_entry(era_cnt); + if (recursive(era->era_format)) { + break; + } + } + if (era_cnt == (int) num_eras) { + era_cnt = -1; + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + *decided = loc; + era_cnt = -1; + break; + } + + *decided = raw; + } + get_number(0, 9999, 4); + tm->tm_year = val - 1900; + want_century = 0; + want_xday = 1; + break; + case 'x': + if (*decided != raw) { + const char *fmt = _NL_CURRENT(LC_TIME, ERA_D_FMT); + + if (*fmt == '\0') { + fmt = _NL_CURRENT(LC_TIME, D_FMT); + } + + if (!recursive(fmt)) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (strcmp(fmt, HERE_D_FMT)) { + *decided = loc; + } + break; + } + *decided = raw; + } + if (!recursive(HERE_D_FMT)) { + return NULL; + } + break; + case 'X': + if (*decided != raw) { + const char *fmt = _NL_CURRENT(LC_TIME, ERA_T_FMT); + + if (*fmt == '\0') { + fmt = _NL_CURRENT(LC_TIME, T_FMT); + } + + if (!recursive(fmt)) { + if (*decided == loc) { + return NULL; + } else { + rp = rp_backup; + } + } else { + if (strcmp(fmt, HERE_T_FMT)) { + *decided = loc; + } + break; + } + *decided = raw; + } + if (!recursive(HERE_T_FMT)) { + return NULL; + } + break; + default: + return NULL; + } + break; #else - /* We have no information about the era format. Just use - the normal format. */ - if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' - && *fmt != 'x' && *fmt != 'X') - /* This is an illegal format. */ - return NULL; - - goto start_over; + /* We have no information about the era format. Just use + the normal format. */ + if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' + && *fmt != 'x' && *fmt != 'X') + /* This is an illegal format. */ + { + return NULL; + } + + goto start_over; #endif - case 'O': - switch (*fmt++) - { - case 'd': - case 'e': - /* Match day of month using alternate numeric symbols. */ - get_alt_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'H': - /* Match hour in 24-hour clock using alternate numeric - symbols. */ - get_alt_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock using alternate numeric - symbols. */ - get_alt_number (1, 12, 2); - tm->tm_hour = val - 1; - have_I = 1; - break; - case 'm': - /* Match month using alternate numeric symbols. */ - get_alt_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minutes using alternate numeric symbols. */ - get_alt_number (0, 59, 2); - tm->tm_min = val; - break; - case 'S': - /* Match seconds using alternate numeric symbols. */ - get_alt_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'U': - case 'V': - case 'W': - get_alt_number (0, 53, 2); - /* XXX This cannot determine any field in TM without - further information. */ - break; - case 'w': - /* Match number of weekday using alternate numeric symbols. */ - get_alt_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': - /* Match year within century using alternate numeric symbols. */ - get_alt_number (0, 99, 2); - tm->tm_year = val >= 69 ? val : val + 100; - want_xday = 1; - break; - default: - return NULL; - } - break; - default: - return NULL; - } + case 'O': + switch (*fmt++) { + case 'd': + case 'e': + /* Match day of month using alternate numeric symbols. */ + get_alt_number(1, 31, 2); + tm->tm_mday = val; + have_mday = 1; + want_xday = 1; + break; + case 'H': + /* Match hour in 24-hour clock using alternate numeric + symbols. */ + get_alt_number(0, 23, 2); + tm->tm_hour = val; + have_I = 0; + break; + case 'I': + /* Match hour in 12-hour clock using alternate numeric + symbols. */ + get_alt_number(1, 12, 2); + tm->tm_hour = val - 1; + have_I = 1; + break; + case 'm': + /* Match month using alternate numeric symbols. */ + get_alt_number(1, 12, 2); + tm->tm_mon = val - 1; + have_mon = 1; + want_xday = 1; + break; + case 'M': + /* Match minutes using alternate numeric symbols. */ + get_alt_number(0, 59, 2); + tm->tm_min = val; + break; + case 'S': + /* Match seconds using alternate numeric symbols. */ + get_alt_number(0, 61, 2); + tm->tm_sec = val; + break; + case 'U': + case 'V': + case 'W': + get_alt_number(0, 53, 2); + /* XXX This cannot determine any field in TM without + further information. */ + break; + case 'w': + /* Match number of weekday using alternate numeric symbols. */ + get_alt_number(0, 6, 1); + tm->tm_wday = val; + have_wday = 1; + break; + case 'y': + /* Match year within century using alternate numeric symbols. */ + get_alt_number(0, 99, 2); + tm->tm_year = val >= 69 ? val : val + 100; + want_xday = 1; + break; + default: + return NULL; + } + break; + default: + return NULL; } + } - if (have_I && is_pm) + if (have_I && is_pm) { tm->tm_hour += 12; + } - if (century != -1) + if (century != -1) { + if (want_century) { + tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; + } else + /* Only the century, but not the year. Strange, but so be it. */ { - if (want_century) - tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; - else - /* Only the century, but not the year. Strange, but so be it. */ - tm->tm_year = (century - 19) * 100; + tm->tm_year = (century - 19) * 100; } + } #ifdef _NL_CURRENT - if (era_cnt != -1) + if (era_cnt != -1) { + era = _nl_select_era_entry(era_cnt); + if (want_era) + tm->tm_year = (era->start_date[0] + + ((tm->tm_year - era->offset) + * era->absolute_direction)); + else + /* Era start year assumed. */ { - era = _nl_select_era_entry(era_cnt); - if (want_era) - tm->tm_year = (era->start_date[0] - + ((tm->tm_year - era->offset) - * era->absolute_direction)); - else - /* Era start year assumed. */ - tm->tm_year = era->start_date[0]; + tm->tm_year = era->start_date[0]; } - else + } else #endif - if (want_era) + if (want_era) { return NULL; + } - if (want_xday && !have_wday) - { - if ( !(have_mon && have_mday) && have_yday) - { - /* We don't have tm_mon and/or tm_mday, compute them. */ - int t_mon = 0; - while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) - t_mon++; - if (!have_mon) - tm->tm_mon = t_mon - 1; - if (!have_mday) - tm->tm_mday = - (tm->tm_yday - - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); - } - day_of_the_week (tm); + if (want_xday && !have_wday) { + if (!(have_mon && have_mday) && have_yday) { + /* We don't have tm_mon and/or tm_mday, compute them. */ + int t_mon = 0; + while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) { + t_mon++; + } + if (!have_mon) { + tm->tm_mon = t_mon - 1; + } + if (!have_mday) + tm->tm_mday = + (tm->tm_yday + - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); } - if (want_xday && !have_yday) - day_of_the_year (tm); + day_of_the_week(tm); + } + if (want_xday && !have_yday) { + day_of_the_year(tm); + } return (char *) rp; } char * -strptime (buf, format, tm) - const char *buf; - const char *format; - struct tm *tm; +strptime(buf, format, tm) +const char *buf; +const char *format; +struct tm *tm; { enum locale_status decided; @@ -1017,6 +1003,6 @@ strptime (buf, format, tm) #else decided = raw; #endif - return strptime_internal (buf, format, tm, &decided, -1); + return strptime_internal(buf, format, tm, &decided, -1); } diff --git a/gpsbabel/strptime.h b/gpsbabel/strptime.h index 97e4f59f6..3270703cc 100644 --- a/gpsbabel/strptime.h +++ b/gpsbabel/strptime.h @@ -10,12 +10,12 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. diff --git a/gpsbabel/subrip.c b/gpsbabel/subrip.c index 0958ccba3..40f2c83ff 100644 --- a/gpsbabel/subrip.c +++ b/gpsbabel/subrip.c @@ -1,6 +1,6 @@ /* Write points to SubRip subtitle file (for video geotagging) - + Copyright (C) 2010 Michael von Glasow, michael @t vonglasow d.t com This program is free software; you can redistribute it and/or modify @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include @@ -37,104 +37,95 @@ static const waypoint * prevwpp; static time_t sync_time(time_t arg_gpstime, char * arg_videotime) { - static time_t videotime_t; - static struct tm * ptm_video; - static time_t result; - - videotime_t = 0; - ptm_video = gmtime(&videotime_t); - if (arg_videotime) - { - sscanf(arg_videotime, "%2d%2d%2d", &ptm_video->tm_hour, &ptm_video->tm_min, &ptm_video->tm_sec); - } - videotime_t = mkgmtime(ptm_video); - result = (arg_gpstime - videotime_t); - return result; + static time_t videotime_t; + static struct tm * ptm_video; + static time_t result; + + videotime_t = 0; + ptm_video = gmtime(&videotime_t); + if (arg_videotime) { + sscanf(arg_videotime, "%2d%2d%2d", &ptm_video->tm_hour, &ptm_video->tm_min, &ptm_video->tm_sec); + } + videotime_t = mkgmtime(ptm_video); + result = (arg_gpstime - videotime_t); + return result; } static time_t gps_to_video_time(time_t arg_gpstime) { - static time_t result; - /* Converts a GPS timestamp to relative time in the video stream. */ - result = arg_gpstime - time_offset; - return result; + static time_t result; + /* Converts a GPS timestamp to relative time in the video stream. */ + result = arg_gpstime - time_offset; + return result; } static void subrip_write_duration(time_t starttime, time_t endtime) { - /* Writes start and end time for subtitle display to file. */ - struct tm * tmptime; - - tmptime = gmtime(&starttime); - gbfprintf(fout, "%02d:%02d:%02d,000 --> ", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); - - tmptime = gmtime(&endtime); - gbfprintf(fout, "%02d:%02d:%02d,000\n", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); + /* Writes start and end time for subtitle display to file. */ + struct tm * tmptime; + + tmptime = gmtime(&starttime); + gbfprintf(fout, "%02d:%02d:%02d,000 --> ", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); + + tmptime = gmtime(&endtime); + gbfprintf(fout, "%02d:%02d:%02d,000\n", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); } static void subrip_write_time(time_t arg_time) { - /* Writes a timestamp to file. */ - struct tm * tmptime; - - tmptime = gmtime(&arg_time); - gbfprintf(fout, "%02d:%02d:%02d", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); + /* Writes a timestamp to file. */ + struct tm * tmptime; + + tmptime = gmtime(&arg_time); + gbfprintf(fout, "%02d:%02d:%02d", tmptime->tm_hour, tmptime->tm_min, tmptime->tm_sec); } static void subrip_prevwp_pr(const waypoint *waypointp) { - /* Now that we have the next waypoint, we can write out the subtitle for - * the previous one. - */ - time_t starttime; - time_t endtime; - - if (prevwpp->creation_time >= time_offset) - /* if this condition is not true, the waypoint is before the beginning of - * the video and will be ignored - */ - { - - starttime = gps_to_video_time(prevwpp->creation_time); - if (!waypointp) - { - endtime = starttime + 1; - } - else - { - endtime = gps_to_video_time(waypointp->creation_time); - } - gbfprintf(fout, "%d\n", stnum); - stnum++; - subrip_write_duration(starttime, endtime); - if WAYPT_HAS(prevwpp, speed) - { - gbfprintf(fout, "%d km/h", - (int) (MPS_TO_KPH(prevwpp->speed) + 0.5)); - } - if (prevwpp->altitude != unknown_alt) - { - if WAYPT_HAS(prevwpp, speed) - { - gbfprintf(fout, ", "); - } - gbfprintf(fout, "%d m\n", - (int) (prevwpp->altitude + 0.5)); - } - else if WAYPT_HAS(prevwpp, speed) - { - gbfprintf(fout, "\n"); - } - subrip_write_time(prevwpp->creation_time); - gbfprintf(fout, " Lat=%0.5lf Lon=%0.5lf\n", - prevwpp->latitude + .000005, - prevwpp->longitude + .000005); - gbfprintf(fout, "\n"); - } + /* Now that we have the next waypoint, we can write out the subtitle for + * the previous one. + */ + time_t starttime; + time_t endtime; + + if (prevwpp->creation_time >= time_offset) + /* if this condition is not true, the waypoint is before the beginning of + * the video and will be ignored + */ + { + + starttime = gps_to_video_time(prevwpp->creation_time); + if (!waypointp) { + endtime = starttime + 1; + } else { + endtime = gps_to_video_time(waypointp->creation_time); + } + gbfprintf(fout, "%d\n", stnum); + stnum++; + subrip_write_duration(starttime, endtime); + if WAYPT_HAS(prevwpp, speed) { + gbfprintf(fout, "%d km/h", + (int)(MPS_TO_KPH(prevwpp->speed) + 0.5)); + } + if (prevwpp->altitude != unknown_alt) { + if WAYPT_HAS(prevwpp, speed) { + gbfprintf(fout, ", "); + } + gbfprintf(fout, "%d m\n", + (int)(prevwpp->altitude + 0.5)); + } else if WAYPT_HAS(prevwpp, speed) { + gbfprintf(fout, "\n"); + } + subrip_write_time(prevwpp->creation_time); + gbfprintf(fout, " Lat=%0.5lf Lon=%0.5lf\n", + prevwpp->latitude + .000005, + prevwpp->longitude + .000005); + gbfprintf(fout, "\n"); + } } /* callback functions */ @@ -142,29 +133,28 @@ subrip_prevwp_pr(const waypoint *waypointp) static void subrip_trkpt_pr(const waypoint *waypointp) { - /* - * To determine the duration of the subtitle, we need the timestamp of the - * associated waypoint plus that of the following one. - * Since we get waypoints one at a time, the only way is to store one and - * defer processing until we get the next one. - */ - if ((stnum == 1) && (time_offset == 0)) - /* - * esoteric bug: GPS tracks created on Jan 1, 1970 at midnight would cause - * undesirable behavior here. But if you run into this problem, I assume - * you are capable of time-travel as well as inventing a high-tech system - * some 20 years before the rest of mankind does, so finding a prettier - * way of solving this should be trivial to you :-) - */ - { - time_offset = sync_time(waypointp->creation_time, opt_videotime); - } - - if (prevwpp) - { - subrip_prevwp_pr(waypointp); - } - prevwpp = waypointp; + /* + * To determine the duration of the subtitle, we need the timestamp of the + * associated waypoint plus that of the following one. + * Since we get waypoints one at a time, the only way is to store one and + * defer processing until we get the next one. + */ + if ((stnum == 1) && (time_offset == 0)) + /* + * esoteric bug: GPS tracks created on Jan 1, 1970 at midnight would cause + * undesirable behavior here. But if you run into this problem, I assume + * you are capable of time-travel as well as inventing a high-tech system + * some 20 years before the rest of mankind does, so finding a prettier + * way of solving this should be trivial to you :-) + */ + { + time_offset = sync_time(waypointp->creation_time, opt_videotime); + } + + if (prevwpp) { + subrip_prevwp_pr(waypointp); + } + prevwpp = waypointp; } /* global callback (exported) functions */ @@ -172,93 +162,89 @@ subrip_trkpt_pr(const waypoint *waypointp) static void subrip_wr_init(const char *fname) { - time_t gpstime_t; - struct tm * ptm_gps; - - stnum = 1; - - time_offset = 0; - - prevwpp = NULL; - - if ((opt_gpstime != NULL) && (opt_gpsdate != NULL)) - { - time (&gpstime_t); - ptm_gps = gmtime(&gpstime_t); - if (opt_gpstime) - { - sscanf(opt_gpstime, "%2d%2d%2d", &ptm_gps->tm_hour, &ptm_gps->tm_min, &ptm_gps->tm_sec); - } - if (opt_gpsdate) - { - sscanf(opt_gpsdate, "%4d%2d%2d", &ptm_gps->tm_year, &ptm_gps->tm_mon, &ptm_gps->tm_mday); - /* - * Don't ask me why we need to do this nonsense, but it seems to be necessary: - * Years are two-digit since this was fashionable in the mid-1900s. - * For dates after 2000, just add 100 to the year. - * Months are zero-based (0 is January), but days are one-based. - * Makes sense, eh? - * Btw: correct dates will result in incorrect timestamps and you'll - * never figure out why. Suppose that's to confuse the Russians, - * given that the system was developed during the Cold War. But that - * is true for most of Unix. - * Make a difference - contribute to ReactOS. - */ - ptm_gps->tm_year-=1900; - ptm_gps->tm_mon--; - } - gpstime_t = mkgmtime(ptm_gps); - time_offset = sync_time(gpstime_t, opt_videotime); - - } - - fout = gbfopen(fname, "wb", MYNAME); + time_t gpstime_t; + struct tm * ptm_gps; + + stnum = 1; + + time_offset = 0; + + prevwpp = NULL; + + if ((opt_gpstime != NULL) && (opt_gpsdate != NULL)) { + time(&gpstime_t); + ptm_gps = gmtime(&gpstime_t); + if (opt_gpstime) { + sscanf(opt_gpstime, "%2d%2d%2d", &ptm_gps->tm_hour, &ptm_gps->tm_min, &ptm_gps->tm_sec); + } + if (opt_gpsdate) { + sscanf(opt_gpsdate, "%4d%2d%2d", &ptm_gps->tm_year, &ptm_gps->tm_mon, &ptm_gps->tm_mday); + /* + * Don't ask me why we need to do this nonsense, but it seems to be necessary: + * Years are two-digit since this was fashionable in the mid-1900s. + * For dates after 2000, just add 100 to the year. + * Months are zero-based (0 is January), but days are one-based. + * Makes sense, eh? + * Btw: correct dates will result in incorrect timestamps and you'll + * never figure out why. Suppose that's to confuse the Russians, + * given that the system was developed during the Cold War. But that + * is true for most of Unix. + * Make a difference - contribute to ReactOS. + */ + ptm_gps->tm_year-=1900; + ptm_gps->tm_mon--; + } + gpstime_t = mkgmtime(ptm_gps); + time_offset = sync_time(gpstime_t, opt_videotime); + + } + + fout = gbfopen(fname, "wb", MYNAME); } static void subrip_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void subrip_write(void) { - track_disp_all(NULL, NULL, subrip_trkpt_pr); - - /* - * Due to the necessary hack, one waypoint is still in memory (unless we - * did not get any waypoints). Check if there is one and, if so, write it. - */ - if (prevwpp) - { - subrip_prevwp_pr(NULL); - } + track_disp_all(NULL, NULL, subrip_trkpt_pr); + + /* + * Due to the necessary hack, one waypoint is still in memory (unless we + * did not get any waypoints). Check if there is one and, if so, write it. + */ + if (prevwpp) { + subrip_prevwp_pr(NULL); + } } /* arguments: definitions of format-specific arguments */ arglist_t subrip_args[] = { - // FIXME: document that gps_date and gps_time must be specified together or they will both be ignored and the timestamp of the first trackpoint will be used. - {"video_time", &opt_videotime, "Video position for which exact GPS time is known (hhmmss, default is 0:00:00)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, - {"gps_time", &opt_gpstime, "GPS time at position video_time (hhmmss, default is first timestamp of track)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, - {"gps_date", &opt_gpsdate, "GPS date at position video_time (hhmmss, default is first timestamp of track)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + // FIXME: document that gps_date and gps_time must be specified together or they will both be ignored and the timestamp of the first trackpoint will be used. + {"video_time", &opt_videotime, "Video position for which exact GPS time is known (hhmmss, default is 0:00:00)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, + {"gps_time", &opt_gpstime, "GPS time at position video_time (hhmmss, default is first timestamp of track)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, + {"gps_date", &opt_gpsdate, "GPS date at position video_time (hhmmss, default is first timestamp of track)", 0, ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; /* manifest: capabilities of this module, pointers to exported functions and others */ ff_vecs_t subrip_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_write, ff_cap_none }, // waypoints, track, route; for now, we just do tracks - NULL, - subrip_wr_init, - NULL, - subrip_wr_deinit, - NULL, - subrip_write, - NULL, - subrip_args, - CET_CHARSET_ASCII, 0 + ff_type_file, + { ff_cap_none, ff_cap_write, ff_cap_none }, // waypoints, track, route; for now, we just do tracks + NULL, + subrip_wr_init, + NULL, + subrip_wr_deinit, + NULL, + subrip_write, + NULL, + subrip_args, + CET_CHARSET_ASCII, 0 }; diff --git a/gpsbabel/swapdata.c b/gpsbabel/swapdata.c index ddbc55e8f..e5c0b8b8a 100644 --- a/gpsbabel/swapdata.c +++ b/gpsbabel/swapdata.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" #include @@ -30,42 +30,42 @@ static arglist_t swapdata_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static void swapdata_cb(const waypoint *ref) { - waypoint *wpt = (waypoint *)ref; - double x; + waypoint *wpt = (waypoint *)ref; + double x; - x = wpt->latitude; - wpt->latitude = wpt->longitude; - wpt->longitude = x; + x = wpt->latitude; + wpt->latitude = wpt->longitude; + wpt->longitude = x; - return; + return; } /******************************************************************************* * %%% global callbacks called by gpsbabel main process %%% * *******************************************************************************/ -static void +static void swapdata_process(void) /* this procedure must be present in vecs */ { - waypt_disp_all(swapdata_cb); - route_disp_all(NULL, NULL, swapdata_cb); - track_disp_all(NULL, NULL, swapdata_cb); + waypt_disp_all(swapdata_cb); + route_disp_all(NULL, NULL, swapdata_cb); + track_disp_all(NULL, NULL, swapdata_cb); } /*******************************************************************************/ filter_vecs_t swapdata_vecs = { - NULL, - swapdata_process, - NULL, - NULL, - swapdata_args + NULL, + swapdata_process, + NULL, + NULL, + swapdata_args }; /*******************************************************************************/ diff --git a/gpsbabel/tef_xml.c b/gpsbabel/tef_xml.c index 8d2d82d20..528ace1e0 100644 --- a/gpsbabel/tef_xml.c +++ b/gpsbabel/tef_xml.c @@ -1,7 +1,7 @@ -/* - Support for XML based "TourExchangeFormat", +/* + Support for XML based "TourExchangeFormat", found in Map & Guide Motorrad-Tourenplaner 2005/06 - + Copyright (C) 2005 Olaf Klein, o.b.klein@gpsbabel.org Based on kml.c, Keyhole "kml" format. @@ -34,11 +34,12 @@ static route_head *route = NULL; static char *routevia = NULL; -static arglist_t tef_xml_args[] = -{ - {"routevia", &routevia, "Include only via stations in route", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR +static arglist_t tef_xml_args[] = { + { + "routevia", &routevia, "Include only via stations in route", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; #define MYNAME "TourExchangeFormat" @@ -47,7 +48,7 @@ static arglist_t tef_xml_args[] = void tef_xml_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded TEF support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded TEF support because expat was not installed.\n"); } void @@ -60,29 +61,32 @@ tef_xml_read(void) static char * trimmed_strdup(const char *str) { - char *c1, *c2, *res; - - c1 = xstrdup(str); - c2 = lrtrim(c1); - if (*c2) res = xstrdup(c2); - else res = NULL; - xfree(c1); - return res; + char *c1, *c2, *res; + + c1 = xstrdup(str); + c2 = lrtrim(c1); + if (*c2) { + res = xstrdup(c2); + } else { + res = NULL; + } + xfree(c1); + return res; } static xg_callback tef_start, tef_header, tef_list_start, tef_list_end; static xg_callback tef_item_start, tef_point, tef_item_end; -static +static xg_tag_mapping tef_xml_map[] = { - { tef_start, cb_start, "/TEF" }, - { tef_header, cb_start, "/TEF/Header" }, - { tef_list_start, cb_start, "/TEF/WaypointList" }, - { tef_item_start, cb_start, "/TEF/WaypointList/Item" }, - { tef_point, cb_start, "/TEF/WaypointList/Item/Point" }, - { tef_item_end, cb_end, "/TEF/WaypointList/Item" }, - { tef_list_end, cb_end, "/TEF/WaypointList" }, - { NULL, 0, NULL } + { tef_start, cb_start, "/TEF" }, + { tef_header, cb_start, "/TEF/Header" }, + { tef_list_start, cb_start, "/TEF/WaypointList" }, + { tef_item_start, cb_start, "/TEF/WaypointList/Item" }, + { tef_point, cb_start, "/TEF/WaypointList/Item/Point" }, + { tef_item_end, cb_end, "/TEF/WaypointList/Item" }, + { tef_list_end, cb_end, "/TEF/WaypointList" }, + { NULL, 0, NULL } }; @@ -90,55 +94,59 @@ xg_tag_mapping tef_xml_map[] = { * tef_start: check for comment "TourExchangeFormat" */ -void +void tef_start(const char *args, const char **attrv) { - int valid = 0; - const char **avp = &attrv[0]; - - while (*avp) { - if (0 == case_ignore_strcmp(avp[0], "Comment")) { - if (0 == case_ignore_strcmp(avp[1], "TourExchangeFormat")) - valid = 1; - } - else if (0 == case_ignore_strcmp(avp[0], "Version")) - version = atof(avp[1]); - avp+=2; - } - if (!valid) - fatal(MYNAME ": Error in source file.\n"); + int valid = 0; + const char **avp = &attrv[0]; + + while (*avp) { + if (0 == case_ignore_strcmp(avp[0], "Comment")) { + if (0 == case_ignore_strcmp(avp[1], "TourExchangeFormat")) { + valid = 1; + } + } else if (0 == case_ignore_strcmp(avp[0], "Version")) { + version = atof(avp[1]); + } + avp+=2; + } + if (!valid) { + fatal(MYNAME ": Error in source file.\n"); + } } /* * tef_header: "Name" > Route name, "Software" > Route descr. */ -static void +static void tef_header(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - route = route_head_alloc(); - while (*avp) { - if (case_ignore_strcmp(avp[0], "Name") == 0) - route->rte_name = trimmed_strdup(avp[1]); - else if (case_ignore_strcmp(avp[0], "Software") == 0) - route->rte_desc = trimmed_strdup(avp[1]); - avp+=2; - } - route_add_head(route); + const char **avp = &attrv[0]; + + route = route_head_alloc(); + while (*avp) { + if (case_ignore_strcmp(avp[0], "Name") == 0) { + route->rte_name = trimmed_strdup(avp[1]); + } else if (case_ignore_strcmp(avp[0], "Software") == 0) { + route->rte_desc = trimmed_strdup(avp[1]); + } + avp+=2; + } + route_add_head(route); } static void tef_list_start(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "ItemCount") == 0) - sscanf(avp[1], "%d", &item_count); - avp+=2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "ItemCount") == 0) { + sscanf(avp[1], "%d", &item_count); + } + avp+=2; + } } /* in "TourExchangeFormat" the following can happen: @@ -153,166 +161,185 @@ tef_list_start(const char *args, const char **attrv) static char * fix_notes(const char *name, char *notes) { - char *cleft, *cright, *cback, *ctmp; - - if ((! name) || (! notes)) return notes; - - /* do we have a BACKSLASH in shortname ? */ - cback = strchr(name, '\\'); - if ((! cback) || (cback == name)) return notes; - - /* do we have left, but no right parenthesis in notes ? */ - if (! (cleft = strchr(notes, '('))) return notes; - cright = strchr(notes, ')'); - if (cright && (cright > cleft)) return notes; - - /* now contruct the new name */ - ctmp = lrtrim(xstrndup(notes, cleft - notes)); - xfree(notes); - xasprintf(¬es, "%s (%*.*s)", ctmp, cback - name, cback - name, name); - xfree(ctmp); - - return notes; + char *cleft, *cright, *cback, *ctmp; + + if ((! name) || (! notes)) { + return notes; + } + + /* do we have a BACKSLASH in shortname ? */ + cback = strchr(name, '\\'); + if ((! cback) || (cback == name)) { + return notes; + } + + /* do we have left, but no right parenthesis in notes ? */ + if (!(cleft = strchr(notes, '('))) { + return notes; + } + cright = strchr(notes, ')'); + if (cright && (cright > cleft)) { + return notes; + } + + /* now contruct the new name */ + ctmp = lrtrim(xstrndup(notes, cleft - notes)); + xfree(notes); + xasprintf(¬es, "%s (%*.*s)", ctmp, cback - name, cback - name, name); + xfree(ctmp); + + return notes; } static void waypoint_final() { - int via; - if (wpt_tmp == NULL) return; + int via; + if (wpt_tmp == NULL) { + return; + } - via = wpt_tmp->microseconds; - wpt_tmp->microseconds = 0; + via = wpt_tmp->microseconds; + wpt_tmp->microseconds = 0; - if (version < 2) { /* keep the old behaviour */ - wpt_tmp->notes = wpt_tmp->description; - wpt_tmp->description = NULL; - } + if (version < 2) { /* keep the old behaviour */ + wpt_tmp->notes = wpt_tmp->description; + wpt_tmp->description = NULL; + } - wpt_tmp->notes = fix_notes(wpt_tmp->shortname, wpt_tmp->notes); + wpt_tmp->notes = fix_notes(wpt_tmp->shortname, wpt_tmp->notes); - if (via != 0) - waypt_add(wpt_tmp); + if (via != 0) { + waypt_add(wpt_tmp); + } - if (route != NULL) { - if ((via != 0) || (routevia == NULL)) { - waypoint *wpt = waypt_dupe(wpt_tmp); - route_add_wpt(route, wpt); - } - } + if (route != NULL) { + if ((via != 0) || (routevia == NULL)) { + waypoint *wpt = waypt_dupe(wpt_tmp); + route_add_wpt(route, wpt); + } + } - if (via == 0) - waypt_free(wpt_tmp); + if (via == 0) { + waypt_free(wpt_tmp); + } - wpt_tmp = NULL; + wpt_tmp = NULL; } -static void +static void tef_item_end(const char *args, const char **unused) { - waypoint_final(); + waypoint_final(); } -static void +static void tef_list_end(const char *args, const char **unused) { - waypoint_final(); - if (waypoints != item_count) - fatal(MYNAME ": waypoint count differs to internal \"ItemCount\"! (%d to %d)\n", - waypoints, item_count); + waypoint_final(); + if (waypoints != item_count) + fatal(MYNAME ": waypoint count differs to internal \"ItemCount\"! (%d to %d)\n", + waypoints, item_count); } -static void +static void tef_item_start(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - waypoints++; - - wpt_tmp = waypt_new(); - if ((waypoints == 1) || (waypoints == item_count)) - wpt_tmp->microseconds++; - - while (*avp) - { - if (0 == case_ignore_strcmp(avp[0], "SegDescription")) - wpt_tmp->shortname = trimmed_strdup(avp[1]); - else if (0 == case_ignore_strcmp(avp[0], "PointDescription")) - wpt_tmp->description = trimmed_strdup(avp[1]); - else if ((0 == case_ignore_strcmp(avp[0], "ViaStation")) && - (0 == case_ignore_strcmp(avp[1], "true"))) - wpt_tmp->microseconds = 1; /* only a flag */ - - /* new in TEF V2 */ - else if (0 == case_ignore_strcmp(avp[0], "Instruction")) - wpt_tmp->description = trimmed_strdup(avp[1]); - else if (0 == case_ignore_strcmp(avp[0], "Altitude")) - wpt_tmp->altitude = atof(avp[1]); - else if (0 == case_ignore_strcmp(avp[0], "TimeStamp")) - { /* nothing for the moment */ } - - avp+=2; - } + const char **avp = &attrv[0]; + + waypoints++; + + wpt_tmp = waypt_new(); + if ((waypoints == 1) || (waypoints == item_count)) { + wpt_tmp->microseconds++; + } + + while (*avp) { + if (0 == case_ignore_strcmp(avp[0], "SegDescription")) { + wpt_tmp->shortname = trimmed_strdup(avp[1]); + } else if (0 == case_ignore_strcmp(avp[0], "PointDescription")) { + wpt_tmp->description = trimmed_strdup(avp[1]); + } else if ((0 == case_ignore_strcmp(avp[0], "ViaStation")) && + (0 == case_ignore_strcmp(avp[1], "true"))) { + wpt_tmp->microseconds = 1; /* only a flag */ + } + + /* new in TEF V2 */ + else if (0 == case_ignore_strcmp(avp[0], "Instruction")) { + wpt_tmp->description = trimmed_strdup(avp[1]); + } else if (0 == case_ignore_strcmp(avp[0], "Altitude")) { + wpt_tmp->altitude = atof(avp[1]); + } else if (0 == case_ignore_strcmp(avp[0], "TimeStamp")) { + /* nothing for the moment */ + } + + avp+=2; + } } -static void +static void tef_point(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - char *comma; - - if (!wpt_tmp) return; - - while (*avp) { - if (strcmp(avp[0], "y") == 0) { - comma = strstr(avp[1], ","); - if (comma) *comma='.'; - sscanf(avp[1], "%lf", &wpt_tmp->latitude); - } - else if (strcmp(avp[0], "x") == 0) { - comma = strstr(avp[1], ","); - if (comma) *comma='.'; - sscanf(avp[1], "%lf", &wpt_tmp->longitude); - } - avp+=2; - } + const char **avp = &attrv[0]; + char *comma; + + if (!wpt_tmp) { + return; + } + + while (*avp) { + if (strcmp(avp[0], "y") == 0) { + comma = strstr(avp[1], ","); + if (comma) { + *comma='.'; + } + sscanf(avp[1], "%lf", &wpt_tmp->latitude); + } else if (strcmp(avp[0], "x") == 0) { + comma = strstr(avp[1], ","); + if (comma) { + *comma='.'; + } + sscanf(avp[1], "%lf", &wpt_tmp->longitude); + } + avp+=2; + } } -static void +static void tef_xml_rd_init(const char *fname) { - wpt_tmp = NULL; - waypoints = 0; - item_count = -1; - version = 1.5; + wpt_tmp = NULL; + waypoints = 0; + item_count = -1; + version = 1.5; - xml_init(fname, tef_xml_map, NULL); + xml_init(fname, tef_xml_map, NULL); } -static void +static void tef_xml_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void tef_xml_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } ff_vecs_t tef_xml_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_none, ff_cap_read }, - tef_xml_rd_init, - NULL, - tef_xml_rd_deinit, - NULL, - tef_xml_read, - NULL, - NULL, - tef_xml_args, - CET_CHARSET_UTF8, 1 + ff_type_file, + { ff_cap_none, ff_cap_none, ff_cap_read }, + tef_xml_rd_init, + NULL, + tef_xml_rd_deinit, + NULL, + tef_xml_read, + NULL, + NULL, + tef_xml_args, + CET_CHARSET_UTF8, 1 }; diff --git a/gpsbabel/teletype.c b/gpsbabel/teletype.c index 5897467f5..476f8fb5c 100644 --- a/gpsbabel/teletype.c +++ b/gpsbabel/teletype.c @@ -27,7 +27,7 @@ static arglist_t teletype_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; /******************************************************************************* @@ -40,54 +40,54 @@ static gbfile *fin; static void teletype_rd_init(const char *fname) { - char header[64]; + char header[64]; - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); - gbfread(header, sizeof(header), 1, fin); - tty_wpt_count = gbfgetint32(fin); + gbfread(header, sizeof(header), 1, fin); + tty_wpt_count = gbfgetint32(fin); } -static void +static void teletype_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void teletype_read(void) { - int i; - for (i = 0; i < tty_wpt_count; i++) { - waypoint *wpt = waypt_new(); - wpt->shortname = (gbfgetcstr(fin)); - wpt->description = (gbfgetcstr(fin)); - - if (1) { // needs bit values of NEWFORMAT2 - gbuint32 direction = gbfgetuint32(fin); - gbuint32 mins = gbfgetuint32(fin); - (void) direction ; - (void) mins ; - } - - if (1) { // need bit value of NEWFORMAT - int len = gbfgetuint16(fin); - // probably could treat as a pascal string - char *junk = xmalloc(len); - gbfread(junk, len, 1, fin); - xfree(junk); - } - wpt->latitude = gbfgetint32(fin) / 1000000.0 ; - wpt->longitude = gbfgetint32(fin) / 1000000.0 ; - - { - char jibberish[21]; - gbfread(jibberish, sizeof(jibberish), 1, fin); - } - - - waypt_add(wpt); - } + int i; + for (i = 0; i < tty_wpt_count; i++) { + waypoint *wpt = waypt_new(); + wpt->shortname = (gbfgetcstr(fin)); + wpt->description = (gbfgetcstr(fin)); + + if (1) { // needs bit values of NEWFORMAT2 + gbuint32 direction = gbfgetuint32(fin); + gbuint32 mins = gbfgetuint32(fin); + (void) direction ; + (void) mins ; + } + + if (1) { // need bit value of NEWFORMAT + int len = gbfgetuint16(fin); + // probably could treat as a pascal string + char *junk = xmalloc(len); + gbfread(junk, len, 1, fin); + xfree(junk); + } + wpt->latitude = gbfgetint32(fin) / 1000000.0 ; + wpt->longitude = gbfgetint32(fin) / 1000000.0 ; + + { + char jibberish[21]; + gbfread(jibberish, sizeof(jibberish), 1, fin); + } + + + waypt_add(wpt); + } } static void @@ -119,24 +119,24 @@ teletype_exit(void) /* optional */ /**************************************************************************/ // capabilities below means: we can only read and write waypoints -// please change this depending on your new module +// please change this depending on your new module ff_vecs_t teletype_vecs = { - ff_type_file, - { - ff_cap_read | ff_cap_write /* waypoints */, - ff_cap_none /* tracks */, - ff_cap_none /* routes */ - }, - teletype_rd_init, - teletype_wr_init, - teletype_rd_deinit, - teletype_wr_deinit, - teletype_read, - teletype_write, - teletype_exit, - teletype_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_read | ff_cap_write /* waypoints */, + ff_cap_none /* tracks */, + ff_cap_none /* routes */ + }, + teletype_rd_init, + teletype_wr_init, + teletype_rd_deinit, + teletype_wr_deinit, + teletype_read, + teletype_write, + teletype_exit, + teletype_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/text.c b/gpsbabel/text.c index 31bb486bc..bad61f755 100644 --- a/gpsbabel/text.c +++ b/gpsbabel/text.c @@ -40,21 +40,33 @@ static char *output_name; static arglist_t text_args[] = { - { "nosep", &suppresssep, - "Suppress separator lines between waypoints", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "encrypt", &txt_encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "logs", &includelogs, - "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - { "degformat", °format, - "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX }, - { "altunits", &altunits, - "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX }, - { "splitoutput", &split_output, - "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - - ARG_TERMINATOR + { + "nosep", &suppresssep, + "Suppress separator lines between waypoints", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "encrypt", &txt_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "logs", &includelogs, + "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "degformat", °format, + "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "altunits", &altunits, + "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "splitoutput", &split_output, + "Write each waypoint in a separate file", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + + ARG_TERMINATOR }; @@ -62,217 +74,220 @@ arglist_t text_args[] = { static void wr_init(const char *fname) { - waypoint_count = 0; - output_name = xstrdup(fname); - if (!split_output) { - file_out = gbfopen(fname, "w", MYNAME); - } - mkshort_handle = mkshort_new_handle(); + waypoint_count = 0; + output_name = xstrdup(fname); + if (!split_output) { + file_out = gbfopen(fname, "w", MYNAME); + } + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - if (!split_output) { - gbfclose(file_out); - } - mkshort_del_handle(&mkshort_handle); - xfree(output_name); + if (!split_output) { + gbfclose(file_out); + } + mkshort_del_handle(&mkshort_handle); + xfree(output_name); } static void text_disp(const waypoint *wpt) { - int latint, lonint; - char tbuf[1024]; - time_t tm = wpt->creation_time; - gbint32 utmz; - double utme, utmn; - char utmzc; - char *tmpout1, *tmpout2; - char *altout; - fs_xml *fs_gpx; - - waypoint_count++; - - if (split_output) { - char *thisfname; - xasprintf(&thisfname, "%s%d", output_name, waypoint_count); - file_out = gbfopen(thisfname, "w", MYNAME); - } - - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); - - GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, - &utme, &utmn, &utmz, &utmzc); - - if (tm == 0) - tm = time(NULL); - strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); - - tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0); - if (wpt->altitude != unknown_alt) { - xasprintf(&altout, " alt:%d", (int) ( (altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude) ); - } - else { - altout = ""; - } - xasprintf (&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout ); - gbfprintf(file_out, "%-16s %59s\n", - (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, - tmpout2); - xfree(tmpout2); - xfree(tmpout1); - if (altout[0]) - xfree(altout); - - - if (strcmp(wpt->description, wpt->shortname)) { - gbfprintf(file_out, "%s", wpt->description); - if (wpt->gc_data->placer) - gbfprintf(file_out, " by %s", wpt->gc_data->placer); - } - if (wpt->gc_data->terr) { - gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n", - gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container), - (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"", - (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":"" ); - if (wpt->gc_data->desc_short.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_short); - gbfprintf (file_out, "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->desc_long.utfstring) { - char *stripped_html = strip_html(&wpt->gc_data->desc_long); - gbfprintf (file_out, "\n%s\n", stripped_html); - xfree(stripped_html); - } - if (wpt->gc_data->hint) { - char *hint = NULL; - if ( txt_encrypt ) - hint = rot13( wpt->gc_data->hint ); - else - hint = xstrdup( wpt->gc_data->hint ); - gbfprintf (file_out, "\nHint: %s\n", hint); - xfree( hint ); - } - } - else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { - gbfprintf (file_out, "\n%s\n", wpt->notes); - } - - fs_gpx = NULL; - if ( includelogs ) { - fs_gpx = (fs_xml *)fs_chain_find( wpt->fs, FS_GPX); - } - - if ( fs_gpx && fs_gpx->tag ) { - xml_tag *root = fs_gpx->tag; - xml_tag *curlog = NULL; - xml_tag *logpart = NULL; - curlog = xml_findfirst( root, "groundspeak:log" ); - while ( curlog ) { - time_t logtime = 0; - struct tm *logtm = NULL; - gbfprintf( file_out, "\n" ); - - logpart = xml_findfirst( curlog, "groundspeak:type" ); - if ( logpart ) { - gbfprintf( file_out, "%s by ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:finder" ); - if ( logpart ) { - gbfprintf( file_out, "%s on ", logpart->cdata ); - } - - logpart = xml_findfirst( curlog, "groundspeak:date" ); - if ( logpart ) { - logtime = xml_parse_time( logpart->cdata, NULL); - logtm = localtime( &logtime ); - if ( logtm ) { - gbfprintf( file_out, - "%4.4d-%2.2d-%2.2d\n", - logtm->tm_year+1900, - logtm->tm_mon+1, - logtm->tm_mday ); - } - } - - logpart = xml_findfirst( curlog, "groundspeak:log_wpt" ); - if ( logpart ) { - char *coordstr = NULL; - float lat = 0; - float lon = 0; - coordstr = xml_attribute( logpart, "lat" ); - if ( coordstr ) { - lat = atof( coordstr ); - } - coordstr = xml_attribute( logpart, "lon" ); - if ( coordstr ) { - lon = atof( coordstr ); - } - coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0); - gbfprintf( file_out, "%s\n", coordstr); - xfree(coordstr); - } - - logpart = xml_findfirst( curlog, "groundspeak:text" ); - if ( logpart ) { - char *encstr = NULL; - char *s = NULL; - int encoded = 0; - encstr = xml_attribute( logpart, "encoded" ); - encoded = (encstr[0] != 'F'); - - if ( txt_encrypt && encoded ) { - s = rot13( logpart->cdata ); - } - else { - s = xstrdup( logpart->cdata ); - } - - gbfprintf( file_out, "%s", s ); - xfree( s ); - } - - gbfprintf( file_out, "\n" ); - curlog = xml_findnext( root, curlog, "groundspeak:log" ); - } - } - if (! suppresssep) - gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n"); - else - gbfprintf(file_out, "\n"); - - if (split_output) { - gbfclose(file_out); - file_out = NULL; - } + int latint, lonint; + char tbuf[1024]; + time_t tm = wpt->creation_time; + gbint32 utmz; + double utme, utmn; + char utmzc; + char *tmpout1, *tmpout2; + char *altout; + fs_xml *fs_gpx; + + waypoint_count++; + + if (split_output) { + char *thisfname; + xasprintf(&thisfname, "%s%d", output_name, waypoint_count); + file_out = gbfopen(thisfname, "w", MYNAME); + } + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude, + &utme, &utmn, &utmz, &utmzc); + + if (tm == 0) { + tm = time(NULL); + } + strftime(tbuf, sizeof(tbuf), "%d-%b-%Y", localtime(&tm)); + + tmpout1 = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 0); + if (wpt->altitude != unknown_alt) { + xasprintf(&altout, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude)); + } else { + altout = ""; + } + xasprintf(&tmpout2, "%s (%d%c %6.0f %7.0f)%s", tmpout1, utmz, utmzc, utme, utmn, altout); + gbfprintf(file_out, "%-16s %59s\n", + (global_opts.synthesize_shortnames) ? mkshort_from_wpt(mkshort_handle, wpt) : wpt->shortname, + tmpout2); + xfree(tmpout2); + xfree(tmpout1); + if (altout[0]) { + xfree(altout); + } + + + if (strcmp(wpt->description, wpt->shortname)) { + gbfprintf(file_out, "%s", wpt->description); + if (wpt->gc_data->placer) { + gbfprintf(file_out, " by %s", wpt->gc_data->placer); + } + } + if (wpt->gc_data->terr) { + gbfprintf(file_out, " - %s / %s - (%d%s / %d%s)\n", + gs_get_cachetype(wpt->gc_data->type), gs_get_container(wpt->gc_data->container), + (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?".5":"", + (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?".5":""); + if (wpt->gc_data->desc_short.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_short); + gbfprintf(file_out, "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->desc_long.utfstring) { + char *stripped_html = strip_html(&wpt->gc_data->desc_long); + gbfprintf(file_out, "\n%s\n", stripped_html); + xfree(stripped_html); + } + if (wpt->gc_data->hint) { + char *hint = NULL; + if (txt_encrypt) { + hint = rot13(wpt->gc_data->hint); + } else { + hint = xstrdup(wpt->gc_data->hint); + } + gbfprintf(file_out, "\nHint: %s\n", hint); + xfree(hint); + } + } else if (wpt->notes && (!wpt->description || strcmp(wpt->notes,wpt->description))) { + gbfprintf(file_out, "\n%s\n", wpt->notes); + } + + fs_gpx = NULL; + if (includelogs) { + fs_gpx = (fs_xml *)fs_chain_find(wpt->fs, FS_GPX); + } + + if (fs_gpx && fs_gpx->tag) { + xml_tag *root = fs_gpx->tag; + xml_tag *curlog = NULL; + xml_tag *logpart = NULL; + curlog = xml_findfirst(root, "groundspeak:log"); + while (curlog) { + time_t logtime = 0; + struct tm *logtm = NULL; + gbfprintf(file_out, "\n"); + + logpart = xml_findfirst(curlog, "groundspeak:type"); + if (logpart) { + gbfprintf(file_out, "%s by ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:finder"); + if (logpart) { + gbfprintf(file_out, "%s on ", logpart->cdata); + } + + logpart = xml_findfirst(curlog, "groundspeak:date"); + if (logpart) { + logtime = xml_parse_time(logpart->cdata, NULL); + logtm = localtime(&logtime); + if (logtm) { + gbfprintf(file_out, + "%4.4d-%2.2d-%2.2d\n", + logtm->tm_year+1900, + logtm->tm_mon+1, + logtm->tm_mday); + } + } + + logpart = xml_findfirst(curlog, "groundspeak:log_wpt"); + if (logpart) { + char *coordstr = NULL; + float lat = 0; + float lon = 0; + coordstr = xml_attribute(logpart, "lat"); + if (coordstr) { + lat = atof(coordstr); + } + coordstr = xml_attribute(logpart, "lon"); + if (coordstr) { + lon = atof(coordstr); + } + coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 0); + gbfprintf(file_out, "%s\n", coordstr); + xfree(coordstr); + } + + logpart = xml_findfirst(curlog, "groundspeak:text"); + if (logpart) { + char *encstr = NULL; + char *s = NULL; + int encoded = 0; + encstr = xml_attribute(logpart, "encoded"); + encoded = (encstr[0] != 'F'); + + if (txt_encrypt && encoded) { + s = rot13(logpart->cdata); + } else { + s = xstrdup(logpart->cdata); + } + + gbfprintf(file_out, "%s", s); + xfree(s); + } + + gbfprintf(file_out, "\n"); + curlog = xml_findnext(root, curlog, "groundspeak:log"); + } + } + if (! suppresssep) { + gbfprintf(file_out, "\n-----------------------------------------------------------------------------\n"); + } else { + gbfprintf(file_out, "\n"); + } + + if (split_output) { + gbfclose(file_out); + file_out = NULL; + } } static void data_write(void) { - if (! suppresssep && !split_output) - gbfprintf(file_out, "-----------------------------------------------------------------------------\n"); - setshort_length(mkshort_handle, 6); - waypt_disp_all(text_disp); + if (! suppresssep && !split_output) { + gbfprintf(file_out, "-----------------------------------------------------------------------------\n"); + } + setshort_length(mkshort_handle, 6); + waypt_disp_all(text_disp); } ff_vecs_t text_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none}, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - text_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + text_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/tiger.c b/gpsbabel/tiger.c index e06c6212e..3560de17a 100644 --- a/gpsbabel/tiger.c +++ b/gpsbabel/tiger.c @@ -36,8 +36,8 @@ static char *suppresswhite = NULL; static char *iconismarker = NULL; static char *snlen = NULL; -static char *margin = NULL; -static char *xpixels = NULL; +static char *margin = NULL; +static char *xpixels = NULL; static char *ypixels = NULL; static char *oldthresh = NULL; static char *oldmarker = NULL; @@ -60,231 +60,270 @@ static char *clickmap = NULL; static arglist_t tiger_args[] = { - {"nolabels", &nolabels, "Suppress labels on generated pins", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"genurl", &genurl, "Generate file with lat/lon for centering map", - NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX }, - {"margin", &margin, "Margin for map. Degrees or percentage", - "15%", ARGTYPE_FLOAT, ARG_NOMINMAX}, - {"snlen", &snlen, "Max shortname length when used with -s", - "10", ARGTYPE_INT, "1", NULL}, - {"oldthresh", &oldthresh, - "Days after which points are considered old", - "14", ARGTYPE_INT, ARG_NOMINMAX}, - {"oldmarker", &oldmarker, "Marker type for old points", - "redpin", ARGTYPE_STRING, ARG_NOMINMAX}, - {"newmarker", &newmarker, "Marker type for new points", - "greenpin", ARGTYPE_STRING, ARG_NOMINMAX}, - {"suppresswhite", &suppresswhite, - "Suppress whitespace in generated shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"unfoundmarker", &unfoundmarker, "Marker type for unfound points", - "bluepin", ARGTYPE_STRING, ARG_NOMINMAX}, - {"xpixels", &xpixels, "Width in pixels of map", - "768", ARGTYPE_INT, ARG_NOMINMAX}, - {"ypixels", &ypixels, "Height in pixels of map", - "768", ARGTYPE_INT, ARG_NOMINMAX}, - {"iconismarker", &iconismarker, - "The icon description is already the marker", NULL, - ARGTYPE_BOOL, ARG_NOMINMAX }, + { + "nolabels", &nolabels, "Suppress labels on generated pins", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "genurl", &genurl, "Generate file with lat/lon for centering map", + NULL, ARGTYPE_OUTFILE, ARG_NOMINMAX + }, + { + "margin", &margin, "Margin for map. Degrees or percentage", + "15%", ARGTYPE_FLOAT, ARG_NOMINMAX + }, + { + "snlen", &snlen, "Max shortname length when used with -s", + "10", ARGTYPE_INT, "1", NULL + }, + { + "oldthresh", &oldthresh, + "Days after which points are considered old", + "14", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "oldmarker", &oldmarker, "Marker type for old points", + "redpin", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "newmarker", &newmarker, "Marker type for new points", + "greenpin", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "suppresswhite", &suppresswhite, + "Suppress whitespace in generated shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "unfoundmarker", &unfoundmarker, "Marker type for unfound points", + "bluepin", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "xpixels", &xpixels, "Width in pixels of map", + "768", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "ypixels", &ypixels, "Height in pixels of map", + "768", ARGTYPE_INT, ARG_NOMINMAX + }, + { + "iconismarker", &iconismarker, + "The icon description is already the marker", NULL, + ARGTYPE_BOOL, ARG_NOMINMAX + }, #if CLICKMAP - {"clickmap", &clickmap, "Generate Clickable map web page", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, + { + "clickmap", &clickmap, "Generate Clickable map web page", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, #endif - ARG_TERMINATOR + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_in = gbfopen(fname, "rb", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void rd_deinit(void) { - gbfclose(file_in); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_in); + mkshort_del_handle(&mkshort_handle); } static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - thresh_days = strtod(oldthresh, NULL); + file_out = gbfopen(fname, "w", MYNAME); + thresh_days = strtod(oldthresh, NULL); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } static void data_read(void) { - double lat,lon; - char desc[100]; - char icon[100]; - char *ibuf; - waypoint *wpt_tmp; - int line = 0; - - while ((ibuf = gbfgetstr(file_in))) { - if ((line++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - if( sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", - &lon, &lat, icon, desc)) { - wpt_tmp = waypt_new(); - - wpt_tmp->longitude = lon; - wpt_tmp->latitude = lat; - wpt_tmp->description = xstrdup(desc); - wpt_tmp->shortname = mkshort(mkshort_handle, desc); - - waypt_add(wpt_tmp); - } - } + double lat,lon; + char desc[100]; + char icon[100]; + char *ibuf; + waypoint *wpt_tmp; + int line = 0; + + while ((ibuf = gbfgetstr(file_in))) { + if ((line++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + if (sscanf(ibuf, "%lf,%lf:%100[^:]:%100[^\n]", + &lon, &lat, icon, desc)) { + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = lon; + wpt_tmp->latitude = lat; + wpt_tmp->description = xstrdup(desc); + wpt_tmp->shortname = mkshort(mkshort_handle, desc); + + waypt_add(wpt_tmp); + } + } } static void tiger_disp(const waypoint *wpt) { - const char *pin; - double lat = wpt->latitude; - double lon = wpt->longitude; - - if (iconismarker) - pin = wpt->icon_descr ? wpt->icon_descr : ""; - else if (wpt->icon_descr && strstr(wpt->icon_descr, "-unfound")) - pin = unfoundmarker; - else if (wpt->creation_time > current_time() - 3600 * 24 * thresh_days) - pin = newmarker; - else - pin = oldmarker; - - if (genurl) { - if (lat > maxlat) maxlat = lat; - if (lon > maxlon) maxlon = lon; - if (lat < minlat) minlat = lat; - if (lon < minlon) minlon = lon; - } - - gbfprintf(file_out, "%f,%f:%s", lon, lat, pin); - if (!nolabels) { - char *temp = NULL; - char *desc = csv_stringclean(wpt->description, ":"); - if (global_opts.synthesize_shortnames) - { - temp = desc; - desc = mkshort(mkshort_whandle, desc); - } - gbfprintf(file_out, ":%s", desc); - if (temp != NULL) desc = temp; - xfree(desc); - } - gbfprintf(file_out, "\n"); + const char *pin; + double lat = wpt->latitude; + double lon = wpt->longitude; + + if (iconismarker) { + pin = wpt->icon_descr ? wpt->icon_descr : ""; + } else if (wpt->icon_descr && strstr(wpt->icon_descr, "-unfound")) { + pin = unfoundmarker; + } else if (wpt->creation_time > current_time() - 3600 * 24 * thresh_days) { + pin = newmarker; + } else { + pin = oldmarker; + } + + if (genurl) { + if (lat > maxlat) { + maxlat = lat; + } + if (lon > maxlon) { + maxlon = lon; + } + if (lat < minlat) { + minlat = lat; + } + if (lon < minlon) { + minlon = lon; + } + } + + gbfprintf(file_out, "%f,%f:%s", lon, lat, pin); + if (!nolabels) { + char *temp = NULL; + char *desc = csv_stringclean(wpt->description, ":"); + if (global_opts.synthesize_shortnames) { + temp = desc; + desc = mkshort(mkshort_whandle, desc); + } + gbfprintf(file_out, ":%s", desc); + if (temp != NULL) { + desc = temp; + } + xfree(desc); + } + gbfprintf(file_out, "\n"); } #if CLICKMAP static void map_plot(const waypoint *wpt) { - static int x,y; + static int x,y; - /* Replace with real math. */ - x+=10; - y+=10; + /* Replace with real math. */ + x+=10; + y+=10; - gbfprintf(linkf, "\"%s\"\n",url, wpt->description); + gbfprintf(linkf, "\"%s\"\n",url, wpt->description); } #endif /* CLICKMAP */ static double dscale(double distance) { - /* - * If we have any specified margin options factor those in now. - * A additional little boundary is helpful because Tiger always - * puts the pin above the actual coord and if we don't pad the - * top will be clipped. It also makes the maps more useful to - * have a little bit of context around the pins on the border. - */ - - if (strchr(margin, '%')) - return distance + strtod(margin, NULL) / 100.0 * distance; - else - return strtod(margin, NULL) + distance; + /* + * If we have any specified margin options factor those in now. + * A additional little boundary is helpful because Tiger always + * puts the pin above the actual coord and if we don't pad the + * top will be clipped. It also makes the maps more useful to + * have a little bit of context around the pins on the border. + */ + + if (strchr(margin, '%')) { + return distance + strtod(margin, NULL) / 100.0 * distance; + } else { + return strtod(margin, NULL) + distance; + } } static void data_write(void) { - double latsz,lonsz; - maxlat = -9999.0; - maxlon = -9999.0; - minlat = 9999.0; - minlon = 9999.0; - rec_cnt = 0; - - short_length = atoi(snlen); - mkshort_whandle = mkshort_new_handle(); - - if (suppresswhite) { - setshort_whitespace_ok(mkshort_whandle, 0); - } - - setshort_length(mkshort_whandle, short_length); - - gbfprintf(file_out, "#tms-marker\n"); - waypt_disp_all(tiger_disp); - - if (genurl) { - gbfile *urlf; - - urlf = gbfopen(genurl, "w", MYNAME); - latsz = fabs(maxlat - minlat); - lonsz = fabs(maxlon - minlon); - - /* - * Center the map along X and Y axis the midpoint of - * our min and max coords each way. - */ - gbfprintf(urlf, "lat=%f&lon=%f&ht=%f&wid=%f", - minlat + (latsz/2.0), - minlon + (lonsz/2.0), - dscale(latsz), - dscale(lonsz)); - - gbfprintf(urlf, "&iwd=%s&iht=%s", xpixels, ypixels); - gbfclose(urlf); + double latsz,lonsz; + maxlat = -9999.0; + maxlon = -9999.0; + minlat = 9999.0; + minlon = 9999.0; + rec_cnt = 0; + + short_length = atoi(snlen); + mkshort_whandle = mkshort_new_handle(); + + if (suppresswhite) { + setshort_whitespace_ok(mkshort_whandle, 0); + } + + setshort_length(mkshort_whandle, short_length); + + gbfprintf(file_out, "#tms-marker\n"); + waypt_disp_all(tiger_disp); + + if (genurl) { + gbfile *urlf; + + urlf = gbfopen(genurl, "w", MYNAME); + latsz = fabs(maxlat - minlat); + lonsz = fabs(maxlon - minlon); + + /* + * Center the map along X and Y axis the midpoint of + * our min and max coords each way. + */ + gbfprintf(urlf, "lat=%f&lon=%f&ht=%f&wid=%f", + minlat + (latsz/2.0), + minlon + (lonsz/2.0), + dscale(latsz), + dscale(lonsz)); + + gbfprintf(urlf, "&iwd=%s&iht=%s", xpixels, ypixels); + gbfclose(urlf); #if CLICKMAP - if (clickmap) { - linkf = gbfopen(clickmap, "w", MYNAME); - gbfprintf(linkf, "\n"); - waypt_disp_all(map_plot); - gbfprintf(linkf, "\n"); - gbfclose(linkf); - linkf = NULL; - } + if (clickmap) { + linkf = gbfopen(clickmap, "w", MYNAME); + gbfprintf(linkf, "\n"); + waypt_disp_all(map_plot); + gbfprintf(linkf, "\n"); + gbfclose(linkf); + linkf = NULL; + } #endif - } + } - mkshort_del_handle(&mkshort_whandle); + mkshort_del_handle(&mkshort_whandle); } ff_vecs_t tiger_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - tiger_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + tiger_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/tmpro.c b/gpsbabel/tmpro.c index c46899602..94cb02ff1 100644 --- a/gpsbabel/tmpro.c +++ b/gpsbabel/tmpro.c @@ -10,7 +10,7 @@ Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink 25 6 80 8 8 8 8 8 4 4 128 (lengths) - + Based on the specifications found in the TopoMapPro documentation available from website ---------------------------------------------------------------------------------------- @@ -41,219 +41,226 @@ static gbfile *file_in, *file_out; static short_handle mkshort_handle; -static void +static void rd_init(const char *fname) { - file_in = gbfopen(fname, "rb", MYNAME); + file_in = gbfopen(fname, "rb", MYNAME); } -static void +static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } -static void +static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); + file_out = gbfopen(fname, "w", MYNAME); } -static void +static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } -static void +static void data_read(void) { - char *buff; - char *s; - char *holder; - waypoint *wpt_tmp; - int i; - int linecount = 0; - - while ((buff = gbfgetstr(file_in))) { - if ((linecount++ == 0) && file_in->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); - - /* skip the line if it contains "sHyperLink" as it is a header (I hope :) */ - if ((strlen(buff)) && (strstr(buff, "sHyperLink") == NULL)) { - - wpt_tmp = waypt_new(); - - /* data delimited by tabs, not enclosed in quotes. */ - s = buff; - s = csv_lineparse(s, "\t", "", linecount); - - i = 0; - while (s) { - switch (i) { - - /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ - /* 0 1 2 3 4 5 6 7 8 9 10 */ - - case 0: - /* ignore: group */ - break; - case 1: - wpt_tmp->shortname = csv_stringtrim(s, "", 0); - break; - case 2: - /* Description is not a TopoMapPro format requirement. - If we assign "" then .loc/.gpx will generate empty XML tags :( - */ - holder = csv_stringtrim(s, "", 0); - if (strlen(holder)) - wpt_tmp->description = holder; - else - xfree(holder); - break; - case 3: - wpt_tmp->latitude = atof(s); - break; - case 4: - wpt_tmp->longitude = atof(s); - break; - case 5: - /* ignore: NZMapGrid Easting */ - break; - case 6: - /* ignore: NZMapGrid Northing */ - break; - case 7: - wpt_tmp->altitude = atof(s); - break; - case 8: - /* ignore: color */ - break; - case 9: - /* ignore: symbol (non standard) */ - break; - case 10: - /* URL is not a TopoMapPro format requirement. - You can store file links etc, we will discard anything that is not http - (as URLs in TMPro must start "http:") as other GPS formats probably can't - use the TopoMapLinks links. - (plus discards length 0 strings (so no empty XML tags)) - */ - holder = csv_stringtrim(s, "", 0); - if (strstr(holder, "http:") != NULL) - wpt_tmp->url = holder; - else - xfree(holder); - break; - default: - /* whoa! nelly */ - warning(MYNAME ": Warning: data fields on line %d exceed specification.\n", - linecount); - break; - } - i++; - - s = csv_lineparse(NULL, "\t", "\"", linecount); - } - - if (i != 11) { - xfree(wpt_tmp); - warning(MYNAME ": WARNING - extracted %d fields from line %d. \nData on line ignored.\n", - i, linecount); - } else { - waypt_add(wpt_tmp); - } - - } else { - /* empty line */ - } + char *buff; + char *s; + char *holder; + waypoint *wpt_tmp; + int i; + int linecount = 0; + + while ((buff = gbfgetstr(file_in))) { + if ((linecount++ == 0) && file_in->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } + + /* skip the line if it contains "sHyperLink" as it is a header (I hope :) */ + if ((strlen(buff)) && (strstr(buff, "sHyperLink") == NULL)) { + + wpt_tmp = waypt_new(); + + /* data delimited by tabs, not enclosed in quotes. */ + s = buff; + s = csv_lineparse(s, "\t", "", linecount); + + i = 0; + while (s) { + switch (i) { + + /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ + /* 0 1 2 3 4 5 6 7 8 9 10 */ + + case 0: + /* ignore: group */ + break; + case 1: + wpt_tmp->shortname = csv_stringtrim(s, "", 0); + break; + case 2: + /* Description is not a TopoMapPro format requirement. + If we assign "" then .loc/.gpx will generate empty XML tags :( + */ + holder = csv_stringtrim(s, "", 0); + if (strlen(holder)) { + wpt_tmp->description = holder; + } else { + xfree(holder); + } + break; + case 3: + wpt_tmp->latitude = atof(s); + break; + case 4: + wpt_tmp->longitude = atof(s); + break; + case 5: + /* ignore: NZMapGrid Easting */ + break; + case 6: + /* ignore: NZMapGrid Northing */ + break; + case 7: + wpt_tmp->altitude = atof(s); + break; + case 8: + /* ignore: color */ + break; + case 9: + /* ignore: symbol (non standard) */ + break; + case 10: + /* URL is not a TopoMapPro format requirement. + You can store file links etc, we will discard anything that is not http + (as URLs in TMPro must start "http:") as other GPS formats probably can't + use the TopoMapLinks links. + (plus discards length 0 strings (so no empty XML tags)) + */ + holder = csv_stringtrim(s, "", 0); + if (strstr(holder, "http:") != NULL) { + wpt_tmp->url = holder; + } else { + xfree(holder); + } + break; + default: + /* whoa! nelly */ + warning(MYNAME ": Warning: data fields on line %d exceed specification.\n", + linecount); + break; + } + i++; + + s = csv_lineparse(NULL, "\t", "\"", linecount); + } + if (i != 11) { + xfree(wpt_tmp); + warning(MYNAME ": WARNING - extracted %d fields from line %d. \nData on line ignored.\n", + i, linecount); + } else { + waypt_add(wpt_tmp); + } + + } else { + /* empty line */ } + + } } -static void +static void tmpro_waypt_pr(const waypoint * wpt) { - int icon = 1; /* default to "flag" */ - int colour = 255; /*default to red */ - char *shortname = NULL; - char *description = NULL; - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = csv_stringclean(wpt->description, ",\""); - } else { - /* no description available */ - shortname = xstrdup(""); - } - } else{ - shortname = csv_stringclean(wpt->shortname, ",\""); + int icon = 1; /* default to "flag" */ + int colour = 255; /*default to red */ + char *shortname = NULL; + char *description = NULL; + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = csv_stringclean(wpt->description, ",\""); + } + } else { + /* no description available */ + shortname = xstrdup(""); } + } else { + shortname = csv_stringclean(wpt->shortname, ",\""); + } - if (! wpt->description) { - if (shortname) { - description = csv_stringclean(shortname, ",\""); - } else { - description = xstrdup(""); - } - } else{ - description = csv_stringclean(wpt->description, ",\""); + if (! wpt->description) { + if (shortname) { + description = csv_stringclean(shortname, ",\""); + } else { + description = xstrdup(""); } - - /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ - /* 0 1 2 3 4 5 6 7 8 9 10 */ - /* Number of characters */ - /* 25 6 80 8 8 8 8 8 4 4 128 */ - - gbfprintf(file_out, "new\t%.6s\t%.80s\t%08.6f\t%08.6f\t\t\t%.2f\t%d\t%d\t%.128s\n", - shortname, - description, - wpt->latitude, - wpt->longitude, - wpt->altitude, - colour, - icon, - wpt->url ? wpt->url : "" - ); - - - if (description) - xfree(description); - if (shortname) - xfree(shortname); + } else { + description = csv_stringclean(wpt->description, ",\""); + } + + /* Group sID sDescription fLat fLong fEasting fNorthing fAlt iColour iSymbol sHyperLink */ + /* 0 1 2 3 4 5 6 7 8 9 10 */ + /* Number of characters */ + /* 25 6 80 8 8 8 8 8 4 4 128 */ + + gbfprintf(file_out, "new\t%.6s\t%.80s\t%08.6f\t%08.6f\t\t\t%.2f\t%d\t%d\t%.128s\n", + shortname, + description, + wpt->latitude, + wpt->longitude, + wpt->altitude, + colour, + icon, + wpt->url ? wpt->url : "" + ); + + + if (description) { + xfree(description); + } + if (shortname) { + xfree(shortname); + } } -static void +static void data_write(void) { - /* Short names */ - if (global_opts.synthesize_shortnames) { - mkshort_handle = mkshort_new_handle(); - setshort_length(mkshort_handle, 6); - setshort_whitespace_ok(mkshort_handle, 0); - setshort_badchars(mkshort_handle, "\","); - } - - /* Write file header */ - gbfprintf(file_out, "Group\tsID\tsDescription\tfLat\tfLong\tfEasting\tfNorthing\tfAlt\tiColour\tiSymbol\tsHyperLink\n"); + /* Short names */ + if (global_opts.synthesize_shortnames) { + mkshort_handle = mkshort_new_handle(); + setshort_length(mkshort_handle, 6); + setshort_whitespace_ok(mkshort_handle, 0); + setshort_badchars(mkshort_handle, "\","); + } + + /* Write file header */ + gbfprintf(file_out, "Group\tsID\tsDescription\tfLat\tfLong\tfEasting\tfNorthing\tfAlt\tiColour\tiSymbol\tsHyperLink\n"); - waypt_disp_all(tmpro_waypt_pr); - mkshort_del_handle(&mkshort_handle); + waypt_disp_all(tmpro_waypt_pr); + mkshort_del_handle(&mkshort_handle); } ff_vecs_t tmpro_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - NULL, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + NULL, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/tomtom.c b/gpsbabel/tomtom.c index 76d7d03d1..d79a76cf4 100644 --- a/gpsbabel/tomtom.c +++ b/gpsbabel/tomtom.c @@ -23,20 +23,20 @@ /* This module is based on my reverse-engineering of the .ov2 format, so - it might not be aware of all record types. In particular, I've seen + it might not be aware of all record types. In particular, I've seen a type-3 record that may contain additional strings, but since I haven't seen any of those from a legitimate source, I don't know what they are supposed to contain. Thus, they are not currently supported. (The one I saw was due to an errant pair of double-quotes in the input to makeov2.exe.) -- Ron Parker, 28 April 2005 - - Because they've been seen in the wild, I have updated the reader to - deal with type 3 as if they were type 2. I still haven't seen any + + Because they've been seen in the wild, I have updated the reader to + deal with type 3 as if they were type 2. I still haven't seen any records that fill in the other two strings, so until I know for sure - that they are indeed strings, I'm just putting them on the end of the + that they are indeed strings, I'm just putting them on the end of the description string beyond the NUL terminator. -- Ron Parker, 17 July 2006 */ - + #include "defs.h" @@ -47,31 +47,31 @@ static gbfile *file_out; static arglist_t tomtom_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static void rd_init(const char *fname) { - file_in = gbfopen_le(fname, "rb", MYNAME); + file_in = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(file_in); + gbfclose(file_in); } static void wr_init(const char *fname) { - file_out = gbfopen_le(fname, "wb", MYNAME); + file_out = gbfopen_le(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(file_out); + gbfclose(file_out); } #define read_long(f) gbfgetint32((f)) @@ -91,8 +91,8 @@ decode_8(int sz, const unsigned char *inbuf) char *out = rval; int i; - for (i = 0; i < sz;) { - if (inbuf[0] & 0x80) { + for (i = 0; i < sz;) { + if (inbuf[0] & 0x80) { int idx; int res; idx = (inbuf[0] & 0x70) >> 4; @@ -103,11 +103,13 @@ decode_8(int sz, const unsigned char *inbuf) inbuf++; i++; - } else { + } else { int c1 = (inbuf[0] & 0x7c) >> 2; int c2 = ((inbuf[0] & 3) << 3) | (inbuf[1] & 0xe0) >> 5; int c3 = inbuf[1] & 0x1f; - if ((c1 | c2 | c3) > 0x1f) fatal("bit unpacking error"); + if ((c1 | c2 | c3) > 0x1f) { + fatal("bit unpacking error"); + } *out++ = encoding_8[c1]; *out++ = encoding_8[c2]; *out++ = encoding_8[c3]; @@ -125,8 +127,8 @@ decode_latlon(double *lat, double *lon) unsigned char lonbuf[3]; double rlat, rlon; - gbfread(&lonbuf, 3, 1, file_in ); - gbfread(&latbuf, 3, 1, file_in ); + gbfread(&lonbuf, 3, 1, file_in); + gbfread(&latbuf, 3, 1, file_in); rlat = ((latbuf[2] << 16) + (latbuf[1] << 8) + latbuf[0]) / 1000000.0; *lat = 80 - rlat; @@ -137,327 +139,334 @@ decode_latlon(double *lat, double *lon) static void check_recsize(int sz) { - if ((sz > 100000) || (sz < 0)) { - fatal(MYNAME ":malformed file. Bad record size."); - } + if ((sz > 100000) || (sz < 0)) { + fatal(MYNAME ":malformed file. Bad record size."); + } } static void data_read(void) { - int rectype; - long recsize; - long x; - long y; - char *desc; - waypoint *wpt_tmp; - while (!gbfeof( file_in ) ) { - rectype = read_char( file_in ); - if (rectype == EOF) { - fatal(MYNAME ":Unexpected EOF."); - } - if (global_opts.debug_level >= 5) - printf("Reading record type %d\n", rectype ); - switch (rectype) { - case 0: - case 100: - if (global_opts.debug_level >= 5) - printf("Skipping deleted record\n" ); - recsize = read_long( file_in ) - 5; - check_recsize(recsize); - if (global_opts.debug_level >= 5) - printf("Skipping %li bytes\n", recsize ); - gbfseek(file_in, recsize, SEEK_CUR); - break; - case 1: - /* a block header; ignored on read */ - read_long( file_in ); - read_long( file_in ); - read_long( file_in ); - read_long( file_in ); - read_long( file_in ); - break; - case 2: - case 3: - recsize = read_long( file_in ); - check_recsize(recsize); - x = read_long( file_in ); - y = read_long( file_in ); - desc = (char *)xmalloc( recsize - 13 ); - gbfread( desc, recsize-13, 1, file_in ); - - wpt_tmp = waypt_new(); - - wpt_tmp->longitude = x/100000.0; - wpt_tmp->latitude = y/100000.0; - wpt_tmp->description = desc; - // TODO:: description in rectype 3 contains two zero-terminated strings - // First is same as rectype 2, second apparently contains the unique ID of the waypoint - // See http://www.tomtom.com/lib/doc/PRO/TTN6_SDK_documentation.zip - if ( rectype == 3) { - warning("Unexpected waypoint record type %d encountered.\nThe unique ID of the POI may have been dropped.\n", rectype ); - } - - waypt_add(wpt_tmp); - break; - case 8: - case 24: + int rectype; + long recsize; + long x; + long y; + char *desc; + waypoint *wpt_tmp; + while (!gbfeof(file_in)) { + rectype = read_char(file_in); + if (rectype == EOF) { + fatal(MYNAME ":Unexpected EOF."); + } + if (global_opts.debug_level >= 5) { + printf("Reading record type %d\n", rectype); + } + switch (rectype) { + case 0: + case 100: + if (global_opts.debug_level >= 5) { + printf("Skipping deleted record\n"); + } + recsize = read_long(file_in) - 5; + check_recsize(recsize); + if (global_opts.debug_level >= 5) { + printf("Skipping %li bytes\n", recsize); + } + gbfseek(file_in, recsize, SEEK_CUR); + break; + case 1: + /* a block header; ignored on read */ + read_long(file_in); + read_long(file_in); + read_long(file_in); + read_long(file_in); + read_long(file_in); + break; + case 2: + case 3: + recsize = read_long(file_in); + check_recsize(recsize); + x = read_long(file_in); + y = read_long(file_in); + desc = (char *)xmalloc(recsize - 13); + gbfread(desc, recsize-13, 1, file_in); + + wpt_tmp = waypt_new(); + + wpt_tmp->longitude = x/100000.0; + wpt_tmp->latitude = y/100000.0; + wpt_tmp->description = desc; + // TODO:: description in rectype 3 contains two zero-terminated strings + // First is same as rectype 2, second apparently contains the unique ID of the waypoint + // See http://www.tomtom.com/lib/doc/PRO/TTN6_SDK_documentation.zip + if (rectype == 3) { + warning("Unexpected waypoint record type %d encountered.\nThe unique ID of the POI may have been dropped.\n", rectype); + } + + waypt_add(wpt_tmp); + break; + case 8: + case 24: #if 0 // Fallthrough for now to silently ignore these until this is done. - recsize = read_char( file_in ) ; - check_recsize(recsize); - wpt_tmp = waypt_new(); - decode_latlon(&wpt_tmp->latitude, &wpt_tmp->longitude); - gbfread( tbuf, 3, 1, file_in ); - gbfread( tbuf, 3, 1, file_in ); - gbfread( tbuf, recsize, 1, file_in ); - wpt_tmp->shortname = decode_8(recsize, tbuf); - waypt_add(wpt_tmp); - break; + recsize = read_char(file_in) ; + check_recsize(recsize); + wpt_tmp = waypt_new(); + decode_latlon(&wpt_tmp->latitude, &wpt_tmp->longitude); + gbfread(tbuf, 3, 1, file_in); + gbfread(tbuf, 3, 1, file_in); + gbfread(tbuf, recsize, 1, file_in); + wpt_tmp->shortname = decode_8(recsize, tbuf); + waypt_add(wpt_tmp); + break; #else #endif - case 9: - case 25: - recsize = read_char( file_in ) + 6; - check_recsize(recsize); - if (global_opts.debug_level >= 5) - warning("Unknown record type 0x%x; skipping %ld bytes.\n", - rectype, recsize); - gbfseek(file_in, recsize, SEEK_CUR); - break; - default: - if (global_opts.debug_level >= 1) { - warning("Unexpected waypoint record type: %d at offset 0x%x\n", rectype, gbftell(file_in) ); - } - } - } + case 9: + case 25: + recsize = read_char(file_in) + 6; + check_recsize(recsize); + if (global_opts.debug_level >= 5) + warning("Unknown record type 0x%x; skipping %ld bytes.\n", + rectype, recsize); + gbfseek(file_in, recsize, SEEK_CUR); + break; + default: + if (global_opts.debug_level >= 1) { + warning("Unexpected waypoint record type: %d at offset 0x%x\n", rectype, gbftell(file_in)); + } + } + } } -struct hdr{ - waypoint *wpt; +struct hdr { + waypoint *wpt; }; static int compare_lon(const void *a, const void *b); static -int +int compare_lat(const void *a, const void *b) { - const struct hdr *wa = a; - const struct hdr *wb = b; - - double difference = wa->wpt->latitude - wb->wpt->latitude; - if ( difference < 0 ) { - return -1; - } - if ( difference ) { - return 1; - } - if ( wa->wpt->longitude - wb->wpt->longitude == 0 ) { - return strcmp(wa->wpt->shortname, wb->wpt->shortname); - } - return compare_lon(a,b); + const struct hdr *wa = a; + const struct hdr *wb = b; + + double difference = wa->wpt->latitude - wb->wpt->latitude; + if (difference < 0) { + return -1; + } + if (difference) { + return 1; + } + if (wa->wpt->longitude - wb->wpt->longitude == 0) { + return strcmp(wa->wpt->shortname, wb->wpt->shortname); + } + return compare_lon(a,b); } static -int +int compare_lon(const void *a, const void *b) { - const struct hdr *wa = a; - const struct hdr *wb = b; - - double difference = wa->wpt->longitude - wb->wpt->longitude; - if ( difference < 0 ) { - return -1; - } - if ( difference ) { - return 1; - } - if ( wa->wpt->latitude - wb->wpt->latitude == 0 ) { - return strcmp(wa->wpt->shortname, wb->wpt->shortname); - } - return compare_lat(a,b); + const struct hdr *wa = a; + const struct hdr *wb = b; + + double difference = wa->wpt->longitude - wb->wpt->longitude; + if (difference < 0) { + return -1; + } + if (difference) { + return 1; + } + if (wa->wpt->latitude - wb->wpt->latitude == 0) { + return strcmp(wa->wpt->shortname, wb->wpt->shortname); + } + return compare_lat(a,b); } #define write_long(f,v) gbfputint32((v),f) static void -write_float_as_long( gbfile *file, double value ) +write_float_as_long(gbfile *file, double value) { - long tmp = (value + 0.500000000001); - write_long( file, tmp); + long tmp = (value + 0.500000000001); + write_long(file, tmp); } #define write_char(f,c) gbfputc((c),f) #define write_string(f,s) gbfputcstr((s),f) struct blockheader { - struct hdr *start; - long count; - long size; - double minlat; - double maxlat; - double minlon; - double maxlon; - struct blockheader *ch1; - struct blockheader *ch2; + struct hdr *start; + long count; + long size; + double minlat; + double maxlat; + double minlon; + double maxlon; + struct blockheader *ch1; + struct blockheader *ch2; }; static void -write_blocks( gbfile *f, struct blockheader *blocks ) { - int i; - write_char( f, 1 ); - write_long( f, blocks->size ); - write_float_as_long( f, blocks->maxlon*100000 ); - write_float_as_long( f, blocks->maxlat*100000 ); - write_float_as_long( f, blocks->minlon*100000 ); - write_float_as_long( f, blocks->minlat*100000 ); - if ( blocks->ch1 ) { - write_blocks( f, blocks->ch1 ); - } - if ( blocks->ch2 ) { - write_blocks( f, blocks->ch2 ); - } - if ( !blocks->ch1 && !blocks->ch2 ) { - for ( i = 0; i < blocks->count; i++ ) { - char desc_field [256]; - write_char( f, 2 ); - if (global_opts.smart_names && - blocks->start[i].wpt->gc_data->diff && - blocks->start[i].wpt->gc_data->terr) { - snprintf(desc_field,sizeof(desc_field),"%s(t%ud%u)%s(type%dcont%d)",blocks->start[i].wpt->description, - blocks->start[i].wpt->gc_data->terr/10, - blocks->start[i].wpt->gc_data->diff/10, - blocks->start[i].wpt->shortname, - (int) blocks->start[i].wpt->gc_data->type, - (int) blocks->start[i].wpt->gc_data->container); - //Unfortunately enums mean we get numbers for cache type and container. - } else { - snprintf(desc_field, sizeof(desc_field), "%s", - blocks->start[i].wpt->description); - } - write_long( f, strlen( desc_field ) + 14 ); - write_float_as_long( f, blocks->start[i].wpt->longitude*100000); - write_float_as_long( f, blocks->start[i].wpt->latitude*100000); - write_string( f, desc_field); - } - } -} +write_blocks(gbfile *f, struct blockheader *blocks) +{ + int i; + write_char(f, 1); + write_long(f, blocks->size); + write_float_as_long(f, blocks->maxlon*100000); + write_float_as_long(f, blocks->maxlat*100000); + write_float_as_long(f, blocks->minlon*100000); + write_float_as_long(f, blocks->minlat*100000); + if (blocks->ch1) { + write_blocks(f, blocks->ch1); + } + if (blocks->ch2) { + write_blocks(f, blocks->ch2); + } + if (!blocks->ch1 && !blocks->ch2) { + for (i = 0; i < blocks->count; i++) { + char desc_field [256]; + write_char(f, 2); + if (global_opts.smart_names && + blocks->start[i].wpt->gc_data->diff && + blocks->start[i].wpt->gc_data->terr) { + snprintf(desc_field,sizeof(desc_field),"%s(t%ud%u)%s(type%dcont%d)",blocks->start[i].wpt->description, + blocks->start[i].wpt->gc_data->terr/10, + blocks->start[i].wpt->gc_data->diff/10, + blocks->start[i].wpt->shortname, + (int) blocks->start[i].wpt->gc_data->type, + (int) blocks->start[i].wpt->gc_data->container); + //Unfortunately enums mean we get numbers for cache type and container. + } else { + snprintf(desc_field, sizeof(desc_field), "%s", + blocks->start[i].wpt->description); + } + write_long(f, strlen(desc_field) + 14); + write_float_as_long(f, blocks->start[i].wpt->longitude*100000); + write_float_as_long(f, blocks->start[i].wpt->latitude*100000); + write_string(f, desc_field); + } + } +} static struct blockheader * -compute_blocks( struct hdr *start, int count, - double minlon, double maxlon, double minlat, double maxlat ) { - struct blockheader *newblock; - - newblock = (struct blockheader *)xcalloc( sizeof( *newblock ), 1); - newblock->start = start; - newblock->count = count; - newblock->minlon = minlon; - newblock->maxlon = maxlon; - newblock->minlat = minlat; - newblock->maxlat = maxlat; - newblock->size = 4 * 5 + 1; /* hdr is 5 longs, 1 char */ - if ( count < 20 ) { - int i; - waypoint *wpt = NULL; - - for ( i = 0; i < count; i++ ) { - newblock->size += 4 * 3 + 1; - /* wpt const part 3 longs, 1 char */ - wpt = start[i].wpt; - newblock->size += strlen( wpt->description ) + 1; - } - } - else { - if ( (maxlat-minlat)>(maxlon-minlon)) { - /* split along lats */ - qsort( start, count, sizeof(*start), compare_lat); - newblock->ch1 = compute_blocks( start, count/2, - minlon, maxlon, minlat, - start[count/2].wpt->latitude ); - newblock->ch2 = compute_blocks( start+count/2, - count-count/2, minlon, maxlon, - start[count/2].wpt->latitude, maxlat ); - } - else { - /* split along lons */ - qsort( start, count, sizeof(*start), compare_lon); - newblock->ch1 = compute_blocks( start, count/2, - minlon, start[count/2].wpt->longitude, - minlat, maxlat ); - newblock->ch2 = compute_blocks( start+count/2, - count-count/2, start[count/2].wpt->longitude, - maxlon, minlat, maxlat ); - } - if ( newblock->ch1 ) { - newblock->size += newblock->ch1->size; - } - if ( newblock->ch2 ) { - newblock->size += newblock->ch2->size; - } - } - return newblock; +compute_blocks(struct hdr *start, int count, + double minlon, double maxlon, double minlat, double maxlat) { + struct blockheader *newblock; + + newblock = (struct blockheader *)xcalloc(sizeof(*newblock), 1); + newblock->start = start; + newblock->count = count; + newblock->minlon = minlon; + newblock->maxlon = maxlon; + newblock->minlat = minlat; + newblock->maxlat = maxlat; + newblock->size = 4 * 5 + 1; /* hdr is 5 longs, 1 char */ + if (count < 20) { + int i; + waypoint *wpt = NULL; + + for (i = 0; i < count; i++) { + newblock->size += 4 * 3 + 1; + /* wpt const part 3 longs, 1 char */ + wpt = start[i].wpt; + newblock->size += strlen(wpt->description) + 1; + } + } else { + if ((maxlat-minlat)>(maxlon-minlon)) { + /* split along lats */ + qsort(start, count, sizeof(*start), compare_lat); + newblock->ch1 = compute_blocks(start, count/2, + minlon, maxlon, minlat, + start[count/2].wpt->latitude); + newblock->ch2 = compute_blocks(start+count/2, + count-count/2, minlon, maxlon, + start[count/2].wpt->latitude, maxlat); + } else { + /* split along lons */ + qsort(start, count, sizeof(*start), compare_lon); + newblock->ch1 = compute_blocks(start, count/2, + minlon, start[count/2].wpt->longitude, + minlat, maxlat); + newblock->ch2 = compute_blocks(start+count/2, + count-count/2, start[count/2].wpt->longitude, + maxlon, minlat, maxlat); + } + if (newblock->ch1) { + newblock->size += newblock->ch1->size; + } + if (newblock->ch2) { + newblock->size += newblock->ch2->size; + } + } + return newblock; } static void -free_blocks( struct blockheader *block ) { - if ( block->ch1 ) free_blocks( block->ch1 ); - if ( block->ch2 ) free_blocks( block->ch2 ); - xfree( block ); +free_blocks(struct blockheader *block) +{ + if (block->ch1) { + free_blocks(block->ch1); + } + if (block->ch2) { + free_blocks(block->ch2); + } + xfree(block); } static void data_write(void) { - int ct = waypt_count(); - struct hdr *htable, *bh; - queue *elem, *tmp; - extern queue waypt_head; - waypoint *waypointp; - double minlon = 200; - double maxlon = -200; - double minlat = 200; - double maxlat = -200; - struct blockheader *blocks = NULL; - - htable = xmalloc(ct * sizeof(*htable)); - bh = htable; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - bh->wpt = waypointp; - if ( waypointp->longitude > maxlon ) { - maxlon = waypointp->longitude; - } - if ( waypointp->longitude < minlon ) { - minlon = waypointp->longitude; - } - if ( waypointp->latitude > maxlat ) { - maxlat = waypointp->latitude; - } - if ( waypointp->latitude < minlat ) { - minlat = waypointp->latitude; - } - bh ++; - } - - blocks = compute_blocks( htable, ct, minlon, maxlon, minlat, maxlat ); - write_blocks( file_out, blocks ); - free_blocks( blocks ); - - xfree(htable); + int ct = waypt_count(); + struct hdr *htable, *bh; + queue *elem, *tmp; + extern queue waypt_head; + waypoint *waypointp; + double minlon = 200; + double maxlon = -200; + double minlat = 200; + double maxlat = -200; + struct blockheader *blocks = NULL; + + htable = xmalloc(ct * sizeof(*htable)); + bh = htable; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + bh->wpt = waypointp; + if (waypointp->longitude > maxlon) { + maxlon = waypointp->longitude; + } + if (waypointp->longitude < minlon) { + minlon = waypointp->longitude; + } + if (waypointp->latitude > maxlat) { + maxlat = waypointp->latitude; + } + if (waypointp->latitude < minlat) { + minlat = waypointp->latitude; + } + bh ++; + } + + blocks = compute_blocks(htable, ct, minlon, maxlon, minlat, maxlat); + write_blocks(file_out, blocks); + free_blocks(blocks); + + xfree(htable); } ff_vecs_t tomtom_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - data_read, - data_write, - NULL, - tomtom_args, - CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + data_read, + data_write, + NULL, + tomtom_args, + CET_CHARSET_MS_ANSI, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/tpg.c b/gpsbabel/tpg.c index 4fe014ea8..bc8c0fa8d 100644 --- a/gpsbabel/tpg.c +++ b/gpsbabel/tpg.c @@ -3,7 +3,7 @@ Contributed to gpsbabel by Alex Mottram For Topo! version 2.x. Routes are currently not implemented. - + Copyright (C) 2002 Alex Mottram, geo_alexm at cox-internet.com This program is free software; you can redistribute it and/or modify @@ -30,7 +30,7 @@ #define MYNAME "TPG" #define MAXTPGSTRINGSIZE 256 -#define MAXTPGOUTPUTPINS 65535 +#define MAXTPGOUTPUTPINS 65535 static gbfile *tpg_file_in; static gbfile *tpg_file_out; @@ -42,287 +42,290 @@ static unsigned int waypt_out_count; static arglist_t tpg_args[] = { - {"datum", &tpg_datum_opt, "Datum (default=NAD27)", "N. America 1927 mean", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + {"datum", &tpg_datum_opt, "Datum (default=NAD27)", "N. America 1927 mean", ARGTYPE_STRING, ARG_NOMINMAX }, + ARG_TERMINATOR }; static int -valid_tpg_header(char * header, int len) +valid_tpg_header(char * header, int len) { - unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, - 0x00, 0x43, 0x54, 0x6F, 0x70, - 0x6F, 0x57, 0x61, 0x79, 0x70, - 0x6F, 0x69, 0x6E, 0x74 }; - if (len != 19) { - return (-1); - } - - return memcmp(header_bytes, header, len); + unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, + 0x00, 0x43, 0x54, 0x6F, 0x70, + 0x6F, 0x57, 0x61, 0x79, 0x70, + 0x6F, 0x69, 0x6E, 0x74 + }; + if (len != 19) { + return (-1); + } + + return memcmp(header_bytes, header, len); } static void tpg_common_init(void) { - tpg_datum_idx = GPS_Lookup_Datum_Index(tpg_datum_opt); - if (tpg_datum_idx < 0) { - fatal(MYNAME ": Datum '%s' is not recognized.\n", tpg_datum_opt); - } + tpg_datum_idx = GPS_Lookup_Datum_Index(tpg_datum_opt); + if (tpg_datum_idx < 0) { + fatal(MYNAME ": Datum '%s' is not recognized.\n", tpg_datum_opt); + } } static void tpg_rd_init(const char *fname) { - tpg_common_init(); - tpg_file_in = gbfopen_le(fname, "rb", MYNAME); + tpg_common_init(); + tpg_file_in = gbfopen_le(fname, "rb", MYNAME); } static void tpg_rd_deinit(void) { - gbfclose(tpg_file_in); + gbfclose(tpg_file_in); } static void tpg_wr_init(const char *fname) { - tpg_common_init(); - tpg_file_out = gbfopen_le(fname, "wb", MYNAME); - mkshort_handle = mkshort_new_handle(); - waypt_out_count = 0; + tpg_common_init(); + tpg_file_out = gbfopen_le(fname, "wb", MYNAME); + mkshort_handle = mkshort_new_handle(); + waypt_out_count = 0; } static void tpg_wr_deinit(void) { - mkshort_del_handle(&mkshort_handle); - gbfclose(tpg_file_out); + mkshort_del_handle(&mkshort_handle); + gbfclose(tpg_file_out); } static void tpg_read(void) { - char buff[MAXTPGSTRINGSIZE + 1]; - waypoint *wpt_tmp; - double lat, lon, elev; - double amt; - short int pointcount; - - pointcount = gbfgetint16(tpg_file_in); - - /* the rest of the header */ - gbfread(&buff[0], 19, 1, tpg_file_in); - - if (valid_tpg_header(buff, 19) != 0) { - fatal(MYNAME ": input file does not appear to be a valid .TPG file.\n"); - } - - - while (pointcount--) { - wpt_tmp = waypt_new(); - - /* pascal-like shortname */ - wpt_tmp->shortname = gbfgetpstr(tpg_file_in); - - /* for some very odd reason, signs on longitude are swapped */ - /* coordinates are in NAD27/CONUS datum */ - - /* 8 bytes - longitude, sign swapped */ - lon = gbfgetdbl(tpg_file_in); - - /* 8 bytes - latitude */ - lat = gbfgetdbl(tpg_file_in); - - /* swap sign before we do datum conversions */ - lon *= -1.0; - - /* 2 bytes - elevation in feet */ - elev = FEET_TO_METERS(gbfgetint16(tpg_file_in)); - - /* convert incoming NAD27/CONUS coordinates to WGS84 */ - GPS_Math_Known_Datum_To_WGS84_M( - lat, - lon, - 0.0, - &wpt_tmp->latitude, - &wpt_tmp->longitude, - &amt, - tpg_datum_idx); - - wpt_tmp->altitude = elev; - - - /* 4 bytes? */ - (void) gbfgetint32(tpg_file_in); - - /* pascal-like description */ - wpt_tmp->description = gbfgetpstr(tpg_file_in); - - /* 2 bytes */ - (void) gbfgetint16(tpg_file_in); - - waypt_add(wpt_tmp); - } + char buff[MAXTPGSTRINGSIZE + 1]; + waypoint *wpt_tmp; + double lat, lon, elev; + double amt; + short int pointcount; + + pointcount = gbfgetint16(tpg_file_in); + + /* the rest of the header */ + gbfread(&buff[0], 19, 1, tpg_file_in); + + if (valid_tpg_header(buff, 19) != 0) { + fatal(MYNAME ": input file does not appear to be a valid .TPG file.\n"); + } + + + while (pointcount--) { + wpt_tmp = waypt_new(); + + /* pascal-like shortname */ + wpt_tmp->shortname = gbfgetpstr(tpg_file_in); + + /* for some very odd reason, signs on longitude are swapped */ + /* coordinates are in NAD27/CONUS datum */ + + /* 8 bytes - longitude, sign swapped */ + lon = gbfgetdbl(tpg_file_in); + + /* 8 bytes - latitude */ + lat = gbfgetdbl(tpg_file_in); + + /* swap sign before we do datum conversions */ + lon *= -1.0; + + /* 2 bytes - elevation in feet */ + elev = FEET_TO_METERS(gbfgetint16(tpg_file_in)); + + /* convert incoming NAD27/CONUS coordinates to WGS84 */ + GPS_Math_Known_Datum_To_WGS84_M( + lat, + lon, + 0.0, + &wpt_tmp->latitude, + &wpt_tmp->longitude, + &amt, + tpg_datum_idx); + + wpt_tmp->altitude = elev; + + + /* 4 bytes? */ + (void) gbfgetint32(tpg_file_in); + + /* pascal-like description */ + wpt_tmp->description = gbfgetpstr(tpg_file_in); + + /* 2 bytes */ + (void) gbfgetint16(tpg_file_in); + + waypt_add(wpt_tmp); + } } static void tpg_waypt_pr(const waypoint *wpt) { - double lon, lat; - double amt; - short int elev; - char tbuf[64]; - char c,ocount; - char *shortname; - char *description; - int i; - - /* these unknown 4 are probably point properties (color, icon, etc..) */ - unsigned char unknown4[] = { 0x78, 0x56, 0x34, 0x12 }; - - /* these 2 appear to be constant across test files */ - unsigned char unknown2[] = { 0x01, 0x80 }; - - /* our personal waypoint counter */ - waypt_out_count++; - - /* this output format pretty much requires a description - * and a shortname - */ - - if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { - if (wpt->description) { - if (global_opts.synthesize_shortnames) - shortname = mkshort_from_wpt(mkshort_handle, wpt); - else - shortname = xstrdup(wpt->description); - } else { - /* no description available */ - shortname = xstrdup(""); - } - } else{ - shortname = xstrdup(wpt->shortname); - } - - if (! wpt->description) { - if (shortname) { - description = xstrdup(shortname); - } else { - description = xstrdup(""); - } - } else{ - description = xstrdup(wpt->description); - } - - /* convert lat/long to NAD27/CONUS datum */ - GPS_Math_WGS84_To_Known_Datum_M( - wpt->latitude, - wpt->longitude, - 0.0, - &lat, - &lon, - &amt, - tpg_datum_idx); - - - /* swap the sign back *after* the datum conversion */ - lon *= -1.0; - - /* convert meters back to feets */ - elev = (short int) METERS_TO_FEET(wpt->altitude); - - /* 1 bytes stringsize for shortname */ - c = strlen(shortname); - ocount = 0; - /* - * It's reported the only legal characters are upper case - * A-Z and 0-9. Wow. We have to make two passes: one to - * count and one to output. - */ - for (i = 0; i < c; i++) { - char oc = toupper(shortname[i]); - if (isalnum(oc) || oc == ' ') { - ocount++; - } - } - - gbfwrite(&ocount, 1, 1, tpg_file_out); - - for (i = 0; i < c; i++) { - char oc = toupper(shortname[i]); - if (isalnum(oc) || oc == ' ') { - gbfputc(oc, tpg_file_out); - } - } - - /* 8 bytes - longitude */ - gbfputdbl(lon, tpg_file_out); - - /* 8 bytes - latitude */ - gbfputdbl(lat, tpg_file_out); - - /* 2 bytes - elevation_feet */ - gbfputint16(elev, tpg_file_out); - - /* 4 unknown bytes */ - memset(tbuf, '\0', sizeof(tbuf)); - gbfwrite(unknown4, 1, 4, tpg_file_out); - - /* pascal-like description */ - gbfputpstr(description, tpg_file_out); - - /* and finally 2 unknown bytes */ - - if (waypt_out_count == waypt_count()) { - /* last point gets 0x0000 instead of 0x0180 */ - gbfputint16(0, tpg_file_out); - } else { - gbfwrite(unknown2, 1, 2, tpg_file_out); - } - - xfree(shortname); - xfree(description); + double lon, lat; + double amt; + short int elev; + char tbuf[64]; + char c,ocount; + char *shortname; + char *description; + int i; + + /* these unknown 4 are probably point properties (color, icon, etc..) */ + unsigned char unknown4[] = { 0x78, 0x56, 0x34, 0x12 }; + + /* these 2 appear to be constant across test files */ + unsigned char unknown2[] = { 0x01, 0x80 }; + + /* our personal waypoint counter */ + waypt_out_count++; + + /* this output format pretty much requires a description + * and a shortname + */ + + if ((! wpt->shortname) || (global_opts.synthesize_shortnames)) { + if (wpt->description) { + if (global_opts.synthesize_shortnames) { + shortname = mkshort_from_wpt(mkshort_handle, wpt); + } else { + shortname = xstrdup(wpt->description); + } + } else { + /* no description available */ + shortname = xstrdup(""); + } + } else { + shortname = xstrdup(wpt->shortname); + } + + if (! wpt->description) { + if (shortname) { + description = xstrdup(shortname); + } else { + description = xstrdup(""); + } + } else { + description = xstrdup(wpt->description); + } + + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + wpt->latitude, + wpt->longitude, + 0.0, + &lat, + &lon, + &amt, + tpg_datum_idx); + + + /* swap the sign back *after* the datum conversion */ + lon *= -1.0; + + /* convert meters back to feets */ + elev = (short int) METERS_TO_FEET(wpt->altitude); + + /* 1 bytes stringsize for shortname */ + c = strlen(shortname); + ocount = 0; + /* + * It's reported the only legal characters are upper case + * A-Z and 0-9. Wow. We have to make two passes: one to + * count and one to output. + */ + for (i = 0; i < c; i++) { + char oc = toupper(shortname[i]); + if (isalnum(oc) || oc == ' ') { + ocount++; + } + } + + gbfwrite(&ocount, 1, 1, tpg_file_out); + + for (i = 0; i < c; i++) { + char oc = toupper(shortname[i]); + if (isalnum(oc) || oc == ' ') { + gbfputc(oc, tpg_file_out); + } + } + + /* 8 bytes - longitude */ + gbfputdbl(lon, tpg_file_out); + + /* 8 bytes - latitude */ + gbfputdbl(lat, tpg_file_out); + + /* 2 bytes - elevation_feet */ + gbfputint16(elev, tpg_file_out); + + /* 4 unknown bytes */ + memset(tbuf, '\0', sizeof(tbuf)); + gbfwrite(unknown4, 1, 4, tpg_file_out); + + /* pascal-like description */ + gbfputpstr(description, tpg_file_out); + + /* and finally 2 unknown bytes */ + + if (waypt_out_count == waypt_count()) { + /* last point gets 0x0000 instead of 0x0180 */ + gbfputint16(0, tpg_file_out); + } else { + gbfwrite(unknown2, 1, 2, tpg_file_out); + } + + xfree(shortname); + xfree(description); } static void tpg_write(void) { - int s; - unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, - 0x00, 0x43, 0x54, 0x6F, 0x70, - 0x6F, 0x57, 0x61, 0x79, 0x70, - 0x6F, 0x69, 0x6E, 0x74 }; + int s; + unsigned char header_bytes[] = { 0xFF, 0xFF, 0x01, 0x00, 0x0D, + 0x00, 0x43, 0x54, 0x6F, 0x70, + 0x6F, 0x57, 0x61, 0x79, 0x70, + 0x6F, 0x69, 0x6E, 0x74 + }; - s = waypt_count(); + s = waypt_count(); - if (global_opts.synthesize_shortnames) { - setshort_length(mkshort_handle, 32); - setshort_whitespace_ok(mkshort_handle, 1); - setshort_mustupper(mkshort_handle, 1); - } + if (global_opts.synthesize_shortnames) { + setshort_length(mkshort_handle, 32); + setshort_whitespace_ok(mkshort_handle, 1); + setshort_mustupper(mkshort_handle, 1); + } - if (s > MAXTPGOUTPUTPINS) { - fatal(MYNAME ": attempt to output too many points (%d). The max is %d. Sorry.\n", s, MAXTPGOUTPUTPINS); - } + if (s > MAXTPGOUTPUTPINS) { + fatal(MYNAME ": attempt to output too many points (%d). The max is %d. Sorry.\n", s, MAXTPGOUTPUTPINS); + } - /* write the waypoint count */ - gbfputint16(s, tpg_file_out); + /* write the waypoint count */ + gbfputint16(s, tpg_file_out); - /* write the rest of the header */ - gbfwrite(header_bytes, 1, 19, tpg_file_out); + /* write the rest of the header */ + gbfwrite(header_bytes, 1, 19, tpg_file_out); - waypt_disp_all(tpg_waypt_pr); + waypt_disp_all(tpg_waypt_pr); } ff_vecs_t tpg_vecs = { - ff_type_file, - FF_CAP_RW_WPT, - tpg_rd_init, - tpg_wr_init, - tpg_rd_deinit, - tpg_wr_deinit, - tpg_read, - tpg_write, - NULL, - tpg_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + FF_CAP_RW_WPT, + tpg_rd_init, + tpg_wr_init, + tpg_rd_deinit, + tpg_wr_deinit, + tpg_read, + tpg_write, + NULL, + tpg_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/tpo.c b/gpsbabel/tpo.c index 253e681ec..640f4943d 100644 --- a/gpsbabel/tpo.c +++ b/gpsbabel/tpo.c @@ -7,7 +7,7 @@ Topo! version 3.x: Reading of Tracks/Waypoints/Routes is implemented. Also extracts Map Notes/ Symbols/Text Labels as Waypoints. - + Copyright (C) 2005 Steve Chamberlin, slc at alum.mit.edu Portions Copyright (C) 2006 Curtis E. Mills, archer at eskimo dot com @@ -79,14 +79,14 @@ static char *dumpheader = NULL; static char *output_state = NULL; - + /* static arglist_t tpo2_args[] = { - { "dumpheader", &dumpheader, "Display the file header bytes", - "0", ARGTYPE_BOOL, ARG_NOMINMAX} , - { "state", &output_state, "State map format to write, default=CA", - "CA", ARGTYPE_STRING, ARG_NOMINMAX} , + { "dumpheader", &dumpheader, "Display the file header bytes", + "0", ARGTYPE_BOOL, ARG_NOMINMAX} , + { "state", &output_state, "State map format to write, default=CA", + "CA", ARGTYPE_STRING, ARG_NOMINMAX} , ARG_TERMINATOR }; */ @@ -99,12 +99,12 @@ arglist_t tpo2_args[] = { // static arglist_t tpo2_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static arglist_t tpo3_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; @@ -126,7 +126,7 @@ static double last_waypoint_z; /*******************************************************************************/ /* READ */ /*******************************************************************************/ - + /* Define a global here that we can query from multiple places */ float tpo_version = 0.0; @@ -136,38 +136,36 @@ static void tpo_check_version_string() { - unsigned char string_size; - char* string_buffer; - char* v3_id_string = "TOPO! Ver"; - - /* read the id string */ - gbfread(&string_size, 1, 1, tpo_file_in); - string_buffer = xmalloc(string_size+1); - gbfread(string_buffer, 1, string_size, tpo_file_in); - - /* terminate the string */ - string_buffer[string_size] = 0; - - /* check for the presence of a 3.0-style id string */ - if (strncmp(v3_id_string, string_buffer, strlen(v3_id_string)) == 0) - { -/* fatal(MYNAME ": gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); */ + unsigned char string_size; + char* string_buffer; + char* v3_id_string = "TOPO! Ver"; + + /* read the id string */ + gbfread(&string_size, 1, 1, tpo_file_in); + string_buffer = xmalloc(string_size+1); + gbfread(string_buffer, 1, string_size, tpo_file_in); + + /* terminate the string */ + string_buffer[string_size] = 0; + + /* check for the presence of a 3.0-style id string */ + if (strncmp(v3_id_string, string_buffer, strlen(v3_id_string)) == 0) { + /* fatal(MYNAME ": gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); */ //fprintf(stderr,"gpsbabel can only read TPO version 2.7.7 or below; this file is %s\n", string_buffer); - gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); - xfree(string_buffer); - tpo_version = 3.0; /* Really any 3.x version */ - return; - - } - else { - /* We found a version 1.x or 2.x file */ - /* seek back to the beginning of the file */ - gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); - xfree(string_buffer); - tpo_version = 2.0; /* Really any 1.x or 2.x version */ - return; - } + gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 3.0; /* Really any 3.x version */ + return; + + } else { + /* We found a version 1.x or 2.x file */ + /* seek back to the beginning of the file */ + gbfseek(tpo_file_in, -(string_size+1), SEEK_CUR); + xfree(string_buffer); + tpo_version = 2.0; /* Really any 1.x or 2.x version */ + return; + } } static void @@ -176,26 +174,29 @@ static void as a C array definition. */ tpo_dump_header_bytes(int header_size) { - int i; - unsigned char* buffer = (unsigned char*)xmalloc(header_size); - - gbfread(buffer, 1, header_size, tpo_file_in); - - printf("unsigned char header_bytes[] = {\n"); - - for (i=0; irte_name = xstrdup(buff); - - /* zoom level 1-5 visibility flags */ - gbfread(&buff[0], 1, 10, tpo_file_in); - - /* 8 bytes of zeros, meaning unknown */ - gbfread(&buff[0], 1, 8, tpo_file_in); - - /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ - gbfread(&buff[0], 1, 4, tpo_file_in); - - /* read the position of the initial track point */ - /* for some very odd reason, signs on longitude are swapped */ - /* coordinates are in NAD27/CONUS datum */ - - /* 8 bytes - longitude, sign swapped */ - first_lon = gbfgetdbl(tpo_file_in); - - /* 8 bytes - latitude */ - first_lat = gbfgetdbl(tpo_file_in); - - /* swap sign before we do datum conversions */ - first_lon *= -1.0; - - /* 8 unknown bytes: seems to be some kind of bounding box info */ - gbfread(&buff[0], 1, 8, tpo_file_in); - - /* number of route points */ - waypoint_count = gbfgetint16(tpo_file_in); - - /* allocate temporary memory for the waypoint deltas */ - lon_delta = (short*)xmalloc(waypoint_count * sizeof(short)); - lat_delta = (short*)xmalloc(waypoint_count * sizeof(short)); - - for (j=0; jlatitude, - &waypoint_temp->longitude, - &amt, - 78); - - /* there is no elevation data for the waypoints */ - waypoint_temp->altitude = 0; - - track_add_wpt(track_temp, waypoint_temp); - } - - /* free temporary memory */ - xfree(lon_delta); - xfree(lat_delta); - } + char buff[16]; + short track_count, waypoint_count; + double first_lat, first_lon, lat_scale, lon_scale, amt; + short *lon_delta, *lat_delta; + int i, j; + route_head* track_temp; + waypoint* waypoint_temp; + + /* track count */ + track_count = gbfgetint16(tpo_file_in); + + /*fprintf(stderr,"track_count:%d\n", track_count);*/ + + /* 4 unknown bytes */ + gbfread(&buff[0], 1, 4, tpo_file_in); + + /* chunk name: "CTopoRoute" */ + gbfread(&buff[0], 1, 12, tpo_file_in); + + for (i=0; irte_name = xstrdup(buff); + + /* zoom level 1-5 visibility flags */ + gbfread(&buff[0], 1, 10, tpo_file_in); + + /* 8 bytes of zeros, meaning unknown */ + gbfread(&buff[0], 1, 8, tpo_file_in); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + gbfread(&buff[0], 1, 4, tpo_file_in); + + /* read the position of the initial track point */ + /* for some very odd reason, signs on longitude are swapped */ + /* coordinates are in NAD27/CONUS datum */ + + /* 8 bytes - longitude, sign swapped */ + first_lon = gbfgetdbl(tpo_file_in); + + /* 8 bytes - latitude */ + first_lat = gbfgetdbl(tpo_file_in); + + /* swap sign before we do datum conversions */ + first_lon *= -1.0; + + /* 8 unknown bytes: seems to be some kind of bounding box info */ + gbfread(&buff[0], 1, 8, tpo_file_in); + + /* number of route points */ + waypoint_count = gbfgetint16(tpo_file_in); + + /* allocate temporary memory for the waypoint deltas */ + lon_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + lat_delta = (short*)xmalloc(waypoint_count * sizeof(short)); + + for (j=0; jlatitude, + &waypoint_temp->longitude, + &amt, + 78); + + /* there is no elevation data for the waypoints */ + waypoint_temp->altitude = 0; + + track_add_wpt(track_temp, waypoint_temp); + } + + /* free temporary memory */ + xfree(lon_delta); + xfree(lat_delta); + } } @@ -413,27 +409,27 @@ void tpo_read_2_x(void) // int tpo_read_int() { - unsigned char val; + unsigned char val; - val = (unsigned char) gbfgetc(tpo_file_in); + val = (unsigned char) gbfgetc(tpo_file_in); - switch (val) { + switch (val) { - case 0xff: // 32-bit value + case 0xff: // 32-bit value //printf("Found 32-bit value indicator: %x\n", val); - return( gbfgetint32(tpo_file_in) ); - break; + return(gbfgetint32(tpo_file_in)); + break; - case 0xfe: // 16-bit value + case 0xfe: // 16-bit value //printf("Found 16-bit value indicator: %x\n", val); - return( gbfgetuint16(tpo_file_in) ); - break; + return(gbfgetuint16(tpo_file_in)); + break; - default: // 8-bit value + default: // 8-bit value //printf("Found 8-bit value: %x\n", val); - return( (int)val ); - break; - } + return((int)val); + break; + } } @@ -453,31 +449,31 @@ int tpo_read_int() // int tpo_find_block(unsigned int block_desired) { - int block_type; - int block_offset; + int block_type; + int block_offset; - // Skip 512 byte fixed-length header - block_offset = 512; + // Skip 512 byte fixed-length header + block_offset = 512; - do { + do { - // Seek to offset from start of file - gbfseek(tpo_file_in, block_offset, SEEK_SET); - - // Read record type - block_type = gbfgetint32(tpo_file_in); + // Seek to offset from start of file + gbfseek(tpo_file_in, block_offset, SEEK_SET); + + // Read record type + block_type = gbfgetint32(tpo_file_in); //printf("Block: %08x\tat offset: %08x\n", block_type, block_offset); - // Read offset to next record - block_offset = gbfgetint32(tpo_file_in); - } - while (block_type != block_desired && block_offset != 0); + // Read offset to next record + block_offset = gbfgetint32(tpo_file_in); + } while (block_type != block_desired && block_offset != 0); - if (block_type == block_desired) - return(0); - else - return(-1); + if (block_type == block_desired) { + return(0); + } else { + return(-1); + } } @@ -488,42 +484,43 @@ int tpo_find_block(unsigned int block_desired) // // For version 3.x files. // -waypoint *tpo_convert_ll(int lat, int lon) { - double latitude; - double longitude; - waypoint *waypoint_temp; +waypoint *tpo_convert_ll(int lat, int lon) +{ + double latitude; + double longitude; + waypoint *waypoint_temp; - waypoint_temp = waypt_new(); + waypoint_temp = waypt_new(); - latitude = (double)lat / 0x800000; - longitude = (double)lon / 0x800000; + latitude = (double)lat / 0x800000; + longitude = (double)lon / 0x800000; //printf("lat: %f\tlon: %f\n", latitude, longitude); -/* - // Note: We shouldn't need this section of code as the version - // 3.x files are already in WGS84 datum. - // - // Convert incoming NAD27/CONUS coordinates to WGS84, Molodensky - // transform. - // - GPS_Math_Known_Datum_To_WGS84_M( - latitude, // Source latitude - longitude, // Source longitude - 0.0, // Source height (meters) - &waypoint_temp->latitude, // Dest latitude - &waypoint_temp->longitude, // Dest longitude - &height, // Dest height (meters) - 78); -*/ - - waypoint_temp->latitude = latitude; - waypoint_temp->longitude = longitude; + /* + // Note: We shouldn't need this section of code as the version + // 3.x files are already in WGS84 datum. + // + // Convert incoming NAD27/CONUS coordinates to WGS84, Molodensky + // transform. + // + GPS_Math_Known_Datum_To_WGS84_M( + latitude, // Source latitude + longitude, // Source longitude + 0.0, // Source height (meters) + &waypoint_temp->latitude, // Dest latitude + &waypoint_temp->longitude, // Dest longitude + &height, // Dest height (meters) + 78); + */ + + waypoint_temp->latitude = latitude; + waypoint_temp->longitude = longitude; //printf("lat: %f\tlon: %f\tNew Height: %f\n", waypoint_temp->latitude, waypoint_temp->longitude, height); - return(waypoint_temp); + return(waypoint_temp); } @@ -535,189 +532,190 @@ waypoint *tpo_convert_ll(int lat, int lon) { // void tpo_process_tracks(void) { - unsigned int track_count; - unsigned int ii; + unsigned int track_count; + unsigned int ii; //printf("Processing Tracks...\n"); - // Find block 0x060000 (free-hand routes) - if (tpo_find_block(0x060000)) - return; + // Find block 0x060000 (free-hand routes) + if (tpo_find_block(0x060000)) { + return; + } - // Read the number of tracks. Can be 8/16/32-bit value. - track_count = tpo_read_int(); + // Read the number of tracks. Can be 8/16/32-bit value. + track_count = tpo_read_int(); //printf("Total Tracks: %d\n", track_count); - if (track_count == 0) - return; - - // Read/process each track in the file - // - for (ii = 0; ii < track_count; ii++) { - unsigned int line_type; - unsigned int track_number; - unsigned int track_length; - unsigned int name_length; - char *track_name; - unsigned int track_byte_count; - int llvalid; - unsigned char *buf; - int lonscale; - int latscale; - int waypoint_count = 0; - int lat = 0; - int lon = 0; - unsigned int jj; - route_head* track_temp; - - - // Allocate the track struct - track_temp = route_head_alloc(); - track_add_head(track_temp); + if (track_count == 0) { + return; + } + + // Read/process each track in the file + // + for (ii = 0; ii < track_count; ii++) { + unsigned int line_type; + unsigned int track_number; + unsigned int track_length; + unsigned int name_length; + char *track_name; + unsigned int track_byte_count; + int llvalid; + unsigned char *buf; + int lonscale; + int latscale; + int waypoint_count = 0; + int lat = 0; + int lon = 0; + unsigned int jj; + route_head* track_temp; + + + // Allocate the track struct + track_temp = route_head_alloc(); + track_add_head(track_temp); //UNKNOWN DATA LENGTH - line_type = tpo_read_int(); + line_type = tpo_read_int(); - // Can be 8/16/32-bit value - track_number = tpo_read_int(); + // Can be 8/16/32-bit value + track_number = tpo_read_int(); - // Can be 8/16/32-bit value - track_length = tpo_read_int(); + // Can be 8/16/32-bit value + track_length = tpo_read_int(); -//UNKNOWN DATA LENGTH - name_length = tpo_read_int(); - - if (name_length) { - track_name = xmalloc(name_length+1); - track_name[0] = '\0'; - gbfread(track_name, 1, name_length, tpo_file_in); - track_name[name_length] = '\0'; // Terminator - } - else { // Assign a generic track name - track_name = xmalloc(15); - sprintf(track_name, "TRK %d", ii+1); - } - track_temp->rte_name = track_name; +//UNKNOWN DATA LENGTH + name_length = tpo_read_int(); + + if (name_length) { + track_name = xmalloc(name_length+1); + track_name[0] = '\0'; + gbfread(track_name, 1, name_length, tpo_file_in); + track_name[name_length] = '\0'; // Terminator + } else { // Assign a generic track name + track_name = xmalloc(15); + sprintf(track_name, "TRK %d", ii+1); + } + track_temp->rte_name = track_name; //printf("\nTrack Name: %s ", track_name); - // Route description + // Route description // track_temp->rte_desc = NULL; - // Route number - track_temp->rte_num = ii+1; + // Route number + track_temp->rte_num = ii+1; -//UNKNOWN DATA LENGTH - track_byte_count = tpo_read_int(); +//UNKNOWN DATA LENGTH + track_byte_count = tpo_read_int(); - // Read the number of bytes specified for the track. These - // contain scaling factors, long/lat's, and offsets from - // those long/lat's. First will be a long/lat (8 bytes). - // Keep track of the bytes as we go so that we know how many - // we've read. We need to do this so that we start at the - // proper place for the next track. + // Read the number of bytes specified for the track. These + // contain scaling factors, long/lat's, and offsets from + // those long/lat's. First will be a long/lat (8 bytes). + // Keep track of the bytes as we go so that we know how many + // we've read. We need to do this so that we start at the + // proper place for the next track. - // Read the track bytes into a buffer - buf = xmalloc(track_byte_count); - gbfread(buf, 1, track_byte_count, tpo_file_in); + // Read the track bytes into a buffer + buf = xmalloc(track_byte_count); + gbfread(buf, 1, track_byte_count, tpo_file_in); - latscale=0; - lonscale=0; + latscale=0; + lonscale=0; - // Process the track bytes - llvalid = 0; - for (jj = 0; jj < track_byte_count; ) { - waypoint* waypoint_temp; + // Process the track bytes + llvalid = 0; + for (jj = 0; jj < track_byte_count;) { + waypoint* waypoint_temp; - // Time to read a new latlong? - if (!llvalid) { + // Time to read a new latlong? + if (!llvalid) { - lon = le_read32(buf+jj); - jj+=4; + lon = le_read32(buf+jj); + jj+=4; - lat = le_read32(buf+jj); - jj+=4; + lat = le_read32(buf+jj); + jj+=4; //printf("L"); - // Peek to see if next is a lonscale. Note that it - // can begin with 0x88, which is confusing. Here we - // allow up to 16-bits of offset, so two of the - // bytes must be 0x00 for us to recognize it. - if(jj+3>4]; - lat+=latscale*scarray[(buf[jj]&0xf)]; -//printf("."); - jj++; + jj++; + llvalid = 0; + } - waypoint_temp = tpo_convert_ll(lat, lon); - route_add_wpt(track_temp, waypoint_temp); - waypoint_count++; - } + // Process the delta + else { + int scarray[] = {0,1,2,3,4,5,6,7,0,-7,-6,-5,-4,-3,-2,-1}; + + + if (buf[jj] == 0) { + printf("Found unexpected ZERO\n"); + exit(1); + } + + if (latscale == 0 || lonscale == 0) { + printf("Found bad scales lonscale=0x%x latscale=0x%x\n", lonscale, latscale); + exit(1); } - track_temp->rte_waypt_ct = waypoint_count; - - xfree(buf); + + lon+=lonscale*scarray[buf[jj]>>4]; + lat+=latscale*scarray[(buf[jj]&0xf)]; +//printf("."); + jj++; + + waypoint_temp = tpo_convert_ll(lat, lon); + route_add_wpt(track_temp, waypoint_temp); + waypoint_count++; + } } + track_temp->rte_waypt_ct = waypoint_count; + + xfree(buf); + } //printf("\n"); } @@ -732,7 +730,7 @@ void tpo_process_tracks(void) // waypoint** tpo_wp_index; unsigned int tpo_index_ptr = 0; - + @@ -741,128 +739,129 @@ unsigned int tpo_index_ptr = 0; // void tpo_process_waypoints(void) { - unsigned int waypoint_count; - unsigned int ii; - + unsigned int waypoint_count; + unsigned int ii; + //printf("Processing Waypoints...\n"); - // Find block 0x0e0000 (GPS-Waypoints) - if (tpo_find_block(0x0e0000)) - return; + // Find block 0x0e0000 (GPS-Waypoints) + if (tpo_find_block(0x0e0000)) { + return; + } - // Read the number of waypoints. 8/16/32-bit value. - waypoint_count = tpo_read_int(); + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); //printf("Total Waypoints: %d\n", waypoint_count); - // Fetch storage for the waypoint index (needed later for - // routes) - tpo_wp_index = (waypoint **)xmalloc(sizeof(waypoint *) * waypoint_count); + // Fetch storage for the waypoint index (needed later for + // routes) + tpo_wp_index = (waypoint **)xmalloc(sizeof(waypoint *) * waypoint_count); + + if (waypoint_count == 0) { + return; + } + + // Read/process each waypoint in the file + for (ii = 0; ii < waypoint_count; ii++) { + waypoint* waypoint_temp; + waypoint* waypoint_temp2; + unsigned int name_length; + char *waypoint_name; + int lat; + int lon; + int altitude; - if (waypoint_count == 0) - return; - // Read/process each waypoint in the file - for (ii = 0; ii < waypoint_count; ii++) { - waypoint* waypoint_temp; - waypoint* waypoint_temp2; - unsigned int name_length; - char *waypoint_name; - int lat; - int lon; - int altitude; - - //UNKNOWN DATA LENGTH - (void)tpo_read_int(); // 0x00 + (void)tpo_read_int(); // 0x00 //UNKNOWN DATA LENGTH - (void)tpo_read_int(); // 0x00 + (void)tpo_read_int(); // 0x00 //UNKNOWN DATA LENGTH - // Fetch name length - name_length = tpo_read_int(); + // Fetch name length + name_length = tpo_read_int(); //printf("\nName Length: %d\n", name_length); - if (name_length) { - waypoint_name = xmalloc(name_length+1); - waypoint_name[0] = '\0'; - gbfread(waypoint_name, 1, name_length, tpo_file_in); - waypoint_name[name_length] = '\0'; // Terminator - } - else { // Assign a generic waypoint name - waypoint_name = xmalloc(15); - sprintf(waypoint_name, "WPT %d", ii+1); - } + if (name_length) { + waypoint_name = xmalloc(name_length+1); + waypoint_name[0] = '\0'; + gbfread(waypoint_name, 1, name_length, tpo_file_in); + waypoint_name[name_length] = '\0'; // Terminator + } else { // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "WPT %d", ii+1); + } //printf("\tWaypoint Name: %s\n", waypoint_name); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - lon = gbfgetint32(tpo_file_in); - lat = gbfgetint32(tpo_file_in); + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); - // Allocate space for waypoint and store lat/lon - waypoint_temp = tpo_convert_ll(lat, lon); + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); - // Assign the waypoint name - waypoint_temp->shortname = waypoint_name; + // Assign the waypoint name + waypoint_temp->shortname = waypoint_name; - // Grab the altitude in meters - altitude = gbfgetint32(tpo_file_in); - if (altitude == 0xfffd000c) // Unknown altitude - altitude = 0; - waypoint_temp->altitude = altitude / 100; // Meters + // Grab the altitude in meters + altitude = gbfgetint32(tpo_file_in); + if (altitude == 0xfffd000c) { // Unknown altitude + altitude = 0; + } + waypoint_temp->altitude = altitude / 100; // Meters //printf("\tAltitude: %1.0f meters\n", waypoint_temp->altitude); //UNKNOWN DATA LENGTH - // Fetch comment length - name_length = tpo_read_int(); -//printf("\tComment length: %d\n", name_length); - if (name_length) { - char *comment; - - comment = xmalloc(name_length+1); - comment[0] = '\0'; - gbfread(comment, 1, name_length, tpo_file_in); - comment[name_length] = '\0'; // Terminator - waypoint_temp->description = comment; + // Fetch comment length + name_length = tpo_read_int(); +//printf("\tComment length: %d\n", name_length); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; //printf("\tComment: %s\n", waypoint_name); - } - else { + } else { // waypoint_temp->description = NULL; - } + } // waypoint_temp->notes = NULL; // waypoint_temp->url = NULL; // waypoint_temp->url_link_text = NULL; - - // For routes (later), we need a duplicate of each waypoint - // indexed by the order we read them in. - waypoint_temp2 = waypt_dupe(waypoint_temp); - // Attach the copy to our index - tpo_wp_index[tpo_index_ptr++] = waypoint_temp2; + // For routes (later), we need a duplicate of each waypoint + // indexed by the order we read them in. + waypoint_temp2 = waypt_dupe(waypoint_temp); - // Add the original waypoint to the chain of waypoints - waypt_add(waypoint_temp); + // Attach the copy to our index + tpo_wp_index[tpo_index_ptr++] = waypoint_temp2; + + // Add the original waypoint to the chain of waypoints + waypt_add(waypoint_temp); //UNKNOWN DATA LENGTH // (void)tpo_read_int(); - (void) gbfgetc(tpo_file_in); + (void) gbfgetc(tpo_file_in); //UNKNOWN DATA LENGTH // (void)tpo_read_int(); - (void) gbfgetc(tpo_file_in); + (void) gbfgetc(tpo_file_in); //UNKNOWN DATA LENGTH // (void)tpo_read_int(); - (void) gbfgetc(tpo_file_in); + (void) gbfgetc(tpo_file_in); //UNKNOWN DATA LENGTH // (void)tpo_read_int(); - (void) gbfgetc(tpo_file_in); - } + (void) gbfgetc(tpo_file_in); + } } @@ -873,134 +872,133 @@ void tpo_process_waypoints(void) // void tpo_process_map_notes(void) { - unsigned int waypoint_count; - unsigned int ii; - + unsigned int waypoint_count; + unsigned int ii; + //printf("Processing Map Notes...\n"); - // Find block 0x090000 (Map Notes) - if (tpo_find_block(0x090000)) { - return; - } + // Find block 0x090000 (Map Notes) + if (tpo_find_block(0x090000)) { + return; + } - // Read the number of waypoints. 8/16/32-bit value. - waypoint_count = tpo_read_int(); + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); //printf("Elements: %d\n", waypoint_count); - if (!waypoint_count) { - return; - } + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; + unsigned int num_bytes; + unsigned int jj; + - // Process each waypoint - for (ii = 0; ii < waypoint_count; ii++) { - int lat; - int lon; - unsigned int name_length; - char *waypoint_name; - waypoint* waypoint_temp; - unsigned int num_bytes; - unsigned int jj; - - //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - lon = gbfgetint32(tpo_file_in); - lat = gbfgetint32(tpo_file_in); + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); - // Allocate space for waypoint and store lat/lon - waypoint_temp = tpo_convert_ll(lat, lon); + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); - // Assign a generic waypoint name - waypoint_name = xmalloc(15); - sprintf(waypoint_name, "NOTE %d", ii+1); + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "NOTE %d", ii+1); //printf("Waypoint Name: %s\t\t", waypoint_name); - waypoint_temp->shortname = waypoint_name; + waypoint_temp->shortname = waypoint_name; //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - // Fetch comment length - name_length = tpo_read_int(); - if (name_length) { - char *comment; - - comment = xmalloc(name_length+1); - comment[0] = '\0'; - gbfread(comment, 1, name_length, tpo_file_in); - comment[name_length] = '\0'; // Terminator - waypoint_temp->description = comment; + // Fetch comment length + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; //printf("Comment: %s\n", comment); - } - else { + } else { // waypoint_temp->description = NULL; - } + } // waypoint_temp->url_link_text = NULL; - // Length of text for external path. If non-zero, skip past - // the text. + // Length of text for external path. If non-zero, skip past + // the text. //UNKNOWN DATA LENGTH - name_length = tpo_read_int(); + name_length = tpo_read_int(); //printf("name_length: %x\n", name_length); - if (name_length) { - char *notes; - - notes = xmalloc(name_length+1); - notes[0] = '\0'; - gbfread(notes, 1, name_length, tpo_file_in); - notes[name_length] = '\0'; // Terminator - waypoint_temp->url = notes; + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + gbfread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; //printf("Notes: %s\n", notes); - } + } - // Length of text for image path. If non-zero, skip past - // the text. + // Length of text for image path. If non-zero, skip past + // the text. //UNKNOWN DATA LENGTH - name_length = tpo_read_int(); - if (name_length) { - char *notes; - - notes = xmalloc(name_length+1); - notes[0] = '\0'; - gbfread(notes, 1, name_length, tpo_file_in); - notes[name_length] = '\0'; // Terminator - waypoint_temp->url = notes; + name_length = tpo_read_int(); + if (name_length) { + char *notes; + + notes = xmalloc(name_length+1); + notes[0] = '\0'; + gbfread(notes, 1, name_length, tpo_file_in); + notes[name_length] = '\0'; // Terminator + waypoint_temp->url = notes; //printf("Notes: %s\n", notes); - } + } //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - // Number of bytes to skip until next element or end of - // block. May be 8/16/32 bits. - num_bytes = tpo_read_int(); + // Number of bytes to skip until next element or end of + // block. May be 8/16/32 bits. + num_bytes = tpo_read_int(); //printf("num_bytes: %x\n", num_bytes); - for (jj = 0; jj < num_bytes; jj++) { - (void) gbfgetc(tpo_file_in); // Skip bytes - } + for (jj = 0; jj < num_bytes; jj++) { + (void) gbfgetc(tpo_file_in); // Skip bytes + } - // Can be 8/16/32 bits - (void)tpo_read_int(); + // Can be 8/16/32 bits + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - // Add the waypoint to the chain of waypoints - waypt_add(waypoint_temp); - } + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } } @@ -1011,59 +1009,60 @@ void tpo_process_map_notes(void) // void tpo_process_symbols(void) { - unsigned int waypoint_count; - unsigned int ii; + unsigned int waypoint_count; + unsigned int ii; + - //printf("Processing Symbols...\n"); - // Find block 0x040000 (Symbols) - if (tpo_find_block(0x040000)) - return; + // Find block 0x040000 (Symbols) + if (tpo_find_block(0x040000)) { + return; + } - // Read the number of waypoints. 8/16/32-bit value. - waypoint_count = tpo_read_int(); + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); //printf("Elements: %d\n", waypoint_count); - if (!waypoint_count) { - return; - } + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int lat; + int lon; + char *waypoint_name; + waypoint* waypoint_temp; - // Process each waypoint - for (ii = 0; ii < waypoint_count; ii++) { - int lat; - int lon; - char *waypoint_name; - waypoint* waypoint_temp; - //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - lon = gbfgetint32(tpo_file_in); - lat = gbfgetint32(tpo_file_in); + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); - // Allocate space for waypoint and store lat/lon - waypoint_temp = tpo_convert_ll(lat, lon); + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); - // Assign a generic waypoint name - waypoint_name = xmalloc(15); - sprintf(waypoint_name, "SYM %d", ii+1); + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "SYM %d", ii+1); //printf("Waypoint Name: %s\n", waypoint_name); - waypoint_temp->shortname = waypoint_name; + waypoint_temp->shortname = waypoint_name; // waypoint_temp->description = NULL; // waypoint_temp->notes = NULL; // waypoint_temp->url = NULL; // waypoint_temp->url_link_text = NULL; - // Add the waypoint to the chain of waypoints - waypt_add(waypoint_temp); - } + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } } @@ -1074,82 +1073,82 @@ void tpo_process_symbols(void) // void tpo_process_text_labels(void) { - unsigned int waypoint_count; - unsigned int ii; + unsigned int waypoint_count; + unsigned int ii; + - //printf("Processing Text Labels...\n"); - // Find block 0x080000 (Text Labels) - if (tpo_find_block(0x080000)) - return; + // Find block 0x080000 (Text Labels) + if (tpo_find_block(0x080000)) { + return; + } - // Read the number of waypoints. 8/16/32-bit value. - waypoint_count = tpo_read_int(); + // Read the number of waypoints. 8/16/32-bit value. + waypoint_count = tpo_read_int(); //printf("Elements: %d\n", waypoint_count); - if (!waypoint_count) { - return; - } + if (!waypoint_count) { + return; + } + + // Process each waypoint + for (ii = 0; ii < waypoint_count; ii++) { + int jj; + int lat; + int lon; + unsigned int name_length; + char *waypoint_name; + waypoint* waypoint_temp; - // Process each waypoint - for (ii = 0; ii < waypoint_count; ii++) { - int jj; - int lat; - int lon; - unsigned int name_length; - char *waypoint_name; - waypoint* waypoint_temp; - //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); + (void)tpo_read_int(); - lon = gbfgetint32(tpo_file_in); - lat = gbfgetint32(tpo_file_in); + lon = gbfgetint32(tpo_file_in); + lat = gbfgetint32(tpo_file_in); - // Allocate space for waypoint and store lat/lon - waypoint_temp = tpo_convert_ll(lat, lon); + // Allocate space for waypoint and store lat/lon + waypoint_temp = tpo_convert_ll(lat, lon); - // Assign a generic waypoint name - waypoint_name = xmalloc(15); - sprintf(waypoint_name, "TXT %d", ii+1); + // Assign a generic waypoint name + waypoint_name = xmalloc(15); + sprintf(waypoint_name, "TXT %d", ii+1); //printf("Waypoint Name: %s\t\t", waypoint_name); - waypoint_temp->shortname = waypoint_name; + waypoint_temp->shortname = waypoint_name; - for (jj = 0; jj < 16; jj++) { + for (jj = 0; jj < 16; jj++) { //UNKNOWN DATA LENGTH - (void) gbfgetc(tpo_file_in); - } + (void) gbfgetc(tpo_file_in); + } - // Fetch comment length + // Fetch comment length //UNKNOWN DATA LENGTH - name_length = tpo_read_int(); - if (name_length) { - char *comment; - - comment = xmalloc(name_length+1); - comment[0] = '\0'; - gbfread(comment, 1, name_length, tpo_file_in); - comment[name_length] = '\0'; // Terminator - waypoint_temp->description = comment; + name_length = tpo_read_int(); + if (name_length) { + char *comment; + + comment = xmalloc(name_length+1); + comment[0] = '\0'; + gbfread(comment, 1, name_length, tpo_file_in); + comment[name_length] = '\0'; // Terminator + waypoint_temp->description = comment; //printf("Comment: %s\n", comment); - } - else { + } else { // waypoint_temp->description = NULL; - } + } // waypoint_temp->notes = NULL; // waypoint_temp->url = NULL; // waypoint_temp->url_link_text = NULL; - // Add the waypoint to the chain of waypoints - waypt_add(waypoint_temp); - } + // Add the waypoint to the chain of waypoints + waypt_add(waypoint_temp); + } } @@ -1164,107 +1163,110 @@ void tpo_process_text_labels(void) // void tpo_process_routes(void) { - unsigned int route_count; - unsigned int ii; - + unsigned int route_count; + unsigned int ii; + //printf("Processing Routes...\n"); - // Find block 0x0f0000 (GPS-Routes) - if (tpo_find_block(0x0f0000)) - return; + // Find block 0x0f0000 (GPS-Routes) + if (tpo_find_block(0x0f0000)) { + return; + } - // Read the number of routes. 8/16/32-bit value - route_count = tpo_read_int(); + // Read the number of routes. 8/16/32-bit value + route_count = tpo_read_int(); //printf("Total Routes: %d\n", route_count); - if (route_count == 0) - return; + if (route_count == 0) { + return; + } - // Read/process each route in the file - // - for (ii = 0; ii < route_count; ii++) { - unsigned int name_length = 0; - char *route_name; - unsigned int jj; - unsigned int waypoint_cnt; - route_head* route_temp; + // Read/process each route in the file + // + for (ii = 0; ii < route_count; ii++) { + unsigned int name_length = 0; + char *route_name; + unsigned int jj; + unsigned int waypoint_cnt; + route_head* route_temp; - // Allocate the route struct - route_temp = route_head_alloc(); - route_add_head(route_temp); + // Allocate the route struct + route_temp = route_head_alloc(); + route_add_head(route_temp); //UNKNOWN DATA LENGTH - (void)tpo_read_int(); - + (void)tpo_read_int(); + //UNKNOWN DATA LENGTH - (void)tpo_read_int(); - + (void)tpo_read_int(); + //UNKNOWN DATA LENGTH - // Fetch name length - name_length = tpo_read_int(); - if (name_length) { - route_name = xmalloc(name_length+1); - route_name[0] = '\0'; - gbfread(route_name, 1, name_length, tpo_file_in); - route_name[name_length] = '\0'; // Terminator - } - else { // Assign a generic route name - route_name = xmalloc(15); - sprintf(route_name, "RTE %d", ii+1); - } - route_temp->rte_name = route_name; + // Fetch name length + name_length = tpo_read_int(); + if (name_length) { + route_name = xmalloc(name_length+1); + route_name[0] = '\0'; + gbfread(route_name, 1, name_length, tpo_file_in); + route_name[name_length] = '\0'; // Terminator + } else { // Assign a generic route name + route_name = xmalloc(15); + sprintf(route_name, "RTE %d", ii+1); + } + route_temp->rte_name = route_name; //printf("Route Name: %s\n", route_name); -//UNKNOWN DATA LENGTH - // Comment? - (void)tpo_read_int(); +//UNKNOWN DATA LENGTH + // Comment? + (void)tpo_read_int(); // gbfgetc(tpo_file_in); // route_temp->rte_desc = NULL; - route_temp->rte_num = ii+1; + route_temp->rte_num = ii+1; - // Fetch the number of waypoints in this route. 8/16/32-bit - // value. - waypoint_cnt = tpo_read_int(); + // Fetch the number of waypoints in this route. 8/16/32-bit + // value. + waypoint_cnt = tpo_read_int(); - route_temp->rte_waypt_ct = waypoint_cnt; + route_temp->rte_waypt_ct = waypoint_cnt; - // Run through the list of waypoints, look up each in our - // index, then add the waypoint to this route. - // - for (jj = 0; jj < waypoint_cnt; jj++) { - waypoint* waypoint_temp; - unsigned char val; + // Run through the list of waypoints, look up each in our + // index, then add the waypoint to this route. + // + for (jj = 0; jj < waypoint_cnt; jj++) { + waypoint* waypoint_temp; + unsigned char val; //UNKNOWN DATA LENGTH - // Fetch the index to the waypoint - val = tpo_read_int(); + // Fetch the index to the waypoint + val = tpo_read_int(); //printf("val: %x\t\t", val); - // Duplicate a waypoint from our index of waypoints. - waypoint_temp = waypt_dupe(tpo_wp_index[val-1]); + // Duplicate a waypoint from our index of waypoints. + waypoint_temp = waypt_dupe(tpo_wp_index[val-1]); - // Add the waypoint to the route - route_add_wpt(route_temp, waypoint_temp); - } -//printf("\n"); + // Add the waypoint to the route + route_add_wpt(route_temp, waypoint_temp); } +//printf("\n"); + } - // Free the waypoint index, we don't need it anymore. - for (ii = 0; ii < tpo_index_ptr; ii++) { - if (tpo_wp_index[ii]->shortname) - xfree(tpo_wp_index[ii]->shortname); - if (tpo_wp_index[ii]->description) - xfree(tpo_wp_index[ii]->description); - xfree(tpo_wp_index[ii]); + // Free the waypoint index, we don't need it anymore. + for (ii = 0; ii < tpo_index_ptr; ii++) { + if (tpo_wp_index[ii]->shortname) { + xfree(tpo_wp_index[ii]->shortname); } + if (tpo_wp_index[ii]->description) { + xfree(tpo_wp_index[ii]->description); + } + xfree(tpo_wp_index[ii]); + } - // Free the index array itself - xfree(tpo_wp_index); + // Free the index array itself + xfree(tpo_wp_index); } @@ -1276,7 +1278,7 @@ void tpo_process_routes(void) void tpo_process_compass(void) { - // Not implemented yet + // Not implemented yet } @@ -1290,46 +1292,46 @@ void tpo_process_compass(void) void tpo_read_3_x(void) { - if (doing_trks) { + if (doing_trks) { //printf("Processing Tracks\n"); - tpo_process_tracks(); - } + tpo_process_tracks(); + } - if (doing_wpts || doing_rtes) { + if (doing_wpts || doing_rtes) { //printf("Processing Waypoints\n"); - tpo_process_waypoints(); - } + tpo_process_waypoints(); + } - if (doing_rtes) { - // - // Note: To process routes we _MUST_ process waypoints - // first! This creates the index of waypoints that we need - // for routes. - // + if (doing_rtes) { + // + // Note: To process routes we _MUST_ process waypoints + // first! This creates the index of waypoints that we need + // for routes. + // //printf("Processing Routes\n"); - tpo_process_routes(); - } + tpo_process_routes(); + } - if (doing_wpts) { - // - // Other blocks in the file have waypoint-type information - // in them. Map Notes, Symbols, and Text Labels. We - // process those here and add them to the end of the - // waypoint list. - // + if (doing_wpts) { + // + // Other blocks in the file have waypoint-type information + // in them. Map Notes, Symbols, and Text Labels. We + // process those here and add them to the end of the + // waypoint list. + // //printf("Processing Map Notes\n"); - tpo_process_map_notes(); + tpo_process_map_notes(); //printf("Processing Symbols\n"); - tpo_process_symbols(); + tpo_process_symbols(); //printf("Processing Text Labels\n"); - tpo_process_text_labels(); + tpo_process_text_labels(); //printf("Processing Compass Symbols\n"); // tpo_process_compass(); - } + } } @@ -1347,17 +1349,15 @@ static void tpo_read(void) { - if (tpo_version == 2.0) { + if (tpo_version == 2.0) { //printf("\nFound a version 2.x file\n"); - tpo_read_2_x(); - } - else if (tpo_version == 3.0) { + tpo_read_2_x(); + } else if (tpo_version == 3.0) { //printf("\nFound a version 3.x file\n"); - tpo_read_3_x(); - } - else { - fatal(MYNAME ": gpsbabel can only read TPO versions through 3.x.x\n"); - } + tpo_read_3_x(); + } else { + fatal(MYNAME ": gpsbabel can only read TPO versions through 3.x.x\n"); + } } @@ -1369,15 +1369,15 @@ tpo_read(void) /*******************************************************************************/ /* tpo_write_file_header() - Write the appropriate header for the desired TOPO! state. - - National Geographic sells about 75 different state and regional software - programs called TOPO! that use the TPO format. Each one uses a different - header data sequence. The header contains the name of the state maps, as well + Write the appropriate header for the desired TOPO! state. + + National Geographic sells about 75 different state and regional software + programs called TOPO! that use the TPO format. Each one uses a different + header data sequence. The header contains the name of the state maps, as well as some map scaling information and other data. In most cases, you can't open a TPO file created by a different state/regional version of TOPO! than the one - you're using yourself. When writing a TPO file, it is therefore necessary to - specify what TOPO! state product to create the file for. I believe that the + you're using yourself. When writing a TPO file, it is therefore necessary to + specify what TOPO! state product to create the file for. I believe that the TOPO! regional products can open TPO files created by the TOPO! state products as long as the track data is within the area covered by the regional product. As a result, it's only necessary to decide what state product output format to @@ -1385,13 +1385,13 @@ tpo_read(void) TO ADD SUPPORT FOR ANOTHER STATE: 1. Obtain an example .tpo file generated by the state product for which you wish - to add support. National Geographic MapXchange (http://maps.nationalgeographic.com/topo/search.cfm) + to add support. National Geographic MapXchange (http://maps.nationalgeographic.com/topo/search.cfm) is a good source of .tpo files. 2. Run gpsbabel using the "dumpheader" option of the TPO format converter, and specifying a dummy output file. For example: gpsbabel -t -i tpo,dumpheader=1 -f sample_file.tpo -o csv -F dummy.txt - This will write a snippet of C code containing the header bytes to the shell window. - 3. Add a new if() clause to tpo_write_file_header(). Copy the header bytes definition + This will write a snippet of C code containing the header bytes to the shell window. + 3. Add a new if() clause to tpo_write_file_header(). Copy the header bytes definition from the previous step. 4. Recompile gpsbabel. 5. You should now be able write TPO ouput in the new state's format. For example, if @@ -1400,461 +1400,459 @@ tpo_read(void) static void tpo_write_file_header() { - /* force upper-case state name */ - strupper(output_state); - - if (strncmp("CA", output_state, 2) == 0) { - - unsigned char header_bytes[] = { - 0x18, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, - 0x6E, 0x69, 0x61, 0x20, 0x53, 0x68, 0x61, 0x64, - 0x65, 0x64, 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, - 0x66, 0x03, 0x43, 0x41, 0x31, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x27, 0x43, 0x3A, 0x5C, - 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, - 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, - 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, - 0x44, 0x41, 0x54, 0x41, 0x5C, 0x43, 0x41, 0x5F, - 0x44, 0x30, 0x31, 0x5C, 0x20, 0x43, 0x3A, 0x5C, - 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, - 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, - 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, - 0x44, 0x41, 0x54, 0x41, 0x5C, 0x12, 0x43, 0x3A, - 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, 0x54, - 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5C, - 0x00, 0x00, 0x00, 0xDC, 0x30, 0x32, 0x30, 0x32, - 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, - 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, - 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x35, 0x30, 0x35, 0x30, 0x34, 0x30, 0x36, - 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, - 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, - 0x30, 0x37, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, - 0x30, 0x35, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, - 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, - 0x31, 0x30, 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, - 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, - 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, - 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, - 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, - 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, - 0x31, 0x31, 0x31, 0x31, 0x30, 0x39, 0x30, 0x39, - 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0xBC, 0x23, - 0x63, 0xB5, 0xF9, 0x3A, 0x50, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, 0x22, 0xE2, - 0xE6, 0x54, 0x32, 0x28, 0x22, 0x40, 0x0A, 0x43, - 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, - 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, - 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, - 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x43, 0x41, 0x31, - 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, - 0x4C, 0xAF, 0x02, 0x15, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x24, 0x40, 0x84, 0x00, 0x78, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, - 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, - 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, - 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, - 0x0D, 0x00, 0x02, 0x44, 0x41, 0x23, 0x01, 0x6C, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, - 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, - 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, - 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, - 0x02, 0x44, 0x46, 0x00, 0x01, 0x40, 0x01, 0xB5, - 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, - 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, - 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, - 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, - 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, - 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, - 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, - 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, - 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, - 0x00, 0x01, 0x00, 0x28, 0x00 - }; - - gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); - } - else if (strncmp("CT", output_state, 2) == 0 || - strncmp("MA", output_state, 2) == 0 || - strncmp("ME", output_state, 2) == 0 || - strncmp("NJ", output_state, 2) == 0 || - strncmp("NH", output_state, 2) == 0 || - strncmp("NY", output_state, 2) == 0 || - strncmp("RI", output_state, 2) == 0 || - strncmp("VT", output_state, 2) == 0) { - /* These 8 states are all covered in a single "Northeast" title */ - - unsigned char header_bytes[] = { - 0x1E, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, - 0x41, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x64, - 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, 0x66, 0x03, - 0x4E, 0x45, 0x31, 0x05, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x48, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x50, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x0B, 0x44, 0x3A, 0x5C, 0x4E, 0x45, - 0x31, 0x5F, 0x44, 0x30, 0x31, 0x5C, 0x12, 0x43, - 0x3A, 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, - 0x54, 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, - 0x5C, 0x12, 0x45, 0x3A, 0x5C, 0x54, 0x4F, 0x50, - 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, 0x44, - 0x41, 0x54, 0x41, 0x5C, 0x00, 0x00, 0x00, 0xFF, - 0x18, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, - 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x34, - 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, - 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x33, - 0x30, 0x34, 0x30, 0x34, 0x30, 0x35, 0x30, 0x35, - 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, - 0x30, 0x36, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, - 0x30, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x34, - 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x36, - 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, - 0x30, 0x32, 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, - 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, - 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, - 0x30, 0x33, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, - 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, - 0x31, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, - 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x4E, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, - 0x10, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, - 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x48, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, - 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, - 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, - 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, - 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x4E, 0x45, 0x31, - 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, - 0x4C, 0x68, 0x03, 0x16, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x24, 0x40, 0x8C, 0x00, 0x64, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, - 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, - 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, - 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, - 0x0D, 0x00, 0x02, 0x44, 0x41, 0x0B, 0x01, 0x6C, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, - 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, - 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, - 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, - 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, - 0x02, 0x44, 0x46, 0xEA, 0x00, 0x40, 0x01, 0xB5, - 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, - 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, - 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, - 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, - 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, - 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, - 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, - 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, - 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, - 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, - 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, - 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, - 0x00, 0x01, 0x00, 0x28, 0x00 - }; - - gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); - } - - else { - fatal(MYNAME ": writing ouput for state \"%s\" is not currently supported.\n", output_state); - } + /* force upper-case state name */ + strupper(output_state); + + if (strncmp("CA", output_state, 2) == 0) { + + unsigned char header_bytes[] = { + 0x18, 0x43, 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, + 0x6E, 0x69, 0x61, 0x20, 0x53, 0x68, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, + 0x66, 0x03, 0x43, 0x41, 0x31, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x27, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x43, 0x41, 0x5F, + 0x44, 0x30, 0x31, 0x5C, 0x20, 0x43, 0x3A, 0x5C, + 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x20, + 0x46, 0x69, 0x6C, 0x65, 0x73, 0x5C, 0x54, 0x4F, + 0x50, 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, + 0x44, 0x41, 0x54, 0x41, 0x5C, 0x12, 0x43, 0x3A, + 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, 0x54, + 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, 0x5C, + 0x00, 0x00, 0x00, 0xDC, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x34, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x30, 0x35, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, + 0x31, 0x30, 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, + 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, + 0x31, 0x31, 0x31, 0x31, 0x30, 0x39, 0x30, 0x39, + 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, 0x64, 0x20, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, 0xBC, 0x23, + 0x63, 0xB5, 0xF9, 0x3A, 0x50, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, 0x22, 0xE2, + 0xE6, 0x54, 0x32, 0x28, 0x22, 0x40, 0x0A, 0x43, + 0x61, 0x6C, 0x69, 0x66, 0x6F, 0x72, 0x6E, 0x69, + 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5C, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x43, 0x41, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0xAF, 0x02, 0x15, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x26, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x84, 0x00, 0x78, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x23, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0x00, 0x01, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } else if (strncmp("CT", output_state, 2) == 0 || + strncmp("MA", output_state, 2) == 0 || + strncmp("ME", output_state, 2) == 0 || + strncmp("NJ", output_state, 2) == 0 || + strncmp("NH", output_state, 2) == 0 || + strncmp("NY", output_state, 2) == 0 || + strncmp("RI", output_state, 2) == 0 || + strncmp("VT", output_state, 2) == 0) { + /* These 8 states are all covered in a single "Northeast" title */ + + unsigned char header_bytes[] = { + 0x1E, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x64, + 0x20, 0x52, 0x65, 0x6C, 0x69, 0x65, 0x66, 0x03, + 0x4E, 0x45, 0x31, 0x05, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x48, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x50, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0B, 0x44, 0x3A, 0x5C, 0x4E, 0x45, + 0x31, 0x5F, 0x44, 0x30, 0x31, 0x5C, 0x12, 0x43, + 0x3A, 0x5C, 0x54, 0x4F, 0x50, 0x4F, 0x21, 0x5C, + 0x54, 0x50, 0x4F, 0x5F, 0x44, 0x41, 0x54, 0x41, + 0x5C, 0x12, 0x45, 0x3A, 0x5C, 0x54, 0x4F, 0x50, + 0x4F, 0x21, 0x5C, 0x54, 0x50, 0x4F, 0x5F, 0x44, + 0x41, 0x54, 0x41, 0x5C, 0x00, 0x00, 0x00, 0xFF, + 0x18, 0x01, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, 0x30, 0x37, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x37, + 0x30, 0x37, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x34, 0x30, 0x34, 0x30, 0x35, 0x30, 0x35, + 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x34, + 0x30, 0x35, 0x30, 0x35, 0x30, 0x36, 0x30, 0x36, + 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, + 0x30, 0x32, 0x30, 0x32, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x38, 0x30, 0x38, 0x30, 0x38, 0x30, 0x39, + 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x32, 0x30, 0x32, 0x30, 0x32, + 0x30, 0x33, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, 0x30, 0x39, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, + 0x31, 0x30, 0x31, 0x30, 0x30, 0x39, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x0D, 0x55, 0x6E, 0x69, 0x74, 0x65, + 0x64, 0x20, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x4E, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x40, + 0x10, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x61, + 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x55, 0x53, + 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x48, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x50, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, + 0x40, 0x16, 0x2A, 0x47, 0x65, 0x6E, 0x65, 0x72, + 0x61, 0x6C, 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, + 0x65, 0x6E, 0x63, 0x65, 0x20, 0x4D, 0x61, 0x70, + 0x00, 0x09, 0x3D, 0x00, 0x0C, 0x4E, 0x45, 0x31, + 0x5F, 0x4D, 0x41, 0x50, 0x31, 0x5C, 0x53, 0x31, + 0x4C, 0x68, 0x03, 0x16, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x2C, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x24, 0x40, 0x8C, 0x00, 0x64, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x16, + 0x2A, 0x4E, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x61, + 0x6C, 0x20, 0x41, 0x74, 0x6C, 0x61, 0x73, 0x20, + 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, 0xE8, 0x32, + 0x0D, 0x00, 0x02, 0x44, 0x41, 0x0B, 0x01, 0x6C, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, + 0x3F, 0x3C, 0x00, 0x3C, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x10, 0x2A, 0x35, 0x30, 0x30, + 0x4B, 0x20, 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, + 0x72, 0x69, 0x65, 0x73, 0xC0, 0xFE, 0x04, 0x00, + 0x02, 0x44, 0x46, 0xEA, 0x00, 0x40, 0x01, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0xB5, + 0x2B, 0x4C, 0x55, 0x55, 0x55, 0xD5, 0x3F, 0x28, + 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x10, 0x2A, 0x31, 0x30, 0x30, 0x4B, 0x20, + 0x4D, 0x61, 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, + 0x65, 0x73, 0x50, 0xC3, 0x00, 0x00, 0x02, 0x44, + 0x4B, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xB0, 0x3F, 0x2D, 0x00, 0x2D, + 0x00, 0x0C, 0x00, 0x01, 0x00, 0x0A, 0x00, 0x10, + 0x2A, 0x37, 0x2E, 0x35, 0x27, 0x20, 0x4D, 0x61, + 0x70, 0x20, 0x53, 0x65, 0x72, 0x69, 0x65, 0x73, + 0x0F, 0x3C, 0x00, 0x00, 0x02, 0x44, 0x51, 0x00, + 0x00, 0x00, 0x01, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x99, 0x3F, 0x9A, 0x99, 0x99, 0x99, 0x99, + 0x99, 0x89, 0x3F, 0x5A, 0x00, 0x2D, 0x00, 0x0D, + 0x00, 0x01, 0x00, 0x28, 0x00 + }; + + gbfwrite(header_bytes, sizeof(header_bytes), 1, tpo_file_out); + } + + else { + fatal(MYNAME ": writing ouput for state \"%s\" is not currently supported.\n", output_state); + } } static void tpo_track_hdr(const route_head *rte) { - double amt; - unsigned char temp_buffer[8]; - unsigned char visibility_flags[] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; - unsigned char unknown1[] = { 0xFF, 0x00, 0x00, 0x00 }; - unsigned char bounding_box[8] = { 0x00, 0x80, 0x00, 0x80, 0xFF, 0x7F, 0xFF, 0x7F }; - - waypoint* first_track_waypoint = (waypoint*) QUEUE_FIRST(&rte->waypoint_list); - - /* zoom level 1-5 visibility flags */ - gbfwrite(visibility_flags, 1, sizeof(visibility_flags), tpo_file_out); - - /* 8 bytes of zeros, meaning unknown */ - memset(temp_buffer, 0, sizeof(temp_buffer)); - gbfwrite(temp_buffer, 1, sizeof(temp_buffer), tpo_file_out); - - /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ - gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); - - /* the starting point of the route */ - /* convert lat/long to NAD27/CONUS datum */ - GPS_Math_WGS84_To_Known_Datum_M( - first_track_waypoint->latitude, - first_track_waypoint->longitude, - first_track_waypoint->altitude, - &first_track_waypoint_lat, - &first_track_waypoint_lon, - &amt, - 78); - - /* swap the sign back *after* the datum conversion */ - first_track_waypoint_lon *= -1.0; - - /* Compute this track's scaling factors: Used for scaling each track point and then - later written out to the track footer. These are approximately the ratios between - pixels and degrees when viewing the 1:24000 map in TOPO!. In practice, it doesn't - appear to be necessary that they be correct, as long as the same values are used - for doing the scaling and for writing into the track footer data. */ - output_track_lat_scale = 4.8828125e-005; /* TOPO! appears to use a constant lat scale */ - output_track_lon_scale = output_track_lat_scale / cos(GPS_Math_Deg_To_Rad(first_track_waypoint_lat)); - - /* 8 bytes - longitude */ - gbfputdbl(first_track_waypoint_lon, tpo_file_out); - - /* 8 bytes - latitude */ - gbfputdbl(first_track_waypoint_lat, tpo_file_out); - - /* 8 bytes: seems to be bounding box info */ - gbfwrite(bounding_box, 1, sizeof(bounding_box), tpo_file_out); - - /* number of route points */ - gbfputint16(rte->rte_waypt_ct, tpo_file_out); - - /* initialize the track length computation */ - track_length = 0; - GPS_Math_WGS84LatLonH_To_XYZ( - first_track_waypoint->latitude, - first_track_waypoint->longitude, - 0.0, - &last_waypoint_x, - &last_waypoint_y, - &last_waypoint_z); + double amt; + unsigned char temp_buffer[8]; + unsigned char visibility_flags[] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00 }; + unsigned char unknown1[] = { 0xFF, 0x00, 0x00, 0x00 }; + unsigned char bounding_box[8] = { 0x00, 0x80, 0x00, 0x80, 0xFF, 0x7F, 0xFF, 0x7F }; + + waypoint* first_track_waypoint = (waypoint*) QUEUE_FIRST(&rte->waypoint_list); + + /* zoom level 1-5 visibility flags */ + gbfwrite(visibility_flags, 1, sizeof(visibility_flags), tpo_file_out); + + /* 8 bytes of zeros, meaning unknown */ + memset(temp_buffer, 0, sizeof(temp_buffer)); + gbfwrite(temp_buffer, 1, sizeof(temp_buffer), tpo_file_out); + + /* 4 more unknown bytes, possibly sign flags for the longitude and latitude? */ + gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + + /* the starting point of the route */ + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + first_track_waypoint->altitude, + &first_track_waypoint_lat, + &first_track_waypoint_lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + first_track_waypoint_lon *= -1.0; + + /* Compute this track's scaling factors: Used for scaling each track point and then + later written out to the track footer. These are approximately the ratios between + pixels and degrees when viewing the 1:24000 map in TOPO!. In practice, it doesn't + appear to be necessary that they be correct, as long as the same values are used + for doing the scaling and for writing into the track footer data. */ + output_track_lat_scale = 4.8828125e-005; /* TOPO! appears to use a constant lat scale */ + output_track_lon_scale = output_track_lat_scale / cos(GPS_Math_Deg_To_Rad(first_track_waypoint_lat)); + + /* 8 bytes - longitude */ + gbfputdbl(first_track_waypoint_lon, tpo_file_out); + + /* 8 bytes - latitude */ + gbfputdbl(first_track_waypoint_lat, tpo_file_out); + + /* 8 bytes: seems to be bounding box info */ + gbfwrite(bounding_box, 1, sizeof(bounding_box), tpo_file_out); + + /* number of route points */ + gbfputint16(rte->rte_waypt_ct, tpo_file_out); + + /* initialize the track length computation */ + track_length = 0; + GPS_Math_WGS84LatLonH_To_XYZ( + first_track_waypoint->latitude, + first_track_waypoint->longitude, + 0.0, + &last_waypoint_x, + &last_waypoint_y, + &last_waypoint_z); } static void tpo_track_disp(const waypoint *waypointp) { - double lat, lon, amt, x, y, z; - short lat_delta, lon_delta; - -/* fprintf(stderr, "%f/%f\n", waypointp->latitude, waypointp->longitude); */ - - /* convert lat/lon position to XYZ meters */ - GPS_Math_WGS84LatLonH_To_XYZ( - waypointp->latitude, - waypointp->longitude, - 0.0, - &x, - &y, - &z); - - /* increase the track length by the 3D length of last track segment in feet */ - track_length += METERS_TO_FEET(sqrt( - (x - last_waypoint_x) * (x - last_waypoint_x) + - (y - last_waypoint_y) * (y - last_waypoint_y) + - (z - last_waypoint_z) * (z - last_waypoint_z))); - last_waypoint_x = x; - last_waypoint_y = y; - last_waypoint_z = z; - - /* convert lat/long to NAD27/CONUS datum */ - GPS_Math_WGS84_To_Known_Datum_M( - waypointp->latitude, - waypointp->longitude, - waypointp->altitude, - &lat, - &lon, - &amt, - 78); - - /* swap the sign back *after* the datum conversion */ - lon *= -1.0; - - /* longitude delta from first route point */ - lon_delta = (short)((first_track_waypoint_lon - lon) / output_track_lon_scale); - gbfputint16(lon_delta, tpo_file_out); - - /* latitude delta from first route point */ - lat_delta = (short)((first_track_waypoint_lat - lat) / output_track_lat_scale); - gbfputint16(lat_delta, tpo_file_out); - -/* -fprintf(stderr, "%f %f: %x %x - %f %f %f / %f\n", lon, lat, lon_delta, lat_delta, first_track_waypoint_lat, lat, output_track_lat_scale, (first_track_waypoint_lat - lat) ); -*/ + double lat, lon, amt, x, y, z; + short lat_delta, lon_delta; + + /* fprintf(stderr, "%f/%f\n", waypointp->latitude, waypointp->longitude); */ + + /* convert lat/lon position to XYZ meters */ + GPS_Math_WGS84LatLonH_To_XYZ( + waypointp->latitude, + waypointp->longitude, + 0.0, + &x, + &y, + &z); + + /* increase the track length by the 3D length of last track segment in feet */ + track_length += METERS_TO_FEET(sqrt( + (x - last_waypoint_x) * (x - last_waypoint_x) + + (y - last_waypoint_y) * (y - last_waypoint_y) + + (z - last_waypoint_z) * (z - last_waypoint_z))); + last_waypoint_x = x; + last_waypoint_y = y; + last_waypoint_z = z; + + /* convert lat/long to NAD27/CONUS datum */ + GPS_Math_WGS84_To_Known_Datum_M( + waypointp->latitude, + waypointp->longitude, + waypointp->altitude, + &lat, + &lon, + &amt, + 78); + + /* swap the sign back *after* the datum conversion */ + lon *= -1.0; + + /* longitude delta from first route point */ + lon_delta = (short)((first_track_waypoint_lon - lon) / output_track_lon_scale); + gbfputint16(lon_delta, tpo_file_out); + + /* latitude delta from first route point */ + lat_delta = (short)((first_track_waypoint_lat - lat) / output_track_lat_scale); + gbfputint16(lat_delta, tpo_file_out); + + /* + fprintf(stderr, "%f %f: %x %x - %f %f %f / %f\n", lon, lat, lon_delta, lat_delta, first_track_waypoint_lat, lat, output_track_lat_scale, (first_track_waypoint_lat - lat) ); + */ } static void tpo_track_tlr(const route_head *rte) { - unsigned char unknown1[] = { 0x06, 0x00 }; + unsigned char unknown1[] = { 0x06, 0x00 }; - unsigned char continue_marker[] = { 0x01, 0x80 }; - unsigned char end_marker[] = { 0x00, 0x00 }; + unsigned char continue_marker[] = { 0x01, 0x80 }; + unsigned char end_marker[] = { 0x00, 0x00 }; - /* pixel to degree scaling factors */ - gbfputdbl(output_track_lon_scale, tpo_file_out); - gbfputdbl(output_track_lat_scale, tpo_file_out); + /* pixel to degree scaling factors */ + gbfputdbl(output_track_lon_scale, tpo_file_out); + gbfputdbl(output_track_lat_scale, tpo_file_out); - /* 4 bytes: the total length of the route */ - gbfputint32(track_length, tpo_file_out); + /* 4 bytes: the total length of the route */ + gbfputint32(track_length, tpo_file_out); - /* 2 unknown bytes */ - gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); + /* 2 unknown bytes */ + gbfwrite(unknown1, 1, sizeof(unknown1), tpo_file_out); - /* the last track ends with 0x0000 instead of 0x0180 */ - track_out_count++; - if (track_out_count == track_count()) { - gbfwrite(end_marker, 1, sizeof(end_marker), tpo_file_out); - } else { - gbfwrite(continue_marker, 1, sizeof(continue_marker), tpo_file_out); - } + /* the last track ends with 0x0000 instead of 0x0180 */ + track_out_count++; + if (track_out_count == track_count()) { + gbfwrite(end_marker, 1, sizeof(end_marker), tpo_file_out); + } else { + gbfwrite(continue_marker, 1, sizeof(continue_marker), tpo_file_out); + } } static void tpo_wr_init(const char *fname) -{ - if (doing_wpts || doing_rtes) - { - fatal(MYNAME ": this file format only supports tracks, not waypoints or routes.\n"); - } - - tpo_file_out = gbfopen_le(fname, "wb", MYNAME); - tpo_write_file_header(); +{ + if (doing_wpts || doing_rtes) { + fatal(MYNAME ": this file format only supports tracks, not waypoints or routes.\n"); + } + + tpo_file_out = gbfopen_le(fname, "wb", MYNAME); + tpo_write_file_header(); } static void tpo_wr_deinit(void) { - /* the file footer is six bytes of zeroes */ - unsigned char file_footer_bytes[6]; - memset(file_footer_bytes, 0, sizeof(file_footer_bytes)); - gbfwrite(file_footer_bytes, 1, sizeof(file_footer_bytes), tpo_file_out); + /* the file footer is six bytes of zeroes */ + unsigned char file_footer_bytes[6]; + memset(file_footer_bytes, 0, sizeof(file_footer_bytes)); + gbfwrite(file_footer_bytes, 1, sizeof(file_footer_bytes), tpo_file_out); - gbfclose(tpo_file_out); + gbfclose(tpo_file_out); } static void tpo_write(void) { - unsigned char unknown1[] = { 0xFF, 0xFF, 0x01, 0x00 }; + unsigned char unknown1[] = { 0xFF, 0xFF, 0x01, 0x00 }; + + char* chunk_name = "CTopoRoute"; + int chunk_name_length = strlen(chunk_name); - char* chunk_name = "CTopoRoute"; - int chunk_name_length = strlen(chunk_name); + /* write the total number of tracks */ + gbfputint16(track_count(), tpo_file_out); - /* write the total number of tracks */ - gbfputint16(track_count(), tpo_file_out); - - /* 4 unknown bytes */ - gbfwrite(unknown1, 1, 4, tpo_file_out); + /* 4 unknown bytes */ + gbfwrite(unknown1, 1, 4, tpo_file_out); - /* chunk name: "CTopoRoute" */ - gbfputint16(chunk_name_length, tpo_file_out); - gbfwrite(chunk_name, 1, chunk_name_length, tpo_file_out); + /* chunk name: "CTopoRoute" */ + gbfputint16(chunk_name_length, tpo_file_out); + gbfwrite(chunk_name, 1, chunk_name_length, tpo_file_out); - track_out_count = 0; - track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp); + track_out_count = 0; + track_disp_all(tpo_track_hdr, tpo_track_tlr, tpo_track_disp); } /* TPO 2.x format can read tracks only */ ff_vecs_t tpo2_vecs = { - ff_type_file, /* ff_type_internal */ -/* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */ - { ff_cap_none | ff_cap_none, ff_cap_read, ff_cap_none | ff_cap_none }, - tpo_rd_init, - tpo_wr_init, - tpo_rd_deinit, - tpo_wr_deinit, - tpo_read, - tpo_write, - NULL, - tpo2_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, /* ff_type_internal */ + /* { ff_cap_none | ff_cap_none, ff_cap_read | ff_cap_write, ff_cap_none | ff_cap_none }, */ + { ff_cap_none | ff_cap_none, ff_cap_read, ff_cap_none | ff_cap_none }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo2_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; /* TPO 3.x format can read waypoints/tracks/routes */ ff_vecs_t tpo3_vecs = { - ff_type_file, /* ff_type_internal */ - { ff_cap_read, ff_cap_read, ff_cap_read }, - tpo_rd_init, - tpo_wr_init, - tpo_rd_deinit, - tpo_wr_deinit, - tpo_read, - tpo_write, - NULL, - tpo3_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, /* ff_type_internal */ + { ff_cap_read, ff_cap_read, ff_cap_read }, + tpo_rd_init, + tpo_wr_init, + tpo_rd_deinit, + tpo_wr_deinit, + tpo_read, + tpo_write, + NULL, + tpo3_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/trackfilter.c b/gpsbabel/trackfilter.c index 4344b83fd..37eadf77c 100644 --- a/gpsbabel/trackfilter.c +++ b/gpsbabel/trackfilter.c @@ -19,23 +19,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - /* - 2005-07-20: implemented interval option from Etienne Tasse - 2005-07-26: implemented range option - 2005-07-26: implemented move option - 2005-07-26: implemented merge option - 2005-07-29: warning fixes - 2005-08-01: Add 'static' qualifier when we can (robertl) - 2005-10-04: Add filterdefs to hold protos for filter functions... (robertl) - 2005-10-04: Fix range-check max. value; exit filter, if no more tracks left - 2006-04-06: Add fix, course, and speed options (parkrrrr) - 2006-06-01: Add name option - 2007-01-08: if not really needed disable check for valid timestamps - (based on patch from Vladimir Kondratiev) - 2007-07-26: Allow 'range' together with trackpoints without timestamp - 2010-06-02: Add specified timestamp to each trackpoint (added by sven_luzar) - */ - +/* + 2005-07-20: implemented interval option from Etienne Tasse + 2005-07-26: implemented range option + 2005-07-26: implemented move option + 2005-07-26: implemented merge option + 2005-07-29: warning fixes + 2005-08-01: Add 'static' qualifier when we can (robertl) + 2005-10-04: Add filterdefs to hold protos for filter functions... (robertl) + 2005-10-04: Fix range-check max. value; exit filter, if no more tracks left + 2006-04-06: Add fix, course, and speed options (parkrrrr) + 2006-06-01: Add name option + 2007-01-08: if not really needed disable check for valid timestamps + (based on patch from Vladimir Kondratiev) + 2007-07-26: Allow 'range' together with trackpoints without timestamp + 2010-06-02: Add specified timestamp to each trackpoint (added by sven_luzar) +*/ + #include #include "defs.h" #include "filterdefs.h" @@ -84,59 +84,90 @@ static char *opt_faketime = NULL; static arglist_t trackfilter_args[] = { - {TRACKFILTER_MOVE_OPTION, &opt_move, - "Correct trackpoint timestamps by a delta", NULL, ARGTYPE_STRING, - ARG_NOMINMAX}, - {TRACKFILTER_PACK_OPTION, &opt_pack, - "Pack all tracks into one", NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {TRACKFILTER_SPLIT_OPTION, &opt_split, - "Split by date or time interval (see README)", NULL, - ARGTYPE_STRING, ARG_NOMINMAX}, - {TRACKFILTER_SDIST_OPTION, &opt_sdistance, - "Split by distance", NULL, - ARGTYPE_STRING, ARG_NOMINMAX}, - {TRACKFILTER_MERGE_OPTION, &opt_merge, - "Merge multiple tracks for the same way", NULL, ARGTYPE_STRING, - ARG_NOMINMAX}, - {TRACKFILTER_NAME_OPTION, &opt_name, - "Use only track(s) where title matches given name", NULL, ARGTYPE_STRING, - ARG_NOMINMAX}, - {TRACKFILTER_START_OPTION, &opt_start, - "Use only track points after this timestamp", NULL, ARGTYPE_INT, - ARG_NOMINMAX}, - {TRACKFILTER_STOP_OPTION, &opt_stop, - "Use only track points before this timestamp", NULL, ARGTYPE_INT, - ARG_NOMINMAX}, - {TRACKFILTER_TITLE_OPTION, &opt_title, - "Basic title for new track(s)", NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {TRACKFILTER_FIX_OPTION, &opt_fix, - "Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE)", NULL, - ARGTYPE_STRING, ARG_NOMINMAX }, - {TRACKFILTER_COURSE_OPTION, &opt_course, "Synthesize course", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {TRACKFILTER_SPEED_OPTION, &opt_speed, "Synthesize speed", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {TRACKFILTER_SEG2TRK_OPTION, &opt_seg2trk, - "Split track at segment boundaries into multiple tracks", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {TRACKFILTER_TRK2SEG_OPTION, &opt_trk2seg, - "Merge tracks inserting segment separators at boundaries", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {TRACKFILTER_SEGMENT_OPTION, &opt_segment, - "segment tracks with abnormally long gaps", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {TRACKFILTER_FAKETIME_OPTION, &opt_faketime, - "Add specified timestamp to each trackpoint", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + TRACKFILTER_MOVE_OPTION, &opt_move, + "Correct trackpoint timestamps by a delta", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + TRACKFILTER_PACK_OPTION, &opt_pack, + "Pack all tracks into one", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_SPLIT_OPTION, &opt_split, + "Split by date or time interval (see README)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + TRACKFILTER_SDIST_OPTION, &opt_sdistance, + "Split by distance", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + TRACKFILTER_MERGE_OPTION, &opt_merge, + "Merge multiple tracks for the same way", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + TRACKFILTER_NAME_OPTION, &opt_name, + "Use only track(s) where title matches given name", NULL, ARGTYPE_STRING, + ARG_NOMINMAX + }, + { + TRACKFILTER_START_OPTION, &opt_start, + "Use only track points after this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX + }, + { + TRACKFILTER_STOP_OPTION, &opt_stop, + "Use only track points before this timestamp", NULL, ARGTYPE_INT, + ARG_NOMINMAX + }, + { + TRACKFILTER_TITLE_OPTION, &opt_title, + "Basic title for new track(s)", NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + TRACKFILTER_FIX_OPTION, &opt_fix, + "Synthesize GPS fixes (PPS, DGPS, 3D, 2D, NONE)", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + TRACKFILTER_COURSE_OPTION, &opt_course, "Synthesize course", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_SPEED_OPTION, &opt_speed, "Synthesize speed", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_SEG2TRK_OPTION, &opt_seg2trk, + "Split track at segment boundaries into multiple tracks", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_TRK2SEG_OPTION, &opt_trk2seg, + "Merge tracks inserting segment separators at boundaries", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_SEGMENT_OPTION, &opt_segment, + "segment tracks with abnormally long gaps", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + TRACKFILTER_FAKETIME_OPTION, &opt_faketime, + "Add specified timestamp to each trackpoint", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; -typedef struct trkflt_s -{ - route_head *track; - time_t first_time; - time_t last_time; +typedef struct trkflt_s { + route_head *track; + time_t first_time; + time_t last_time; } trkflt_t; static trkflt_t *track_list = NULL; @@ -153,165 +184,170 @@ static char need_time; /* initialized within trackfilter_init */ static int trackfilter_opt_count(void) { - int res = 0; - arglist_t *a = trackfilter_args; - - while (a->argstring) - { - if (*a->argval != NULL) res++; - a++; - } - return res; + int res = 0; + arglist_t *a = trackfilter_args; + + while (a->argstring) { + if (*a->argval != NULL) { + res++; + } + a++; + } + return res; } static int trackfilter_parse_time_opt(const char *arg) { - time_t t0, t1; - int sign = 1; - char *cin = (char *)arg; - char c; - - t0 = t1 = 0; - - while ((c = *cin++)) - { - time_t seconds; - - if (c >= '0' && c <= '9') - { - t1 = (t1 * 10) + (c - '0'); - continue; - } - switch(tolower(c)) - { - case 'd': seconds = SECONDS_PER_DAY; break; - case 'h': seconds = SECONDS_PER_HOUR; break; - case 'm': seconds = 60; break; - case 's': seconds = 1; break; - case '+': sign = +1; continue; - case '-': sign = -1; continue; - default: fatal(MYNAME "-time: invalid character in time option!\n"); - } - t0 += (t1 * seconds * sign); - sign = +1; - t1 = 0; - } - t0 += t1; - return t0; + time_t t0, t1; + int sign = 1; + char *cin = (char *)arg; + char c; + + t0 = t1 = 0; + + while ((c = *cin++)) { + time_t seconds; + + if (c >= '0' && c <= '9') { + t1 = (t1 * 10) + (c - '0'); + continue; + } + switch (tolower(c)) { + case 'd': + seconds = SECONDS_PER_DAY; + break; + case 'h': + seconds = SECONDS_PER_HOUR; + break; + case 'm': + seconds = 60; + break; + case 's': + seconds = 1; + break; + case '+': + sign = +1; + continue; + case '-': + sign = -1; + continue; + default: + fatal(MYNAME "-time: invalid character in time option!\n"); + } + t0 += (t1 * seconds * sign); + sign = +1; + t1 = 0; + } + t0 += t1; + return t0; } static int trackfilter_init_qsort_cb(const void *a, const void *b) { - const trkflt_t *ra = (const trkflt_t*) a; - const trkflt_t *rb = (const trkflt_t*) b; + const trkflt_t *ra = (const trkflt_t*) a; + const trkflt_t *rb = (const trkflt_t*) b; - return ra->first_time - rb->first_time; + return ra->first_time - rb->first_time; } static int trackfilter_merge_qsort_cb(const void *a, const void *b) { - const waypoint *wa = *(waypoint **)a; - const waypoint *wb = *(waypoint **)b; + const waypoint *wa = *(waypoint **)a; + const waypoint *wb = *(waypoint **)b; - return wa->creation_time - wb->creation_time; + return wa->creation_time - wb->creation_time; } static fix_type trackfilter_parse_fix(int *nsats) { - if ( !opt_fix ) { - return fix_unknown; - } - if ( !case_ignore_strcmp( opt_fix, "pps" )) { - *nsats = 4; - return fix_pps; - } - if ( !case_ignore_strcmp( opt_fix, "dgps" )) { - *nsats = 4; - return fix_dgps; - } - if ( !case_ignore_strcmp( opt_fix, "3d" )) { - *nsats = 4; - return fix_3d; - } - if ( !case_ignore_strcmp( opt_fix, "2d" )) { - *nsats = 3; - return fix_2d; - } - if ( !case_ignore_strcmp( opt_fix, "none" )) { - *nsats = 0; - return fix_none; - } - fatal( MYNAME ": invalid fix type\n" ); - return 0; + if (!opt_fix) { + return fix_unknown; + } + if (!case_ignore_strcmp(opt_fix, "pps")) { + *nsats = 4; + return fix_pps; + } + if (!case_ignore_strcmp(opt_fix, "dgps")) { + *nsats = 4; + return fix_dgps; + } + if (!case_ignore_strcmp(opt_fix, "3d")) { + *nsats = 4; + return fix_3d; + } + if (!case_ignore_strcmp(opt_fix, "2d")) { + *nsats = 3; + return fix_2d; + } + if (!case_ignore_strcmp(opt_fix, "none")) { + *nsats = 0; + return fix_none; + } + fatal(MYNAME ": invalid fix type\n"); + return 0; } static void trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_disp_all */ { - int i; - waypoint *wpt, *prev; - queue *elem, *tmp; - - if (track->rte_waypt_ct == 0) - { - track_del_head((route_head *)track); - return; - } - - if (opt_name != NULL) - { - if ((track->rte_name == NULL) || - (case_ignore_str_match(track->rte_name, opt_name) == 0)) - { - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; - track_del_wpt((route_head *)track, wpt); - waypt_free(wpt); - } - track_del_head((route_head *)track); - return; - } - } - - track_list[track_ct].track = (route_head *)track; - - i = 0; - prev = NULL; - - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - track_pts++; - - wpt = (waypoint *)elem; - if((need_time != 0) && (wpt->creation_time == 0)) { - fatal(MYNAME "-init: Found track point at %f,%f without time!\n", - wpt->latitude, wpt->longitude); - } - - i++; - if (i == 1) - track_list[track_ct].first_time = wpt->creation_time; - else - if (i == track->rte_waypt_ct) - track_list[track_ct].last_time = wpt->creation_time; - - if ((need_time != 0) && (prev != NULL) && (prev->creation_time > wpt->creation_time)) - { - if (opt_merge == NULL) { - char t1[64], t2[64]; - xml_fill_in_time(t1, prev->creation_time, 0, XML_LONG_TIME); - xml_fill_in_time(t2, wpt->creation_time, 0, XML_LONG_TIME); - fatal(MYNAME "-init: Track points badly ordered (timestamp %s > %s)!\n", t1, t2); - } - } - prev = wpt; - } - track_ct++; + int i; + waypoint *wpt, *prev; + queue *elem, *tmp; + + if (track->rte_waypt_ct == 0) { + track_del_head((route_head *)track); + return; + } + + if (opt_name != NULL) { + if ((track->rte_name == NULL) || + (case_ignore_str_match(track->rte_name, opt_name) == 0)) { + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + track_del_wpt((route_head *)track, wpt); + waypt_free(wpt); + } + track_del_head((route_head *)track); + return; + } + } + + track_list[track_ct].track = (route_head *)track; + + i = 0; + prev = NULL; + + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + track_pts++; + + wpt = (waypoint *)elem; + if ((need_time != 0) && (wpt->creation_time == 0)) { + fatal(MYNAME "-init: Found track point at %f,%f without time!\n", + wpt->latitude, wpt->longitude); + } + + i++; + if (i == 1) { + track_list[track_ct].first_time = wpt->creation_time; + } else if (i == track->rte_waypt_ct) { + track_list[track_ct].last_time = wpt->creation_time; + } + + if ((need_time != 0) && (prev != NULL) && (prev->creation_time > wpt->creation_time)) { + if (opt_merge == NULL) { + char t1[64], t2[64]; + xml_fill_in_time(t1, prev->creation_time, 0, XML_LONG_TIME); + xml_fill_in_time(t2, wpt->creation_time, 0, XML_LONG_TIME); + fatal(MYNAME "-init: Track points badly ordered (timestamp %s > %s)!\n", t1, t2); + } + } + prev = wpt; + } + track_ct++; } /******************************************************************************* @@ -321,65 +357,57 @@ trackfilter_fill_track_list_cb(const route_head *track) /* callback for track_d static void trackfilter_split_init_rte_name(route_head *track, const time_t time) { - char buff[128], tbuff[128]; - struct tm tm; - - tm = *localtime(&time); - - (opt_interval != 0) ? - strftime(tbuff, sizeof(tbuff), "%Y%m%d%H%M%S", &tm) : - strftime(tbuff, sizeof(tbuff), "%Y%m%d", &tm); - - if ((opt_title != NULL) && (strlen(opt_title) > 0)) - { - if (strchr(opt_title, '%') != NULL) { - strftime(buff, sizeof(buff), opt_title, &tm); - } - else { - snprintf(buff, sizeof(buff), "%s-%s", opt_title, tbuff); - } - } - else if ((track->rte_name != NULL ) && (strlen(track->rte_name) > 0)) - { - snprintf(buff, sizeof(buff), "%s-%s", track->rte_name, tbuff); - } - else { - strncpy(buff, tbuff, sizeof(buff)); - } - - if (track->rte_name != NULL) { - xfree(track->rte_name); - } - track->rte_name = xstrdup(buff); + char buff[128], tbuff[128]; + struct tm tm; + + tm = *localtime(&time); + + (opt_interval != 0) ? + strftime(tbuff, sizeof(tbuff), "%Y%m%d%H%M%S", &tm) : + strftime(tbuff, sizeof(tbuff), "%Y%m%d", &tm); + + if ((opt_title != NULL) && (strlen(opt_title) > 0)) { + if (strchr(opt_title, '%') != NULL) { + strftime(buff, sizeof(buff), opt_title, &tm); + } else { + snprintf(buff, sizeof(buff), "%s-%s", opt_title, tbuff); + } + } else if ((track->rte_name != NULL) && (strlen(track->rte_name) > 0)) { + snprintf(buff, sizeof(buff), "%s-%s", track->rte_name, tbuff); + } else { + strncpy(buff, tbuff, sizeof(buff)); + } + + if (track->rte_name != NULL) { + xfree(track->rte_name); + } + track->rte_name = xstrdup(buff); } static void trackfilter_pack_init_rte_name(route_head *track, const time_t default_time) { - char buff[128]; - - if (strchr(opt_title, '%') != NULL) - { - struct tm tm; - waypoint *wpt; - - if (track->rte_waypt_ct == 0) - { - tm = *localtime(&default_time); - } - else - { - wpt = (waypoint *) QUEUE_FIRST((queue *)&track->waypoint_list); - tm = *localtime(&wpt->creation_time); - } - strftime(buff, sizeof(buff), opt_title, &tm); - } - else - strncpy(buff, opt_title, sizeof(buff)); - - if (track->rte_name != NULL) - xfree(track->rte_name); - track->rte_name = xstrdup(buff); + char buff[128]; + + if (strchr(opt_title, '%') != NULL) { + struct tm tm; + waypoint *wpt; + + if (track->rte_waypt_ct == 0) { + tm = *localtime(&default_time); + } else { + wpt = (waypoint *) QUEUE_FIRST((queue *)&track->waypoint_list); + tm = *localtime(&wpt->creation_time); + } + strftime(buff, sizeof(buff), opt_title, &tm); + } else { + strncpy(buff, opt_title, sizeof(buff)); + } + + if (track->rte_name != NULL) { + xfree(track->rte_name); + } + track->rte_name = xstrdup(buff); } /******************************************************************************* @@ -389,18 +417,19 @@ trackfilter_pack_init_rte_name(route_head *track, const time_t default_time) static void trackfilter_title(void) { - int i; - - if (opt_title == NULL) return; - - if (strlen(opt_title) == 0) { - fatal(MYNAME "-title: Missing your title!\n"); - } - for (i = 0; i < track_ct; i++) - { - route_head *track = track_list[i].track; - trackfilter_pack_init_rte_name(track, 0); - } + int i; + + if (opt_title == NULL) { + return; + } + + if (strlen(opt_title) == 0) { + fatal(MYNAME "-title: Missing your title!\n"); + } + for (i = 0; i < track_ct; i++) { + route_head *track = track_list[i].track; + trackfilter_pack_init_rte_name(track, 0); + } } /******************************************************************************* @@ -410,36 +439,34 @@ trackfilter_title(void) static void trackfilter_pack(void) { - int i, j; - trkflt_t prev; - route_head *master; - - for (i = 1, j = 0; i < track_ct; i++, j++) - { - prev = track_list[j]; - if (prev.last_time >= track_list[i].first_time) - fatal(MYNAME "-pack: Tracks overlap in time!\n"); - } - - /* we fill up the first track by all other track points */ - - master = track_list[0].track; - - for (i = 1; i < track_ct; i++) - { - queue *elem, *tmp; - route_head *curr = track_list[i].track; - - QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; - track_del_wpt(curr, wpt); - track_add_wpt(master, wpt); - } - track_del_head(curr); - track_list[i].track = NULL; - } - track_ct = 1; + int i, j; + trkflt_t prev; + route_head *master; + + for (i = 1, j = 0; i < track_ct; i++, j++) { + prev = track_list[j]; + if (prev.last_time >= track_list[i].first_time) { + fatal(MYNAME "-pack: Tracks overlap in time!\n"); + } + } + + /* we fill up the first track by all other track points */ + + master = track_list[0].track; + + for (i = 1; i < track_ct; i++) { + queue *elem, *tmp; + route_head *curr = track_list[i].track; + + QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + track_del_wpt(curr, wpt); + track_add_wpt(master, wpt); + } + track_del_head(curr); + track_list[i].track = NULL; + } + track_ct = 1; } /******************************************************************************* @@ -449,56 +476,54 @@ trackfilter_pack(void) static void trackfilter_merge(void) { - int i, j, dropped; - - queue *elem, *tmp; - waypoint **buff; - waypoint *prev, *wpt; - route_head *master = track_list[0].track; - - if (track_pts < 1) return; - - buff = (waypoint **)xcalloc(track_pts, sizeof(*buff)); - - j = 0; - for (i = 0; i < track_ct; i++) /* put all points into temp buffer */ - { - route_head *track = track_list[i].track; - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - wpt = (waypoint *)elem; - buff[j++] = waypt_dupe(wpt); - track_del_wpt(track, wpt); - waypt_free(wpt); - } - if (track != master) /* i > 0 */ - track_del_head(track); - } - track_ct = 1; - - qsort(buff, track_pts, sizeof(*buff), trackfilter_merge_qsort_cb); - - dropped = 0; - prev = NULL; - - for (i = 0; i < track_pts; i++) - { - wpt = buff[i]; - if ((prev == NULL) || (prev->creation_time != wpt->creation_time)) - { - route_add_wpt(master, wpt); - prev = wpt; - } - else - { - waypt_free(wpt); - dropped++; - } - } - xfree(buff); - - if (global_opts.verbose_status > 0) - printf(MYNAME "-merge: %d track point(s) merged, %d dropped.\n", track_pts - dropped, dropped); + int i, j, dropped; + + queue *elem, *tmp; + waypoint **buff; + waypoint *prev, *wpt; + route_head *master = track_list[0].track; + + if (track_pts < 1) { + return; + } + + buff = (waypoint **)xcalloc(track_pts, sizeof(*buff)); + + j = 0; + for (i = 0; i < track_ct; i++) { /* put all points into temp buffer */ + route_head *track = track_list[i].track; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + wpt = (waypoint *)elem; + buff[j++] = waypt_dupe(wpt); + track_del_wpt(track, wpt); + waypt_free(wpt); + } + if (track != master) { /* i > 0 */ + track_del_head(track); + } + } + track_ct = 1; + + qsort(buff, track_pts, sizeof(*buff), trackfilter_merge_qsort_cb); + + dropped = 0; + prev = NULL; + + for (i = 0; i < track_pts; i++) { + wpt = buff[i]; + if ((prev == NULL) || (prev->creation_time != wpt->creation_time)) { + route_add_wpt(master, wpt); + prev = wpt; + } else { + waypt_free(wpt); + dropped++; + } + } + xfree(buff); + + if (global_opts.verbose_status > 0) { + printf(MYNAME "-merge: %d track point(s) merged, %d dropped.\n", track_pts - dropped, dropped); + } } /******************************************************************************* @@ -508,207 +533,195 @@ trackfilter_merge(void) static void trackfilter_split(void) { - route_head *curr; - route_head *master = track_list[0].track; - int count = master->rte_waypt_ct; - - waypoint **buff; - waypoint *wpt; - queue *elem, *tmp; - int i, j; - double interval = -1; - double distance = -1; - - if (count <= 1) return; - - /* check additional options */ - - opt_interval = (opt_split && (strlen(opt_split) > 0) && (0 != strcmp(opt_split, TRACKFILTER_SPLIT_OPTION))); - opt_distance = (opt_sdistance && (strlen(opt_sdistance) > 0) && (0 != strcmp(opt_sdistance, TRACKFILTER_SDIST_OPTION))); - - if (opt_interval != 0) - { - double base; - char unit; - - switch(strlen(opt_split)) - { - case 0: - fatal(MYNAME ": No time interval specified.\n"); - break; /* ? */ - - case 1: - unit = *opt_split; - interval = 1; - break; - - default: - i = sscanf(opt_split,"%lf%c", &interval, &unit); - if (i == 0) - { - /* test reverse order */ - i = sscanf(opt_split,"%c%lf", &unit, &interval); - } - if ((i != 2) || (interval <= 0)) - { - fatal(MYNAME ": invalid time interval specified, must be one a positive number.\n"); - } - break; - } - - switch(tolower(unit)) - { - case 's': - base = 1; - break; - case 'm': - base = 60; - break; - case 'h': - base = 60 * 60; - break; - case 'd': - base = 24 * 60 * 60; - break; - default: - fatal(MYNAME ": invalid time interval specified, must be one of [dhms].\n"); - break; - } + route_head *curr; + route_head *master = track_list[0].track; + int count = master->rte_waypt_ct; + + waypoint **buff; + waypoint *wpt; + queue *elem, *tmp; + int i, j; + double interval = -1; + double distance = -1; + + if (count <= 1) { + return; + } + + /* check additional options */ + + opt_interval = (opt_split && (strlen(opt_split) > 0) && (0 != strcmp(opt_split, TRACKFILTER_SPLIT_OPTION))); + opt_distance = (opt_sdistance && (strlen(opt_sdistance) > 0) && (0 != strcmp(opt_sdistance, TRACKFILTER_SDIST_OPTION))); + + if (opt_interval != 0) { + double base; + char unit; + + switch (strlen(opt_split)) { + case 0: + fatal(MYNAME ": No time interval specified.\n"); + break; /* ? */ + + case 1: + unit = *opt_split; + interval = 1; + break; + + default: + i = sscanf(opt_split,"%lf%c", &interval, &unit); + if (i == 0) { + /* test reverse order */ + i = sscanf(opt_split,"%c%lf", &unit, &interval); + } + if ((i != 2) || (interval <= 0)) { + fatal(MYNAME ": invalid time interval specified, must be one a positive number.\n"); + } + break; + } + + switch (tolower(unit)) { + case 's': + base = 1; + break; + case 'm': + base = 60; + break; + case 'h': + base = 60 * 60; + break; + case 'd': + base = 24 * 60 * 60; + break; + default: + fatal(MYNAME ": invalid time interval specified, must be one of [dhms].\n"); + break; + } #ifdef TRACKF_DBG - printf(MYNAME ": unit \"%c\", interval %g -> %g\n", unit, interval, base * interval); + printf(MYNAME ": unit \"%c\", interval %g -> %g\n", unit, interval, base * interval); #endif - interval *= base; - } - - if (opt_distance != 0) - { - double base; - char unit; - - switch(strlen(opt_sdistance)) - { - case 0: - fatal(MYNAME ": No distance specified.\n"); - break; /* ? */ - - case 1: - unit = *opt_sdistance; - distance = 1; - break; - - default: - i = sscanf(opt_sdistance,"%lf%c", &distance, &unit); - if (i == 0) - { - /* test reverse order */ - i = sscanf(opt_sdistance,"%c%lf", &unit, &distance); - } - if ((i != 2) || (distance <= 0)) - { - fatal(MYNAME ": invalid distance specified, must be one a positive number.\n"); - } - break; - } - - switch(tolower(unit)) - { - case 'k': /* kilometers */ - base = 0.6214; - break; - case 'm': /* miles */ - base = 1; - break; - default: - fatal(MYNAME ": invalid distance specified, must be one of [km].\n"); - break; - } + interval *= base; + } + + if (opt_distance != 0) { + double base; + char unit; + + switch (strlen(opt_sdistance)) { + case 0: + fatal(MYNAME ": No distance specified.\n"); + break; /* ? */ + + case 1: + unit = *opt_sdistance; + distance = 1; + break; + + default: + i = sscanf(opt_sdistance,"%lf%c", &distance, &unit); + if (i == 0) { + /* test reverse order */ + i = sscanf(opt_sdistance,"%c%lf", &unit, &distance); + } + if ((i != 2) || (distance <= 0)) { + fatal(MYNAME ": invalid distance specified, must be one a positive number.\n"); + } + break; + } + + switch (tolower(unit)) { + case 'k': /* kilometers */ + base = 0.6214; + break; + case 'm': /* miles */ + base = 1; + break; + default: + fatal(MYNAME ": invalid distance specified, must be one of [km].\n"); + break; + } #ifdef TRACKF_DBG - printf(MYNAME ": unit \"%c\", distance %g -> %g\n", unit, distance, base * distance); + printf(MYNAME ": unit \"%c\", distance %g -> %g\n", unit, distance, base * distance); #endif - distance *= base; - } - - trackfilter_split_init_rte_name(master, track_list[0].first_time); - - buff = (waypoint **) xcalloc(count, sizeof(*buff)); - - i = 0; - QUEUE_FOR_EACH((queue *)&master->waypoint_list, elem, tmp) - { - wpt = (waypoint *)elem; - buff[i++] = wpt; - } - - curr = NULL; /* will be set by first new track */ - - for (i=0, j=1; jcreation_time); - t2 = *localtime(&buff[j]->creation_time); - - new_track_flag = ((t1.tm_year != t2.tm_year) || (t1.tm_mon != t2.tm_mon) || - (t1.tm_mday != t2.tm_mday)); + distance *= base; + } + + trackfilter_split_init_rte_name(master, track_list[0].first_time); + + buff = (waypoint **) xcalloc(count, sizeof(*buff)); + + i = 0; + QUEUE_FOR_EACH((queue *)&master->waypoint_list, elem, tmp) { + wpt = (waypoint *)elem; + buff[i++] = wpt; + } + + curr = NULL; /* will be set by first new track */ + + for (i=0, j=1; jcreation_time); + t2 = *localtime(&buff[j]->creation_time); + + new_track_flag = ((t1.tm_year != t2.tm_year) || (t1.tm_mon != t2.tm_mon) || + (t1.tm_mday != t2.tm_mday)); #ifdef TRACKF_DBG - if (new_track_flag != 0) - printf(MYNAME ": new day %02d.%02d.%04d\n", t2.tm_mday, t2.tm_mon+1, t2.tm_year+1900); + if (new_track_flag != 0) { + printf(MYNAME ": new day %02d.%02d.%04d\n", t2.tm_mday, t2.tm_mon+1, t2.tm_year+1900); + } #endif - } - else - { - new_track_flag = 1; - - if (distance > 0) - { - double rt1 = RAD(buff[i]->latitude); - double rn1 = RAD(buff[i]->longitude); - double rt2 = RAD(buff[j]->latitude); - double rn2 = RAD(buff[j]->longitude); - double curdist = gcdist( rt1, rn1, rt2, rn2 ); - curdist = radtomiles(curdist); - if ( curdist <= distance ) - new_track_flag = 0; + } else { + new_track_flag = 1; + + if (distance > 0) { + double rt1 = RAD(buff[i]->latitude); + double rn1 = RAD(buff[i]->longitude); + double rt2 = RAD(buff[j]->latitude); + double rn2 = RAD(buff[j]->longitude); + double curdist = gcdist(rt1, rn1, rt2, rn2); + curdist = radtomiles(curdist); + if (curdist <= distance) { + new_track_flag = 0; + } #ifdef TRACKF_DBG - else - printf(MYNAME ": sdistance, %g > %g\n", curdist, distance ); + else { + printf(MYNAME ": sdistance, %g > %g\n", curdist, distance); + } #endif - } - - if (interval > 0) - { - double tr_interval = difftime(buff[j]->creation_time,buff[i]->creation_time); - if ( tr_interval <= interval ) - new_track_flag = 0; + } + + if (interval > 0) { + double tr_interval = difftime(buff[j]->creation_time,buff[i]->creation_time); + if (tr_interval <= interval) { + new_track_flag = 0; + } #ifdef TRACKF_DBG - else - printf(MYNAME ": split, %g > %g\n", tr_interval, interval ); + else { + printf(MYNAME ": split, %g > %g\n", tr_interval, interval); + } #endif - } + } - } - if (new_track_flag != 0) - { + } + if (new_track_flag != 0) { #ifdef TRACKF_DBG - printf(MYNAME ": splitting new track\n" ); + printf(MYNAME ": splitting new track\n"); #endif - curr = (route_head *) route_head_alloc(); - trackfilter_split_init_rte_name(curr, buff[j]->creation_time); - track_add_head(curr); - } - if (curr != NULL) - { - wpt = buff[j]; - track_del_wpt(master, wpt); - track_add_wpt(curr, wpt); - buff[j] = wpt; - } - } - xfree(buff); + curr = (route_head *) route_head_alloc(); + trackfilter_split_init_rte_name(curr, buff[j]->creation_time); + track_add_head(curr); + } + if (curr != NULL) { + wpt = buff[j]; + track_del_wpt(master, wpt); + track_add_wpt(curr, wpt); + buff[j] = wpt; + } + } + xfree(buff); } /******************************************************************************* @@ -718,25 +731,25 @@ trackfilter_split(void) static void trackfilter_move(void) { - int i; - queue *elem, *tmp; - waypoint *wpt; - time_t delta; - - delta = trackfilter_parse_time_opt(opt_move); - if (delta == 0) return; - - for (i = 0; i < track_ct; i++) - { - route_head *track = track_list[i].track; - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - wpt = (waypoint *)elem; - wpt->creation_time += delta; - } - track_list[i].first_time += delta; - track_list[i].last_time += delta; - } + int i; + queue *elem, *tmp; + waypoint *wpt; + time_t delta; + + delta = trackfilter_parse_time_opt(opt_move); + if (delta == 0) { + return; + } + + for (i = 0; i < track_ct; i++) { + route_head *track = track_list[i].track; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + wpt = (waypoint *)elem; + wpt->creation_time += delta; + } + track_list[i].first_time += delta; + track_list[i].last_time += delta; + } } /******************************************************************************* @@ -746,64 +759,61 @@ trackfilter_move(void) static void trackfilter_synth(void) { - int i; - queue *elem, *tmp; - waypoint *wpt; - - double oldlat = -999; - double oldlon = -999; - time_t oldtime = 0; - int first = 1; - fix_type fix; - int nsats = 0; - - fix = trackfilter_parse_fix(&nsats); - - for (i = 0; i < track_ct; i++) - { - route_head *track = track_list[i].track; - first = 1; - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - wpt = (waypoint *)elem; - if ( opt_fix ) { - wpt->fix = fix; - if (wpt->sat == 0) - wpt->sat = nsats; - } - if ( first ) { - if ( opt_course ) { - WAYPT_SET(wpt, course, 0); - } - if ( opt_speed ) { - WAYPT_SET(wpt, speed, 0); - } - first = 0; - } - else { - if ( opt_course ) { - WAYPT_SET(wpt, course, heading_true_degrees( RAD(oldlat), - RAD(oldlon),RAD(wpt->latitude), - RAD(wpt->longitude)) ); - } - if ( opt_speed ) { - if ( oldtime != wpt->creation_time ) { - WAYPT_SET(wpt, speed, radtometers(gcdist( - RAD(oldlat), RAD(oldlon), - RAD(wpt->latitude), - RAD(wpt->longitude))) / - labs(wpt->creation_time-oldtime)); - } - else { - WAYPT_UNSET(wpt, speed); - } - } - } - oldlat = wpt->latitude; - oldlon = wpt->longitude; - oldtime = wpt->creation_time; - } - } + int i; + queue *elem, *tmp; + waypoint *wpt; + + double oldlat = -999; + double oldlon = -999; + time_t oldtime = 0; + int first = 1; + fix_type fix; + int nsats = 0; + + fix = trackfilter_parse_fix(&nsats); + + for (i = 0; i < track_ct; i++) { + route_head *track = track_list[i].track; + first = 1; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + wpt = (waypoint *)elem; + if (opt_fix) { + wpt->fix = fix; + if (wpt->sat == 0) { + wpt->sat = nsats; + } + } + if (first) { + if (opt_course) { + WAYPT_SET(wpt, course, 0); + } + if (opt_speed) { + WAYPT_SET(wpt, speed, 0); + } + first = 0; + } else { + if (opt_course) { + WAYPT_SET(wpt, course, heading_true_degrees(RAD(oldlat), + RAD(oldlon),RAD(wpt->latitude), + RAD(wpt->longitude))); + } + if (opt_speed) { + if (oldtime != wpt->creation_time) { + WAYPT_SET(wpt, speed, radtometers(gcdist( + RAD(oldlat), RAD(oldlon), + RAD(wpt->latitude), + RAD(wpt->longitude))) / + labs(wpt->creation_time-oldtime)); + } else { + WAYPT_UNSET(wpt, speed); + } + } + } + oldlat = wpt->latitude; + oldlon = wpt->longitude; + oldtime = wpt->creation_time; + } + } } @@ -814,83 +824,87 @@ trackfilter_synth(void) static time_t trackfilter_range_check(const char *timestr) { - int i; - char fmt[20]; - char c; - char *cin; - struct tm time; - - - i = 0; - strncpy(fmt, "00000101000000", sizeof(fmt)); - cin = (char *)timestr; - - while ((c = *cin++)) - { - if (fmt[i] == '\0') fatal(MYNAME "-range: parameter too long \"%s\"!\n", timestr); - if (isdigit(c) == 0) fatal(MYNAME "-range: invalid character \"%c\"!\n", c); - fmt[i++] = c; - } - cin = strptime(fmt, "%Y%m%d%H%M%S", &time); - if ((cin != NULL) && (*cin != '\0')) - fatal(MYNAME "-range-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmt); - - return mkgmtime(&time); + int i; + char fmt[20]; + char c; + char *cin; + struct tm time; + + + i = 0; + strncpy(fmt, "00000101000000", sizeof(fmt)); + cin = (char *)timestr; + + while ((c = *cin++)) { + if (fmt[i] == '\0') { + fatal(MYNAME "-range: parameter too long \"%s\"!\n", timestr); + } + if (isdigit(c) == 0) { + fatal(MYNAME "-range: invalid character \"%c\"!\n", c); + } + fmt[i++] = c; + } + cin = strptime(fmt, "%Y%m%d%H%M%S", &time); + if ((cin != NULL) && (*cin != '\0')) { + fatal(MYNAME "-range-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmt); + } + + return mkgmtime(&time); } static int trackfilter_range(void) /* returns number of track points left after filtering */ { - time_t start, stop; - queue *elem, *tmp; - int i, dropped, inside = 0; - - if (opt_start != 0) - start = trackfilter_range_check(opt_start); - else - start = 0; - - if (opt_stop != 0) - stop = trackfilter_range_check(opt_stop); - else - stop = 0x7FFFFFFF; - - dropped = inside = 0; - - for (i = 0; i < track_ct; i++) - { - route_head *track = track_list[i].track; - - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; - if (wpt->creation_time > 0) { - inside = ((wpt->creation_time >= start) && (wpt->creation_time <= stop)); - } - // If the time is mangled so horribly that it's - // negative, toss it. - if (wpt->creation_time < 0) { - inside = 0; - } - - if (! inside) { - track_del_wpt(track, wpt); - waypt_free(wpt); - dropped++; - } - } - - if (track->rte_waypt_ct == 0) - { - track_del_head(track); - track_list[i].track = NULL; - } - } - - if ((track_pts > 0) && (dropped == track_pts)) - warning(MYNAME "-range: All %d track points have been dropped!\n", track_pts); - - return track_pts - dropped; + time_t start, stop; + queue *elem, *tmp; + int i, dropped, inside = 0; + + if (opt_start != 0) { + start = trackfilter_range_check(opt_start); + } else { + start = 0; + } + + if (opt_stop != 0) { + stop = trackfilter_range_check(opt_stop); + } else { + stop = 0x7FFFFFFF; + } + + dropped = inside = 0; + + for (i = 0; i < track_ct; i++) { + route_head *track = track_list[i].track; + + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + if (wpt->creation_time > 0) { + inside = ((wpt->creation_time >= start) && (wpt->creation_time <= stop)); + } + // If the time is mangled so horribly that it's + // negative, toss it. + if (wpt->creation_time < 0) { + inside = 0; + } + + if (! inside) { + track_del_wpt(track, wpt); + waypt_free(wpt); + dropped++; + } + } + + if (track->rte_waypt_ct == 0) { + track_del_head(track); + track_list[i].track = NULL; + } + } + + if ((track_pts > 0) && (dropped == track_pts)) { + warning(MYNAME "-range: All %d track points have been dropped!\n", track_pts); + } + + return track_pts - dropped; } /******************************************************************************* @@ -900,52 +914,48 @@ trackfilter_range(void) /* returns number of track points left after filtering static void trackfilter_seg2trk(void) { - int i; - - for (i = 0; i < track_ct; i++) - { - queue *elem, *tmp; - route_head *src = track_list[i].track; - route_head *dest = NULL; - route_head *insert_point = src; - int trk_seg_num = 1, first = 1; - - QUEUE_FOR_EACH((queue *)&src->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; - if (wpt->wpt_flags.new_trkseg && !first) - { - char trk_seg_num_buf[10]; - - dest = route_head_alloc(); - dest->rte_num = src->rte_num; - /* name in the form TRACKNAME #n */ - snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", ++trk_seg_num); - dest->rte_name = xmalloc(strlen(src->rte_name)+strlen(trk_seg_num_buf)+3); - sprintf(dest->rte_name, "%s #%s", src->rte_name, trk_seg_num_buf); - - /* Insert after original track or after last newly - * created track */ - track_insert_head(dest, insert_point); - insert_point = dest; - } - - /* If we found a track separator, transfer from original to - * new track. We have to reset new_trkseg temporarily to - * prevent track_del_wpt() from copying it to the next track - * point. - */ - if (dest) - { - int orig_new_trkseg = wpt->wpt_flags.new_trkseg; - wpt->wpt_flags.new_trkseg = 0; - track_del_wpt(src, wpt); - wpt->wpt_flags.new_trkseg = orig_new_trkseg; - track_add_wpt(dest, wpt); - } - first = 0; - } - } + int i; + + for (i = 0; i < track_ct; i++) { + queue *elem, *tmp; + route_head *src = track_list[i].track; + route_head *dest = NULL; + route_head *insert_point = src; + int trk_seg_num = 1, first = 1; + + QUEUE_FOR_EACH((queue *)&src->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + if (wpt->wpt_flags.new_trkseg && !first) { + char trk_seg_num_buf[10]; + + dest = route_head_alloc(); + dest->rte_num = src->rte_num; + /* name in the form TRACKNAME #n */ + snprintf(trk_seg_num_buf, sizeof(trk_seg_num_buf), "%d", ++trk_seg_num); + dest->rte_name = xmalloc(strlen(src->rte_name)+strlen(trk_seg_num_buf)+3); + sprintf(dest->rte_name, "%s #%s", src->rte_name, trk_seg_num_buf); + + /* Insert after original track or after last newly + * created track */ + track_insert_head(dest, insert_point); + insert_point = dest; + } + + /* If we found a track separator, transfer from original to + * new track. We have to reset new_trkseg temporarily to + * prevent track_del_wpt() from copying it to the next track + * point. + */ + if (dest) { + int orig_new_trkseg = wpt->wpt_flags.new_trkseg; + wpt->wpt_flags.new_trkseg = 0; + track_del_wpt(src, wpt); + wpt->wpt_flags.new_trkseg = orig_new_trkseg; + track_add_wpt(dest, wpt); + } + first = 0; + } + } } /******************************************************************************* @@ -955,131 +965,131 @@ trackfilter_seg2trk(void) static void trackfilter_trk2seg(void) { - int i, first; - route_head *master; - - master = track_list[0].track; - - for (i = 1; i < track_ct; i++) - { - queue *elem, *tmp; - route_head *curr = track_list[i].track; - - first = 1; - QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; - - - int orig_new_trkseg = wpt->wpt_flags.new_trkseg; - wpt->wpt_flags.new_trkseg = 0; - track_del_wpt(curr, wpt); - wpt->wpt_flags.new_trkseg = orig_new_trkseg; - track_add_wpt(master, wpt); - if (first) - { - wpt->wpt_flags.new_trkseg = 1; - first = 0; - } - } - track_del_head(curr); - track_list[i].track = NULL; - } - track_ct = 1; + int i, first; + route_head *master; + + master = track_list[0].track; + + for (i = 1; i < track_ct; i++) { + queue *elem, *tmp; + route_head *curr = track_list[i].track; + + first = 1; + QUEUE_FOR_EACH((queue *)&curr->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; + + + int orig_new_trkseg = wpt->wpt_flags.new_trkseg; + wpt->wpt_flags.new_trkseg = 0; + track_del_wpt(curr, wpt); + wpt->wpt_flags.new_trkseg = orig_new_trkseg; + track_add_wpt(master, wpt); + if (first) { + wpt->wpt_flags.new_trkseg = 1; + first = 0; + } + } + track_del_head(curr); + track_list[i].track = NULL; + } + track_ct = 1; } /******************************************************************************* * option: "faketime" *******************************************************************************/ -typedef struct faketime_s -{ - time_t start; - int step; - int force; +typedef struct faketime_s { + time_t start; + int step; + int force; } faketime_t; static faketime_t trackfilter_faketime_check(const char *timestr) { - int i, j; - char fmtstart[20]; - char fmtstep[20]; - char c; - const char *cin; - struct tm time; - int timeparse = 1; - faketime_t result; - result.force = 0; - - i = j = 0; - strncpy(fmtstart, "00000101000000", sizeof(fmtstart)); - strncpy(fmtstep, "00000000000000", sizeof(fmtstep)); - cin = timestr; - - while ((c = *cin++)) - { - if (c=='f') { - result.force = 1; - continue; - } - - if (c!='+' && isdigit(c) == 0) - fatal(MYNAME "-faketime: invalid character \"%c\"!\n", c); - - if (timeparse) { - if ((c == '+')) { - fmtstart[i++] = '\0'; - timeparse = 0; - } else { - if (fmtstart[i] == '\0') fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr); - fmtstart[i++] = c; - } - } else { - if (fmtstep[j] == '\0') fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr); - fmtstep[j++] = c; - } - } - fmtstep[j++] = '\0'; - - cin = strptime(fmtstart, "%Y%m%d%H%M%S", &time); - result.step = atoi(fmtstep); - if ((cin != NULL) && (*cin != '\0')) - fatal(MYNAME "-faketime-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmtstart); - - result.start = mkgmtime(&time); - return result; + int i, j; + char fmtstart[20]; + char fmtstep[20]; + char c; + const char *cin; + struct tm time; + int timeparse = 1; + faketime_t result; + result.force = 0; + + i = j = 0; + strncpy(fmtstart, "00000101000000", sizeof(fmtstart)); + strncpy(fmtstep, "00000000000000", sizeof(fmtstep)); + cin = timestr; + + while ((c = *cin++)) { + if (c=='f') { + result.force = 1; + continue; + } + + if (c!='+' && isdigit(c) == 0) { + fatal(MYNAME "-faketime: invalid character \"%c\"!\n", c); + } + + if (timeparse) { + if ((c == '+')) { + fmtstart[i++] = '\0'; + timeparse = 0; + } else { + if (fmtstart[i] == '\0') { + fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr); + } + fmtstart[i++] = c; + } + } else { + if (fmtstep[j] == '\0') { + fatal(MYNAME "-faketime: parameter too long \"%s\"!\n", timestr); + } + fmtstep[j++] = c; + } + } + fmtstep[j++] = '\0'; + + cin = strptime(fmtstart, "%Y%m%d%H%M%S", &time); + result.step = atoi(fmtstep); + if ((cin != NULL) && (*cin != '\0')) { + fatal(MYNAME "-faketime-check: Invalid time stamp (stopped at %s of %s)!\n", cin, fmtstart); + } + + result.start = mkgmtime(&time); + return result; } static int trackfilter_faketime(void) /* returns number of track points left after filtering */ { - faketime_t faketime; + faketime_t faketime; - queue *elem, *tmp; - int i, dropped, inside = 0; + queue *elem, *tmp; + int i, dropped, inside = 0; - if (opt_faketime != 0) - faketime = trackfilter_faketime_check(opt_faketime); + if (opt_faketime != 0) { + faketime = trackfilter_faketime_check(opt_faketime); + } - dropped = inside = 0; + dropped = inside = 0; - for (i = 0; i < track_ct; i++) - { - route_head *track = track_list[i].track; + for (i = 0; i < track_ct; i++) { + route_head *track = track_list[i].track; - QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) - { - waypoint *wpt = (waypoint *)elem; + QUEUE_FOR_EACH((queue *)&track->waypoint_list, elem, tmp) { + waypoint *wpt = (waypoint *)elem; - if (opt_faketime != 0 && (wpt->creation_time == 0 || faketime.force)) { - wpt->creation_time = faketime.start; - faketime.start += faketime.step; - } - } - } + if (opt_faketime != 0 && (wpt->creation_time == 0 || faketime.force)) { + wpt->creation_time = faketime.start; + faketime.start += faketime.step; + } + } + } - return track_pts - dropped; + return track_pts - dropped; } static int @@ -1095,15 +1105,15 @@ trackfilter_points_are_same(const waypoint *wpta, const waypoint *wptb) // reasonable tradeoff. return - fabs(wpta->latitude - wptb->latitude) < .00001 && - fabs(wpta->longitude - wptb->longitude) < .00001 && - abs(wpta->altitude - wptb->altitude) < 20 && - (WAYPT_HAS(wpta,course) == WAYPT_HAS(wptb,course)) && - (wpta->course == wptb->course) && - (wpta->speed == wptb->speed) && - (wpta->heartrate == wptb->heartrate) && - (wpta->cadence == wptb->cadence) && - (wpta->temperature == wptb->temperature); + fabs(wpta->latitude - wptb->latitude) < .00001 && + fabs(wpta->longitude - wptb->longitude) < .00001 && + abs(wpta->altitude - wptb->altitude) < 20 && + (WAYPT_HAS(wpta,course) == WAYPT_HAS(wptb,course)) && + (wpta->course == wptb->course) && + (wpta->speed == wptb->speed) && + (wpta->heartrate == wptb->heartrate) && + (wpta->cadence == wptb->cadence) && + (wpta->temperature == wptb->temperature); } static void @@ -1125,8 +1135,9 @@ trackfilter_segment_head(const route_head *rte) RAD(wpt->latitude), RAD(wpt->longitude)); // Denoise points that are on top of each other. - if (avg_dist == 0) + if (avg_dist == 0) { avg_dist = cur_dist; + } if (cur_dist < ktoo_close) { if (wpt != (waypoint *) QUEUE_LAST(&rte->waypoint_list)) { @@ -1135,7 +1146,7 @@ trackfilter_segment_head(const route_head *rte) trackfilter_points_are_same(wpt, next_wpt)) { track_del_wpt((route_head *)rte, wpt); continue; - } + } } } if (cur_dist > .001 && cur_dist > 1.2* avg_dist) { @@ -1155,182 +1166,204 @@ trackfilter_segment_head(const route_head *rte) *******************************************************************************/ static void -trackfilter_init(const char *args) +trackfilter_init(const char *args) { - int count = track_count(); + int count = track_count(); + + /* + * check time presence only if required. Options that NOT require time: + * + * - opt_title (!!! only if no format specifier is present !!!) + * - opt_course + * - opt_name + */ + need_time = ( + opt_merge || opt_pack || opt_split || opt_sdistance || + opt_move || opt_fix || opt_speed || + (trackfilter_opt_count() == 0) /* do pack by default */ + ); + /* in case of a formated title we also need valid timestamps */ + if ((opt_title != NULL) && (strchr(opt_title, '%') != NULL)) { + need_time = 1; + } -/* - * check time presence only if required. Options that NOT require time: - * - * - opt_title (!!! only if no format specifier is present !!!) - * - opt_course - * - opt_name - */ - need_time = ( - opt_merge || opt_pack || opt_split || opt_sdistance || - opt_move || opt_fix || opt_speed || - (trackfilter_opt_count() == 0) /* do pack by default */ - ); - /* in case of a formated title we also need valid timestamps */ - if ((opt_title != NULL) && (strchr(opt_title, '%') != NULL)) need_time = 1; - - track_ct = 0; - track_pts = 0; - - // Perform segmenting first. - if (opt_segment) { - track_disp_all(trackfilter_segment_head, NULL, NULL); - } - - if (count > 0) - { - track_list = (trkflt_t *) xcalloc(count, sizeof(*track_list)); - - /* check all tracks for time and order (except merging) */ - - track_disp_all(trackfilter_fill_track_list_cb, NULL, NULL); - if (need_time) - qsort(track_list, track_ct, sizeof(*track_list), trackfilter_init_qsort_cb); - } + track_ct = 0; + track_pts = 0; + + // Perform segmenting first. + if (opt_segment) { + track_disp_all(trackfilter_segment_head, NULL, NULL); + } + + if (count > 0) { + track_list = (trkflt_t *) xcalloc(count, sizeof(*track_list)); + + /* check all tracks for time and order (except merging) */ + + track_disp_all(trackfilter_fill_track_list_cb, NULL, NULL); + if (need_time) { + qsort(track_list, track_ct, sizeof(*track_list), trackfilter_init_qsort_cb); + } + } } static void -trackfilter_deinit(void) +trackfilter_deinit(void) { - if (track_list != NULL) - { - xfree(track_list); - track_list = NULL; - } - track_ct = 0; - track_pts = 0; + if (track_list != NULL) { + xfree(track_list); + track_list = NULL; + } + track_ct = 0; + track_pts = 0; } /******************************************************************************* * trackfilter_process: called from gpsbabel central engine *******************************************************************************/ -static void +static void trackfilter_process(void) { - int opts, something_done; - - if (track_ct == 0) return; /* no track(s), no fun */ - - opts = trackfilter_opt_count(); - if (opts == 0) opts = -1; /* flag for do "pack" by default */ - - if (opt_name != NULL) - { - if (--opts == 0) return; - } - - if (opt_move != NULL) /* Correct timestamps before any other op */ - { - trackfilter_move(); - if (--opts == 0) return; - } - - if ( opt_speed || opt_course || opt_fix ) { - trackfilter_synth(); - if ( opt_speed ) opts--; - if ( opt_course ) opts--; - if ( opt_fix ) opts--; - if ( !opts ) return; - } - - if ((opt_faketime != NULL)) - { - opts--; - - trackfilter_faketime(); - - if (opts == 0) return; - - trackfilter_deinit(); /* reinitialize */ - trackfilter_init(NULL); - - if (track_ct == 0) return; /* no more track(s), no more fun */ - } - - if ((opt_stop != NULL) || (opt_start != NULL)) - { - if (opt_start != NULL) opts--; - if (opt_stop != NULL) opts--; - - trackfilter_range(); - - if (opts == 0) return; - - trackfilter_deinit(); /* reinitialize */ - trackfilter_init(NULL); - - if (track_ct == 0) return; /* no more track(s), no more fun */ - - } - - if (opt_seg2trk != NULL) - { - trackfilter_seg2trk(); - if (--opts == 0) return; - - trackfilter_deinit(); /* reinitialize */ - trackfilter_init(NULL); - } - - if (opt_trk2seg != NULL) - { - trackfilter_trk2seg(); - if (--opts == 0) return; - } - - if (opt_title != NULL) - { - if (--opts == 0) - { - trackfilter_title(); - return; - } - } - - something_done = 0; - - if ((opt_pack != NULL) || (opts == -1)) /* call our default option */ - { - trackfilter_pack(); - something_done = 1; - } - else if (opt_merge != NULL) - { - trackfilter_merge(); - something_done = 1; - } - - if ((something_done == 1) && (--opts <= 0)) - { - if (opt_title != NULL) - trackfilter_title(); - return; - } - - if ((opt_split != NULL) || (opt_sdistance != NULL)) - { - if (track_ct > 1) - fatal(MYNAME "-split: Cannot split more than one track, please pack (or merge) before!\n"); - - trackfilter_split(); - } + int opts, something_done; + + if (track_ct == 0) { + return; /* no track(s), no fun */ + } + + opts = trackfilter_opt_count(); + if (opts == 0) { + opts = -1; /* flag for do "pack" by default */ + } + + if (opt_name != NULL) { + if (--opts == 0) { + return; + } + } + + if (opt_move != NULL) { /* Correct timestamps before any other op */ + trackfilter_move(); + if (--opts == 0) { + return; + } + } + + if (opt_speed || opt_course || opt_fix) { + trackfilter_synth(); + if (opt_speed) { + opts--; + } + if (opt_course) { + opts--; + } + if (opt_fix) { + opts--; + } + if (!opts) { + return; + } + } + + if ((opt_faketime != NULL)) { + opts--; + + trackfilter_faketime(); + + if (opts == 0) { + return; + } + + trackfilter_deinit(); /* reinitialize */ + trackfilter_init(NULL); + + if (track_ct == 0) { + return; /* no more track(s), no more fun */ + } + } + + if ((opt_stop != NULL) || (opt_start != NULL)) { + if (opt_start != NULL) { + opts--; + } + if (opt_stop != NULL) { + opts--; + } + + trackfilter_range(); + + if (opts == 0) { + return; + } + + trackfilter_deinit(); /* reinitialize */ + trackfilter_init(NULL); + + if (track_ct == 0) { + return; /* no more track(s), no more fun */ + } + + } + + if (opt_seg2trk != NULL) { + trackfilter_seg2trk(); + if (--opts == 0) { + return; + } + + trackfilter_deinit(); /* reinitialize */ + trackfilter_init(NULL); + } + + if (opt_trk2seg != NULL) { + trackfilter_trk2seg(); + if (--opts == 0) { + return; + } + } + + if (opt_title != NULL) { + if (--opts == 0) { + trackfilter_title(); + return; + } + } + + something_done = 0; + + if ((opt_pack != NULL) || (opts == -1)) { /* call our default option */ + trackfilter_pack(); + something_done = 1; + } else if (opt_merge != NULL) { + trackfilter_merge(); + something_done = 1; + } + + if ((something_done == 1) && (--opts <= 0)) { + if (opt_title != NULL) { + trackfilter_title(); + } + return; + } + + if ((opt_split != NULL) || (opt_sdistance != NULL)) { + if (track_ct > 1) { + fatal(MYNAME "-split: Cannot split more than one track, please pack (or merge) before!\n"); + } + + trackfilter_split(); + } } /******************************************************************************************/ filter_vecs_t trackfilter_vecs = { - trackfilter_init, - trackfilter_process, - trackfilter_deinit, - NULL, - trackfilter_args + trackfilter_init, + trackfilter_process, + trackfilter_deinit, + NULL, + trackfilter_args }; /******************************************************************************************/ diff --git a/gpsbabel/transform.c b/gpsbabel/transform.c index 444144454..a8e57e207 100644 --- a/gpsbabel/transform.c +++ b/gpsbabel/transform.c @@ -1,7 +1,7 @@ /* Transformation filter for GPS data. - + Copyright (C) 2006 Olaf Klein, o.b.klein@gpsbabel.org This program is free software; you can redistribute it and/or modify @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */ - + #include "defs.h" #include "filterdefs.h" @@ -37,89 +37,105 @@ static char *opt_routes, *opt_tracks, *opt_waypts, *opt_delete; static arglist_t transform_args[] = { - {"wpt", &opt_waypts, "Transform track(s) or route(s) into waypoint(s) [R/T]", NULL, - ARGTYPE_STRING, ARG_NOMINMAX}, - {"rte", &opt_routes, "Transform waypoint(s) or track(s) into route(s) [W/T]", NULL, - ARGTYPE_STRING, ARG_NOMINMAX}, - {"trk", &opt_tracks, "Transform waypoint(s) or route(s) into tracks(s) [W/R]", NULL, - ARGTYPE_STRING, ARG_NOMINMAX}, - {"del", &opt_delete, "Delete source data after transformation", "N", - ARGTYPE_BOOL, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "wpt", &opt_waypts, "Transform track(s) or route(s) into waypoint(s) [R/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "rte", &opt_routes, "Transform waypoint(s) or track(s) into route(s) [W/T]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "trk", &opt_tracks, "Transform waypoint(s) or route(s) into tracks(s) [W/R]", NULL, + ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "del", &opt_delete, "Delete source data after transformation", "N", + ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void transform_waypoints(void) { - queue *elem, *tmp; - route_head *rte; - - rte = route_head_alloc(); - switch(current_target) { - case 'R': route_add_head(rte); break; - case 'T': track_add_head(rte); break; - } - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) - { - waypoint *wpt = (waypoint *) elem; - - wpt = waypt_dupe(wpt); - switch(current_target) { - case 'R': route_add_wpt(rte, wpt); break; - case 'T': track_add_wpt(rte, wpt); break; - } - } + queue *elem, *tmp; + route_head *rte; + + rte = route_head_alloc(); + switch (current_target) { + case 'R': + route_add_head(rte); + break; + case 'T': + track_add_head(rte); + break; + } + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypoint *wpt = (waypoint *) elem; + + wpt = waypt_dupe(wpt); + switch (current_target) { + case 'R': + route_add_wpt(rte, wpt); + break; + case 'T': + track_add_wpt(rte, wpt); + break; + } + } } static void transform_rte_disp_hdr_cb(const route_head *rte) { - if (current_target == 'T') { - current_trk = route_head_alloc(); - track_add_head(current_trk); - if (rte->rte_name && *rte->rte_name) { - xasprintf(¤t_trk->rte_desc, "Generated from route %s", rte->rte_name); - current_trk->rte_name = xstrdup(rte->rte_name); /* name the new trk */ - } - } + if (current_target == 'T') { + current_trk = route_head_alloc(); + track_add_head(current_trk); + if (rte->rte_name && *rte->rte_name) { + xasprintf(¤t_trk->rte_desc, "Generated from route %s", rte->rte_name); + current_trk->rte_name = xstrdup(rte->rte_name); /* name the new trk */ + } + } } static void transform_trk_disp_hdr_cb(const route_head *trk) { - if (current_target == 'R') { - current_rte = route_head_alloc(); - route_add_head(current_rte); - if (trk->rte_name && *trk->rte_name) { - xasprintf(¤t_rte->rte_desc, "Generated from track %s", trk->rte_name); - current_rte->rte_name = xstrdup(trk->rte_name); /* name the new rte */ - } - } + if (current_target == 'R') { + current_rte = route_head_alloc(); + route_add_head(current_rte); + if (trk->rte_name && *trk->rte_name) { + xasprintf(¤t_rte->rte_desc, "Generated from track %s", trk->rte_name); + current_rte->rte_name = xstrdup(trk->rte_name); /* name the new rte */ + } + } } static void transform_any_disp_wpt_cb(const waypoint *wpt) { - waypoint *temp = waypt_dupe(wpt); - if (current_target == 'R') - route_add_wpt(current_rte, temp); - else if (current_target == 'T') - track_add_wpt(current_trk, temp); - else - waypt_add(temp); + waypoint *temp = waypt_dupe(wpt); + if (current_target == 'R') { + route_add_wpt(current_rte, temp); + } else if (current_target == 'T') { + track_add_wpt(current_trk, temp); + } else { + waypt_add(temp); + } } static void transform_routes(void) { - route_disp_all(transform_rte_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); + route_disp_all(transform_rte_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); } static void transform_tracks(void) { - track_disp_all(transform_trk_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); + track_disp_all(transform_trk_disp_hdr_cb, NULL, transform_any_disp_wpt_cb); } /******************************************************************************* @@ -127,75 +143,87 @@ transform_tracks(void) *******************************************************************************/ static void -transform_init(const char *args) +transform_init(const char *args) { } static void -transform_deinit(void) +transform_deinit(void) { } -static void +static void transform_process(void) { - int delete_after = (opt_delete && (*opt_delete == '1')) ? 1 : 0; - - if (opt_waypts != NULL) { - current_target = 'W'; - switch(toupper(*opt_waypts)) { - case 'R': - transform_routes(); - if (delete_after) route_flush_all_routes(); - break; - case 'T': - transform_tracks(); - if (delete_after) route_flush_all_tracks(); - break; - default: - fatal(MYNAME ": Invalid option value (%s)!\n", opt_waypts); - } - } - if (opt_routes != NULL) { - current_target = 'R'; - switch(toupper(*opt_routes)) { - case 'W': - transform_waypoints(); - if (delete_after) waypt_flush_all(); - break; - case 'T': - transform_tracks(); - if (delete_after) route_flush_all_tracks(); - break; - default: - fatal(MYNAME ": Invalid option value (%s)!\n", opt_routes); - } - } - if (opt_tracks != NULL) { - current_target = 'T'; - switch(toupper(*opt_tracks)) { - case 'W': - transform_waypoints(); - if (delete_after) waypt_flush_all(); - break; - case 'R': - transform_routes(); - if (delete_after) route_flush_all_routes(); - break; - default: - fatal(MYNAME ": Invalid option value (%s)!\n", opt_tracks); - } - } + int delete_after = (opt_delete && (*opt_delete == '1')) ? 1 : 0; + + if (opt_waypts != NULL) { + current_target = 'W'; + switch (toupper(*opt_waypts)) { + case 'R': + transform_routes(); + if (delete_after) { + route_flush_all_routes(); + } + break; + case 'T': + transform_tracks(); + if (delete_after) { + route_flush_all_tracks(); + } + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_waypts); + } + } + if (opt_routes != NULL) { + current_target = 'R'; + switch (toupper(*opt_routes)) { + case 'W': + transform_waypoints(); + if (delete_after) { + waypt_flush_all(); + } + break; + case 'T': + transform_tracks(); + if (delete_after) { + route_flush_all_tracks(); + } + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_routes); + } + } + if (opt_tracks != NULL) { + current_target = 'T'; + switch (toupper(*opt_tracks)) { + case 'W': + transform_waypoints(); + if (delete_after) { + waypt_flush_all(); + } + break; + case 'R': + transform_routes(); + if (delete_after) { + route_flush_all_routes(); + } + break; + default: + fatal(MYNAME ": Invalid option value (%s)!\n", opt_tracks); + } + } } /*******************************************************************************/ filter_vecs_t transform_vecs = { - transform_init, - transform_process, - transform_deinit, - NULL, - transform_args + transform_init, + transform_process, + transform_deinit, + NULL, + transform_args }; /*******************************************************************************/ diff --git a/gpsbabel/unicsv.c b/gpsbabel/unicsv.c index 197b0bbdc..819a84032 100644 --- a/gpsbabel/unicsv.c +++ b/gpsbabel/unicsv.c @@ -42,79 +42,79 @@ /* GPSBabel internal and calculated fields */ typedef enum { - fld_shortname = 0, - fld_latitude, - fld_longitude, - fld_description, - fld_notes, - fld_url, - fld_altitude, - fld_utm_zone, - fld_utm_zone_char, - fld_utm_northing, - fld_utm_easting, - fld_utm, - fld_bng, - fld_bng_zone, - fld_bng_northing, - fld_bng_easting, - fld_swiss, - fld_swiss_northing, - fld_swiss_easting, - fld_hdop, - fld_pdop, - fld_vdop, - fld_sat, - fld_fix, - fld_utc_date, - fld_utc_time, - fld_course, - fld_speed, - fld_temperature, - fld_temperature_f, - fld_heartrate, - fld_cadence, - fld_proximity, - fld_depth, - fld_symbol, - fld_date, - fld_time, - fld_datetime, - fld_iso_time, - fld_year, - fld_month, - fld_day, - fld_hour, - fld_min, - fld_sec, - fld_ns, - fld_ew, - - fld_garmin_city, - fld_garmin_postal_code, - fld_garmin_state, - fld_garmin_country, - fld_garmin_addr, - fld_garmin_phone_nr, - fld_garmin_phone_nr2, - fld_garmin_fax_nr, - fld_garmin_email, - fld_garmin_facility, + fld_shortname = 0, + fld_latitude, + fld_longitude, + fld_description, + fld_notes, + fld_url, + fld_altitude, + fld_utm_zone, + fld_utm_zone_char, + fld_utm_northing, + fld_utm_easting, + fld_utm, + fld_bng, + fld_bng_zone, + fld_bng_northing, + fld_bng_easting, + fld_swiss, + fld_swiss_northing, + fld_swiss_easting, + fld_hdop, + fld_pdop, + fld_vdop, + fld_sat, + fld_fix, + fld_utc_date, + fld_utc_time, + fld_course, + fld_speed, + fld_temperature, + fld_temperature_f, + fld_heartrate, + fld_cadence, + fld_proximity, + fld_depth, + fld_symbol, + fld_date, + fld_time, + fld_datetime, + fld_iso_time, + fld_year, + fld_month, + fld_day, + fld_hour, + fld_min, + fld_sec, + fld_ns, + fld_ew, + + fld_garmin_city, + fld_garmin_postal_code, + fld_garmin_state, + fld_garmin_country, + fld_garmin_addr, + fld_garmin_phone_nr, + fld_garmin_phone_nr2, + fld_garmin_fax_nr, + fld_garmin_email, + fld_garmin_facility, #ifdef UNICSV_GC_READY - fld_gc_id, - fld_gc_type, - fld_gc_container, - fld_gc_terr, - fld_gc_diff, - fld_gc_is_archived, - fld_gc_is_available, - fld_gc_exported, - fld_gc_last_found, - fld_gc_placer, - fld_gc_placer_id, - fld_gc_hint, + fld_gc_id, + fld_gc_type, + fld_gc_container, + fld_gc_terr, + fld_gc_diff, + fld_gc_is_archived, + fld_gc_is_available, + fld_gc_exported, + fld_gc_last_found, + fld_gc_placer, + fld_gc_placer_id, + fld_gc_hint, #endif - fld_terminator + fld_terminator } field_e; #define STR_LEFT 1 @@ -126,9 +126,9 @@ typedef enum { #define unicsv_unknown 1e25 typedef struct { - const char *name; - field_e type; - gbuint32 options; + const char *name; + field_e type; + gbuint32 options; } field_t; /* @@ -136,111 +136,111 @@ typedef struct { * we check a second time after replacing underscores with spaces */ static field_t fields_def[] = { - /* unhandled columns */ - { "index", fld_terminator, STR_ANY }, - { "no", fld_terminator, STR_EQUAL }, - { "mini", fld_terminator, STR_ANY }, /* maybe minimum anything, so + /* unhandled columns */ + { "index", fld_terminator, STR_ANY }, + { "no", fld_terminator, STR_EQUAL }, + { "mini", fld_terminator, STR_ANY }, /* maybe minimum anything, so avoid detection as 'min' for minute */ - /* handled columns */ - { "name", fld_shortname, STR_ANY }, - { "title", fld_shortname, STR_ANY }, - { "desc", fld_description, STR_ANY }, - { "notes", fld_notes, STR_ANY }, - { "omment", fld_notes, STR_ANY }, /* works also for German "Kommentar" */ - { "text", fld_notes, STR_ANY }, - { "url", fld_url, STR_ANY }, - { "icon", fld_symbol, STR_ANY }, - { "symb", fld_symbol, STR_ANY }, - { "lat", fld_latitude, STR_ANY }, - { "lon", fld_longitude, STR_ANY }, - { "lng", fld_longitude, STR_ANY }, - { "x", fld_longitude, STR_EQUAL }, - { "y", fld_latitude, STR_EQUAL }, - { "z", fld_altitude, STR_EQUAL }, - { "x_pos", fld_longitude, STR_ANY }, - { "y_pos", fld_latitude, STR_ANY }, - { "alt", fld_altitude, STR_ANY }, - { "ele", fld_altitude, STR_ANY }, - { "height", fld_altitude, STR_ANY }, - { "utm_z", fld_utm_zone, STR_ANY }, - { "utm_c", fld_utm_zone_char, STR_ANY }, - { "utm_zc", fld_utm_zone_char, STR_ANY }, - { "utm_n", fld_utm_northing, STR_ANY }, - { "utm_e", fld_utm_easting, STR_ANY }, - { "utm", fld_utm, STR_EQUAL }, - { "utm_coo", fld_utm, STR_ANY }, - { "utm_pos", fld_utm, STR_ANY }, - { "bng_z", fld_bng_zone, STR_ANY }, - { "bng_n", fld_bng_northing, STR_ANY }, - { "bng_e", fld_bng_easting, STR_ANY }, - { "bng", fld_bng, STR_EQUAL }, - { "bng_coo", fld_bng, STR_ANY }, - { "bng_pos", fld_bng, STR_ANY }, - { "swiss_e", fld_swiss_easting, STR_ANY }, - { "swiss_n", fld_swiss_northing, STR_ANY }, - { "swiss", fld_swiss, STR_EQUAL }, - { "swiss_coo", fld_swiss, STR_ANY }, - { "swiss_pos", fld_swiss, STR_ANY }, - { "hdop", fld_hdop, STR_ANY }, - { "pdop", fld_pdop, STR_ANY }, - { "vdop", fld_vdop, STR_ANY }, - { "sat", fld_sat, STR_ANY }, - { "fix", fld_fix, STR_ANY }, - { "utc_d", fld_utc_date, STR_ANY }, - { "utc_t", fld_utc_time, STR_ANY }, - { "head", fld_course, STR_ANY }, - { "cour", fld_course, STR_ANY }, - { "speed", fld_speed, STR_ANY }, - { "velo", fld_speed, STR_ANY }, - { "geschw", fld_speed, STR_ANY }, /* speed in german */ - { "tempf", fld_temperature_f, STR_EQUAL }, /* degrees fahrenheit */ - { "temp", fld_temperature, STR_ANY }, /* degrees celsius by default */ - { "heart", fld_heartrate, STR_ANY }, - { "caden", fld_cadence, STR_ANY }, - { "prox", fld_proximity, STR_ANY }, - { "depth", fld_depth, STR_ANY }, - { "date", fld_date, STR_ANY }, - { "datum", fld_date, STR_ANY }, - { "time", fld_time, STR_ANY }, - { "zeit", fld_time, STR_ANY }, - { "hour", fld_hour, STR_LEFT }, - { "min", fld_min, STR_LEFT }, - { "sec", fld_sec, STR_LEFT }, - { "year", fld_year, STR_LEFT }, - { "month", fld_month, STR_LEFT }, - { "day", fld_day, STR_LEFT }, - { "n/s", fld_ns, STR_ANY }, - { "e/w", fld_ew, STR_ANY }, - - /* garmin specials */ - { "addr", fld_garmin_addr, STR_ANY }, - { "street", fld_garmin_addr, STR_ANY }, - { "city", fld_garmin_city, STR_ANY }, - { "country", fld_garmin_country, STR_ANY }, - { "post", fld_garmin_postal_code, STR_ANY }, - { "zip", fld_garmin_postal_code, STR_ANY }, - { "phone", fld_garmin_phone_nr, STR_ANY }, - { "phone2", fld_garmin_phone_nr2, STR_ANY }, - { "fax", fld_garmin_fax_nr, STR_ANY }, - { "email", fld_garmin_email, STR_ANY }, - { "state", fld_garmin_state, STR_ANY }, - { "faci", fld_garmin_facility, STR_ANY }, + /* handled columns */ + { "name", fld_shortname, STR_ANY }, + { "title", fld_shortname, STR_ANY }, + { "desc", fld_description, STR_ANY }, + { "notes", fld_notes, STR_ANY }, + { "omment", fld_notes, STR_ANY }, /* works also for German "Kommentar" */ + { "text", fld_notes, STR_ANY }, + { "url", fld_url, STR_ANY }, + { "icon", fld_symbol, STR_ANY }, + { "symb", fld_symbol, STR_ANY }, + { "lat", fld_latitude, STR_ANY }, + { "lon", fld_longitude, STR_ANY }, + { "lng", fld_longitude, STR_ANY }, + { "x", fld_longitude, STR_EQUAL }, + { "y", fld_latitude, STR_EQUAL }, + { "z", fld_altitude, STR_EQUAL }, + { "x_pos", fld_longitude, STR_ANY }, + { "y_pos", fld_latitude, STR_ANY }, + { "alt", fld_altitude, STR_ANY }, + { "ele", fld_altitude, STR_ANY }, + { "height", fld_altitude, STR_ANY }, + { "utm_z", fld_utm_zone, STR_ANY }, + { "utm_c", fld_utm_zone_char, STR_ANY }, + { "utm_zc", fld_utm_zone_char, STR_ANY }, + { "utm_n", fld_utm_northing, STR_ANY }, + { "utm_e", fld_utm_easting, STR_ANY }, + { "utm", fld_utm, STR_EQUAL }, + { "utm_coo", fld_utm, STR_ANY }, + { "utm_pos", fld_utm, STR_ANY }, + { "bng_z", fld_bng_zone, STR_ANY }, + { "bng_n", fld_bng_northing, STR_ANY }, + { "bng_e", fld_bng_easting, STR_ANY }, + { "bng", fld_bng, STR_EQUAL }, + { "bng_coo", fld_bng, STR_ANY }, + { "bng_pos", fld_bng, STR_ANY }, + { "swiss_e", fld_swiss_easting, STR_ANY }, + { "swiss_n", fld_swiss_northing, STR_ANY }, + { "swiss", fld_swiss, STR_EQUAL }, + { "swiss_coo", fld_swiss, STR_ANY }, + { "swiss_pos", fld_swiss, STR_ANY }, + { "hdop", fld_hdop, STR_ANY }, + { "pdop", fld_pdop, STR_ANY }, + { "vdop", fld_vdop, STR_ANY }, + { "sat", fld_sat, STR_ANY }, + { "fix", fld_fix, STR_ANY }, + { "utc_d", fld_utc_date, STR_ANY }, + { "utc_t", fld_utc_time, STR_ANY }, + { "head", fld_course, STR_ANY }, + { "cour", fld_course, STR_ANY }, + { "speed", fld_speed, STR_ANY }, + { "velo", fld_speed, STR_ANY }, + { "geschw", fld_speed, STR_ANY }, /* speed in german */ + { "tempf", fld_temperature_f, STR_EQUAL }, /* degrees fahrenheit */ + { "temp", fld_temperature, STR_ANY }, /* degrees celsius by default */ + { "heart", fld_heartrate, STR_ANY }, + { "caden", fld_cadence, STR_ANY }, + { "prox", fld_proximity, STR_ANY }, + { "depth", fld_depth, STR_ANY }, + { "date", fld_date, STR_ANY }, + { "datum", fld_date, STR_ANY }, + { "time", fld_time, STR_ANY }, + { "zeit", fld_time, STR_ANY }, + { "hour", fld_hour, STR_LEFT }, + { "min", fld_min, STR_LEFT }, + { "sec", fld_sec, STR_LEFT }, + { "year", fld_year, STR_LEFT }, + { "month", fld_month, STR_LEFT }, + { "day", fld_day, STR_LEFT }, + { "n/s", fld_ns, STR_ANY }, + { "e/w", fld_ew, STR_ANY }, + + /* garmin specials */ + { "addr", fld_garmin_addr, STR_ANY }, + { "street", fld_garmin_addr, STR_ANY }, + { "city", fld_garmin_city, STR_ANY }, + { "country", fld_garmin_country, STR_ANY }, + { "post", fld_garmin_postal_code, STR_ANY }, + { "zip", fld_garmin_postal_code, STR_ANY }, + { "phone", fld_garmin_phone_nr, STR_ANY }, + { "phone2", fld_garmin_phone_nr2, STR_ANY }, + { "fax", fld_garmin_fax_nr, STR_ANY }, + { "email", fld_garmin_email, STR_ANY }, + { "state", fld_garmin_state, STR_ANY }, + { "faci", fld_garmin_facility, STR_ANY }, #ifdef UNICSV_GC_READY - /* geocache details */ - { "gcid", fld_gc_id, STR_ANY }, - { "type", fld_gc_type, STR_ANY }, - { "cont", fld_gc_container, STR_ANY }, - { "terr", fld_gc_terr, STR_ANY }, - { "diff", fld_gc_diff, STR_ANY }, - { "arch", fld_gc_is_archived, STR_ANY }, - { "avail", fld_gc_is_available, STR_ANY }, - { "exported", fld_gc_exported, STR_ANY }, - { "found", fld_gc_last_found, STR_ANY }, - { "placer", fld_gc_placer, STR_ANY }, - { "placer_id", fld_gc_placer_id, STR_ANY }, - { "hint", fld_gc_hint, STR_ANY }, + /* geocache details */ + { "gcid", fld_gc_id, STR_ANY }, + { "type", fld_gc_type, STR_ANY }, + { "cont", fld_gc_container, STR_ANY }, + { "terr", fld_gc_terr, STR_ANY }, + { "diff", fld_gc_diff, STR_ANY }, + { "arch", fld_gc_is_archived, STR_ANY }, + { "avail", fld_gc_is_available, STR_ANY }, + { "exported", fld_gc_exported, STR_ANY }, + { "found", fld_gc_last_found, STR_ANY }, + { "placer", fld_gc_placer, STR_ANY }, + { "placer_id", fld_gc_placer_id, STR_ANY }, + { "hint", fld_gc_hint, STR_ANY }, #endif - { NULL, fld_terminator, 0 } + { NULL, fld_terminator, 0 } }; static field_e *unicsv_fields_tab; @@ -260,19 +260,32 @@ static char unicsv_detect; static int llprec; static arglist_t unicsv_args[] = { - {"datum", &opt_datum, "GPS datum (def. WGS 84)", - "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, - {"grid", &opt_grid, "Write position using this grid.", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"utc", &opt_utc, "Write timestamps with offset x to UTC time", - NULL, ARGTYPE_INT, "-23", "+23"}, - {"format", &opt_format, "Write name(s) of format(s) from input session(s)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"filename", &opt_filename, "Write filename(s) from input session(s)", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"prec", &opt_prec, "Precision of numerical coordinates (no grid set)", - "6", ARGTYPE_INT | ARGTYPE_HIDDEN, "0", "15"}, - ARG_TERMINATOR }; + { + "datum", &opt_datum, "GPS datum (def. WGS 84)", + "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "grid", &opt_grid, "Write position using this grid.", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "utc", &opt_utc, "Write timestamps with offset x to UTC time", + NULL, ARGTYPE_INT, "-23", "+23" + }, + { + "format", &opt_format, "Write name(s) of format(s) from input session(s)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "filename", &opt_filename, "Write filename(s) from input session(s)", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "prec", &opt_prec, "Precision of numerical coordinates (no grid set)", + "6", ARGTYPE_INT | ARGTYPE_HIDDEN, "0", "15" + }, + ARG_TERMINATOR +}; /* helpers */ @@ -284,41 +297,51 @@ static arglist_t unicsv_args[] = { static int unicsv_strrcmp(const char *s1, const char *s2) { - int l1, l2; - - l1 = strlen(s1); - l2 = strlen(s2); - if ((l1 - l2) >= 0) - return strcmp(s1 + (l1 - l2), s2); - else - return 1; /* false */ + int l1, l2; + + l1 = strlen(s1); + l2 = strlen(s2); + if ((l1 - l2) >= 0) { + return strcmp(s1 + (l1 - l2), s2); + } else { + return 1; /* false */ + } } static int unicsv_parse_gc_id(const char *str) { - int res = 0; - - if (str && (str[0] == 'G') && (str[1] == 'C')) { - int base; - char cx; - - str += 2; - if (strlen(str) > 4) base = 31; - else base = (*str < 'G') ? 16 : 31; - - while ((cx = *str++)) { - int num; - - if ((cx >= '0') && (cx <= '9')) num = cx - '0'; - else if ((cx >= 'A') && (cx <= 'Z')) num = cx - 'A' + 10; - else break; - - res = (res * base) + num; - } - if (base == 31) res -= 411120; - } - return res; + int res = 0; + + if (str && (str[0] == 'G') && (str[1] == 'C')) { + int base; + char cx; + + str += 2; + if (strlen(str) > 4) { + base = 31; + } else { + base = (*str < 'G') ? 16 : 31; + } + + while ((cx = *str++)) { + int num; + + if ((cx >= '0') && (cx <= '9')) { + num = cx - '0'; + } else if ((cx >= 'A') && (cx <= 'Z')) { + num = cx - 'A' + 10; + } else { + break; + } + + res = (res * base) + num; + } + if (base == 31) { + res -= 411120; + } + } + return res; } // static int unicsv_parse_time(const char *str, int *msec, time_t *date); @@ -326,103 +349,109 @@ unicsv_parse_gc_id(const char *str) static time_t unicsv_parse_date(const char *str, int *consumed) { - int p1, p2, p3, ct; - char sep[2]; - struct tm tm; - int lconsumed = 0; - - memset(&tm, 0, sizeof(tm)); - ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d%n", &p1, sep, &p2, sep, &p3, &lconsumed); - if (consumed && lconsumed) { - *consumed = lconsumed; - } - if (ct != 5) { - if (consumed) { /* don't stop here; it's only sniffing */ - *consumed = 0; /* for a possible date */ - return 0; - } - fatal(MYNAME ": Could not parse date string (%s).\n", str); - } - - if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ - tm.tm_year = p1; - tm.tm_mon = p2; - tm.tm_mday = p3; - } - else if (sep[0] == '.') { /* Germany and any other countries */ - tm.tm_mday = p1; /* have a fixed D.M.Y format */ - tm.tm_mon = p2; - tm.tm_year = p3; - } - else { - tm.tm_mday = p2; - tm.tm_mon = p1; - tm.tm_year = p3; - } - if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { - if (tm.tm_year < 70) tm.tm_year += 2000; - else tm.tm_year += 1900; - } - /* some low-level checks */ - if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) { - if (consumed) { - *consumed = 0; - return 0; /* don't stop here */ - } - fatal(MYNAME ": Could not parse date string (%s).\n", str); - } - - tm.tm_year -= 1900; - tm.tm_mon -= 1; - - return mkgmtime(&tm); + int p1, p2, p3, ct; + char sep[2]; + struct tm tm; + int lconsumed = 0; + + memset(&tm, 0, sizeof(tm)); + ct = sscanf(str, "%d%1[-.//]%d%1[-.//]%d%n", &p1, sep, &p2, sep, &p3, &lconsumed); + if (consumed && lconsumed) { + *consumed = lconsumed; + } + if (ct != 5) { + if (consumed) { /* don't stop here; it's only sniffing */ + *consumed = 0; /* for a possible date */ + return 0; + } + fatal(MYNAME ": Could not parse date string (%s).\n", str); + } + + if ((p1 > 99) || (sep[0] == '-')) { /* Y-M-D (iso like) */ + tm.tm_year = p1; + tm.tm_mon = p2; + tm.tm_mday = p3; + } else if (sep[0] == '.') { /* Germany and any other countries */ + tm.tm_mday = p1; /* have a fixed D.M.Y format */ + tm.tm_mon = p2; + tm.tm_year = p3; + } else { + tm.tm_mday = p2; + tm.tm_mon = p1; + tm.tm_year = p3; + } + if ((p1 < 100) && (p2 < 100) && (p3 < 100)) { + if (tm.tm_year < 70) { + tm.tm_year += 2000; + } else { + tm.tm_year += 1900; + } + } + /* some low-level checks */ + if ((tm.tm_mon > 12) || (tm.tm_mon < 1) || (tm.tm_mday > 31) || (tm.tm_mday < 1)) { + if (consumed) { + *consumed = 0; + return 0; /* don't stop here */ + } + fatal(MYNAME ": Could not parse date string (%s).\n", str); + } + + tm.tm_year -= 1900; + tm.tm_mon -= 1; + + return mkgmtime(&tm); } static time_t unicsv_parse_time(const char *str, int *msec, time_t *date) { - int hour, min, ct, sec; - int consumed = 0; - double ms; - char sep[2]; - time_t ldate; - - /* If we have somethine we're pretty sure is a date, parse that - * first, skip over it, and pass that back to the caller) - */ - ldate = unicsv_parse_date(str, &consumed); - if (consumed && ldate) { - str += consumed; - if (date) { - *date = ldate; - } - } - - ct = sscanf(str, "%d%1[.://]%d%1[.://]%d%lf", &hour, sep, &min, sep, &sec, &ms); - is_fatal(ct < 5, MYNAME ": Could not parse time string (%s).\n", str); - if (ct == 6) { - *msec = (ms * 1000000) + 0.5; - if (*msec > 999999) { - *msec = 0; - sec++; - } - } - else *msec = 0; - - return ((hour * SECONDS_PER_HOUR) + (min * 60) + (int)sec); + int hour, min, ct, sec; + int consumed = 0; + double ms; + char sep[2]; + time_t ldate; + + /* If we have somethine we're pretty sure is a date, parse that + * first, skip over it, and pass that back to the caller) + */ + ldate = unicsv_parse_date(str, &consumed); + if (consumed && ldate) { + str += consumed; + if (date) { + *date = ldate; + } + } + + ct = sscanf(str, "%d%1[.://]%d%1[.://]%d%lf", &hour, sep, &min, sep, &sec, &ms); + is_fatal(ct < 5, MYNAME ": Could not parse time string (%s).\n", str); + if (ct == 6) { + *msec = (ms * 1000000) + 0.5; + if (*msec > 999999) { + *msec = 0; + sec++; + } + } else { + *msec = 0; + } + + return ((hour * SECONDS_PER_HOUR) + (min * 60) + (int)sec); } #ifdef UNICSV_GC_READY static status_type unicsv_parse_status(const char *str) { - if ((case_ignore_strcmp(str, "true") == 0) || - (case_ignore_strcmp(str, "yes") == 0) || - (*str == '1')) return status_true; - else if ((case_ignore_strcmp(str, "false") == 0) || - (case_ignore_strcmp(str, "no") == 0) || - (*str == '0')) return status_false; - else return status_unknown; + if ((case_ignore_strcmp(str, "true") == 0) || + (case_ignore_strcmp(str, "yes") == 0) || + (*str == '1')) { + return status_true; + } else if ((case_ignore_strcmp(str, "false") == 0) || + (case_ignore_strcmp(str, "no") == 0) || + (*str == '0')) { + return status_false; + } else { + return status_unknown; + } } #endif @@ -430,699 +459,800 @@ unicsv_parse_status(const char *str) static time_t unicsv_adjust_time(const time_t time, time_t *date) { - time_t res = time; - if (date) res += *date; - if (opt_utc) res += atoi(opt_utc) * SECONDS_PER_HOUR; - else { - struct tm tm = *gmtime(&res); - res = mklocaltime(&tm); - } - return res; + time_t res = time; + if (date) { + res += *date; + } + if (opt_utc) { + res += atoi(opt_utc) * SECONDS_PER_HOUR; + } else { + struct tm tm = *gmtime(&res); + res = mklocaltime(&tm); + } + return res; } #endif static char unicsv_compare_fields(char *s, const field_t *f) { - char *name = (char *)f->name; - char *test = s; - char result; - - if (! (f->options & STR_CASE)) { - test = strupper(xstrdup(s)); - name = strupper(xstrdup(f->name)); - } - - if (f->options & STR_EQUAL) { - result = (strcmp(test, name) == 0); - } - else if (f->options & STR_ANY) { - result = (strstr(test, name) != NULL); - } - else { - if (f->options & STR_LEFT) { - result = (strncmp(test, name, strlen(name)) == 0); - } - else if (f->options & STR_RIGHT) { - result = (unicsv_strrcmp(test, name) == 0); - } - else { - result = 0; /* fallback to "FALSE" */ - } - } - - if ((! result) && (strchr(test, ' ') != NULL)) { - /* replace ' ' with '_' and try again */ - char *tmp = gstrsub(test, " ", "_"); - result = unicsv_compare_fields(tmp, f); - xfree(tmp); - } - if ((! result) && (strchr(test, '-') != NULL)) { - /* replace '-' with '_' and try again */ - char *tmp = gstrsub(test, "-", "_"); - result = unicsv_compare_fields(tmp, f); - xfree(tmp); - } - - if (name != f->name) { - xfree(name); - xfree(test); - } - - return result; + char *name = (char *)f->name; + char *test = s; + char result; + + if (!(f->options & STR_CASE)) { + test = strupper(xstrdup(s)); + name = strupper(xstrdup(f->name)); + } + + if (f->options & STR_EQUAL) { + result = (strcmp(test, name) == 0); + } else if (f->options & STR_ANY) { + result = (strstr(test, name) != NULL); + } else { + if (f->options & STR_LEFT) { + result = (strncmp(test, name, strlen(name)) == 0); + } else if (f->options & STR_RIGHT) { + result = (unicsv_strrcmp(test, name) == 0); + } else { + result = 0; /* fallback to "FALSE" */ + } + } + + if ((! result) && (strchr(test, ' ') != NULL)) { + /* replace ' ' with '_' and try again */ + char *tmp = gstrsub(test, " ", "_"); + result = unicsv_compare_fields(tmp, f); + xfree(tmp); + } + if ((! result) && (strchr(test, '-') != NULL)) { + /* replace '-' with '_' and try again */ + char *tmp = gstrsub(test, "-", "_"); + result = unicsv_compare_fields(tmp, f); + xfree(tmp); + } + + if (name != f->name) { + xfree(name); + xfree(test); + } + + return result; } static void unicsv_fondle_header(char *ibuf) { - char *s; - char *buf = NULL; - int i, column; - const cet_cs_vec_t *ascii = &cet_cs_vec_ansi_x3_4_1968; /* us-ascii */ - - /* Convert the entire header to lower case for convenience. - * If we see a tab in that header, we decree it to be tabsep. - */ - unicsv_fieldsep = ","; - for (s = ibuf; *s; s++) { - if (*s == '\t') { - unicsv_fieldsep = "\t"; - } - else if (*s == ';') { - unicsv_fieldsep = ";"; - } - else if (*s == '|') { - unicsv_fieldsep = "|"; - } - else { - continue; - } - break; - } - for (s = ibuf; *s; s++) { - *s = tolower(*s); - } - - /* convert the header line into native ascii */ - if (global_opts.charset != ascii) { - buf = cet_str_any_to_any(ibuf, global_opts.charset, ascii); - ibuf = buf; - } - - column = -1; - while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { - - field_t *f = &fields_def[0]; - - ibuf = NULL; - column++; - unicsv_fields_tab_ct++; - s = lrtrim(s); - - if (column % 4 == 0) { - int sz = (column + 4) * sizeof(*unicsv_fields_tab); - if (column == 0) unicsv_fields_tab = (field_e*) xmalloc(sz); - else unicsv_fields_tab = (field_e*) xrealloc(unicsv_fields_tab, sz); - for (i = 0; i < 4; i++) unicsv_fields_tab[column + i] = fld_terminator; - } - - while (f->name) { - if (unicsv_compare_fields(s, f)) { - unicsv_fields_tab[column] = f->type; - break; - } - f++; - } - if ((! f->name) && global_opts.debug_level) - warning(MYNAME ": Unhandled column \"%s\".\n", s); - - /* handle some special items */ - if (f->type == fld_altitude) { - if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { - unicsv_altscale = FEET_TO_METERS(1); - } - } - if (f->type == fld_depth) { - if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { - unicsv_depthscale = FEET_TO_METERS(1); - } - } - if (f->type == fld_proximity) { - if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { - unicsv_proximityscale = FEET_TO_METERS(1); - } - } - if ((f->type == fld_time) || (f->type == fld_date)) { - if (UNICSV_CONTAINS("iso")) - f->type = fld_iso_time; - } - } - if (buf) xfree(buf); + char *s; + char *buf = NULL; + int i, column; + const cet_cs_vec_t *ascii = &cet_cs_vec_ansi_x3_4_1968; /* us-ascii */ + + /* Convert the entire header to lower case for convenience. + * If we see a tab in that header, we decree it to be tabsep. + */ + unicsv_fieldsep = ","; + for (s = ibuf; *s; s++) { + if (*s == '\t') { + unicsv_fieldsep = "\t"; + } else if (*s == ';') { + unicsv_fieldsep = ";"; + } else if (*s == '|') { + unicsv_fieldsep = "|"; + } else { + continue; + } + break; + } + for (s = ibuf; *s; s++) { + *s = tolower(*s); + } + + /* convert the header line into native ascii */ + if (global_opts.charset != ascii) { + buf = cet_str_any_to_any(ibuf, global_opts.charset, ascii); + ibuf = buf; + } + + column = -1; + while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { + + field_t *f = &fields_def[0]; + + ibuf = NULL; + column++; + unicsv_fields_tab_ct++; + s = lrtrim(s); + + if (column % 4 == 0) { + int sz = (column + 4) * sizeof(*unicsv_fields_tab); + if (column == 0) { + unicsv_fields_tab = (field_e*) xmalloc(sz); + } else { + unicsv_fields_tab = (field_e*) xrealloc(unicsv_fields_tab, sz); + } + for (i = 0; i < 4; i++) { + unicsv_fields_tab[column + i] = fld_terminator; + } + } + + while (f->name) { + if (unicsv_compare_fields(s, f)) { + unicsv_fields_tab[column] = f->type; + break; + } + f++; + } + if ((! f->name) && global_opts.debug_level) { + warning(MYNAME ": Unhandled column \"%s\".\n", s); + } + + /* handle some special items */ + if (f->type == fld_altitude) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_altscale = FEET_TO_METERS(1); + } + } + if (f->type == fld_depth) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_depthscale = FEET_TO_METERS(1); + } + } + if (f->type == fld_proximity) { + if (UNICSV_CONTAINS("ft") || UNICSV_CONTAINS("feet")) { + unicsv_proximityscale = FEET_TO_METERS(1); + } + } + if ((f->type == fld_time) || (f->type == fld_date)) { + if (UNICSV_CONTAINS("iso")) { + f->type = fld_iso_time; + } + } + } + if (buf) { + xfree(buf); + } } static void unicsv_rd_init(const char *fname) { - char *c; - unicsv_altscale = 1.0; - unicsv_depthscale = 1.0; - unicsv_proximityscale = 1.0; - - unicsv_fields_tab = NULL; - unicsv_fields_tab_ct = 0; - unicsv_data_type = global_opts.objective; - unicsv_detect = (! (global_opts.masked_objective & (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))); - - unicsv_track = unicsv_route = NULL; - unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); - - fin = gbfopen(fname, "rb", MYNAME); - - if ((c = gbfgetstr(fin))) - unicsv_fondle_header(c); - else - unicsv_fieldsep = NULL; - if (fin->unicode) cet_convert_init(CET_CHARSET_UTF8, 1); + char *c; + unicsv_altscale = 1.0; + unicsv_depthscale = 1.0; + unicsv_proximityscale = 1.0; + + unicsv_fields_tab = NULL; + unicsv_fields_tab_ct = 0; + unicsv_data_type = global_opts.objective; + unicsv_detect = (!(global_opts.masked_objective & (WPTDATAMASK | TRKDATAMASK | RTEDATAMASK | POSNDATAMASK))); + + unicsv_track = unicsv_route = NULL; + unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); + + fin = gbfopen(fname, "rb", MYNAME); + + if ((c = gbfgetstr(fin))) { + unicsv_fondle_header(c); + } else { + unicsv_fieldsep = NULL; + } + if (fin->unicode) { + cet_convert_init(CET_CHARSET_UTF8, 1); + } } static void unicsv_rd_deinit(void) { - gbfclose(fin); - if (unicsv_fields_tab) xfree(unicsv_fields_tab); + gbfclose(fin); + if (unicsv_fields_tab) { + xfree(unicsv_fields_tab); + } } static void unicsv_parse_one_line(char *ibuf) { - char *s; - waypoint *wpt = NULL; - int column; - int utm_zone = -9999; - double utm_easting = 0; - double utm_northing = 0; - char utm_zc = 'N'; - char bng_zone[3] = ""; - double bng_easting = 0; - double bng_northing = 0; - double swiss_easting = unicsv_unknown; - double swiss_northing = unicsv_unknown; - int checked = 0; - time_t date = -1, time = -1; - int msec = -1; - char is_localtime = 0; - garmin_fs_t *gmsd; - double d; - struct tm ymd; - int src_datum = unicsv_datum_idx; - int ns = 1; - int ew = 1; + char *s; + waypoint *wpt = NULL; + int column; + int utm_zone = -9999; + double utm_easting = 0; + double utm_northing = 0; + char utm_zc = 'N'; + char bng_zone[3] = ""; + double bng_easting = 0; + double bng_northing = 0; + double swiss_easting = unicsv_unknown; + double swiss_northing = unicsv_unknown; + int checked = 0; + time_t date = -1, time = -1; + int msec = -1; + char is_localtime = 0; + garmin_fs_t *gmsd; + double d; + struct tm ymd; + int src_datum = unicsv_datum_idx; + int ns = 1; + int ew = 1; #ifdef UNICSV_GC_READY - geocache_data *gc_data = NULL; + geocache_data *gc_data = NULL; #endif - wpt = waypt_new(); - wpt->latitude = unicsv_unknown; - wpt->longitude = unicsv_unknown; - memset(&ymd, 0, sizeof(ymd)); - - column = -1; - while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { - - if (column > unicsv_fields_tab_ct) break; /* ignore extra fields on line */ - - ibuf = NULL; - - column++; - checked++; - - s = lrtrim(s); - if (! *s) continue; /* skip empty columns */ - switch(unicsv_fields_tab[column]) { - - case fld_time: - case fld_date: - case fld_datetime: - /* switch column type if it looks like an iso time string */ - if (strchr(s, 'T')) - unicsv_fields_tab[column] = fld_iso_time; - break; - default: ; - } - - - switch(unicsv_fields_tab[column]) { - - case fld_latitude: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 1 ); - wpt->latitude = wpt->latitude * ns; - break; - - case fld_longitude: - human_to_dec( s, &wpt->latitude, &wpt->longitude, 2 ); - wpt->longitude = wpt->longitude * ew; - break; - - case fld_shortname: - wpt->shortname = xstrdup(s); - break; - - case fld_description: - wpt->description = xstrdup(s); - break; - - case fld_notes: - wpt->notes = xstrdup(s); - break; - - case fld_url: - wpt->url = xstrdup(s); - break; - - case fld_altitude: - if (parse_distance(s, &d, unicsv_altscale, MYNAME)) { - if (fabs(d) < fabs(unknown_alt)) - wpt->altitude = d; - } - break; - - case fld_utm_zone: - utm_zone = atoi(s); - break; - - case fld_utm_easting: - utm_easting = atof(s); - break; - - case fld_utm_northing: - utm_northing = atof(s); - break; - - case fld_utm_zone_char: - utm_zc = toupper(s[0]); - break; - - case fld_utm: - parse_coordinates(s, unicsv_datum_idx, grid_utm, - &wpt->latitude, &wpt->longitude, MYNAME); - /* coordinates from parse_coordinates are in WGS84 - don't convert a second time */ - src_datum = DATUM_WGS84; - break; - - case fld_bng: - parse_coordinates(s, DATUM_OSGB36, grid_bng, - &wpt->latitude, &wpt->longitude, MYNAME); - /* coordinates from parse_coordinates are in WGS84 - don't convert a second time */ - src_datum = DATUM_WGS84; - break; - - case fld_bng_zone: - strncpy(bng_zone, s, sizeof(bng_zone)); - strupper(bng_zone); - break; - - case fld_bng_northing: - bng_northing = atof(s); - break; - - case fld_bng_easting: - bng_easting = atof(s); - break; - - case fld_swiss: - parse_coordinates(s, DATUM_WGS84, grid_swiss, - &wpt->latitude, &wpt->longitude, MYNAME); - /* coordinates from parse_coordinates are in WGS84 - don't convert a second time */ - src_datum = DATUM_WGS84; - break; - - case fld_swiss_easting: - swiss_easting = atof(s); - break; - - case fld_swiss_northing: - swiss_northing = atof(s); - break; - - case fld_hdop: - wpt->hdop = atof(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_pdop: - wpt->pdop = atof(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_vdop: - wpt->vdop = atof(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_sat: - wpt->sat = atoi(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_fix: - if (unicsv_detect) unicsv_data_type = trkdata; - if (case_ignore_strcmp(s, "none") == 0) - wpt->fix = fix_none; - else if (case_ignore_strcmp(s, "2d") == 0) - wpt->fix = fix_2d; - else if (case_ignore_strcmp(s, "3d") == 0) - wpt->fix = fix_3d; - else if (case_ignore_strcmp(s, "dgps") == 0) - wpt->fix = fix_dgps; - else if (case_ignore_strcmp(s, "pps") == 0) - wpt->fix = fix_pps; - else wpt->fix = fix_unknown; - break; - - case fld_utc_date: - if ((is_localtime < 2) && (date < 0)) { - date = unicsv_parse_date(s, NULL); - is_localtime = 0; - } - break; - - case fld_utc_time: - if ((is_localtime < 2) && (time < 0)) { - time = unicsv_parse_time(s, &msec, &date); - is_localtime = 0; - } - break; - - case fld_speed: - if (parse_speed(s, &d, 1.0, MYNAME)) { - WAYPT_SET(wpt, speed, d); - if (unicsv_detect) - unicsv_data_type = trkdata; - } - break; - - case fld_course: - WAYPT_SET(wpt, course, atof(s)); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_temperature: - d = atof(s); - if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, d); - break; - - case fld_temperature_f: - d = atof(s); - if (fabs(d) < 999999) WAYPT_SET(wpt, temperature, FAHRENHEIT_TO_CELSIUS(d)); - break; - - case fld_heartrate: - wpt->heartrate = atoi(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_cadence: - wpt->cadence = atoi(s); - if (unicsv_detect) unicsv_data_type = trkdata; - break; - - case fld_proximity: - if (parse_distance(s, &d, unicsv_proximityscale, MYNAME)) - WAYPT_SET(wpt, proximity, d); - break; - - case fld_depth: - if (parse_distance(s, &d, unicsv_depthscale, MYNAME)) - WAYPT_SET(wpt, depth, d); - break; - - case fld_symbol: - wpt->icon_descr = xstrdup(s); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - break; - - case fld_iso_time: - is_localtime = 2; /* fix result */ - wpt->creation_time = xml_parse_time(s, &wpt->microseconds); - break; - - case fld_time: - if ((is_localtime < 2) && (time < 0)) { - time = unicsv_parse_time(s, &msec, &date); - is_localtime = 1; - } - break; - - case fld_date: - if ((is_localtime < 2) && (date < 0)) { - date = unicsv_parse_date(s, NULL); - is_localtime = 1; - } - break; - - case fld_year: - ymd.tm_year = atoi(s); - break; - - case fld_month: - ymd.tm_mon = atoi(s); - break; - - case fld_day: - ymd.tm_mday = atoi(s); - break; - - case fld_hour: - ymd.tm_hour = atoi(s); - break; - - case fld_min: - ymd.tm_min = atoi(s); - break; - - case fld_sec: - ymd.tm_sec = atoi(s); - break; - - case fld_datetime: - if ((is_localtime < 2) && (date < 0) && (time < 0)) { - time = unicsv_parse_time(s, &msec, &date); - is_localtime = 1; - } - break; - - case fld_ns: - ns = tolower(s[0]) == 'n' ? 1 : -1; - wpt->latitude *= ns; - break; - - case fld_ew: - ew = tolower(s[0]) == 'e' ? 1 : -1; - wpt->longitude *= ew; - break; - - case fld_garmin_city: - case fld_garmin_postal_code: - case fld_garmin_state: - case fld_garmin_country: - case fld_garmin_addr: - case fld_garmin_phone_nr: - case fld_garmin_phone_nr2: - case fld_garmin_fax_nr: - case fld_garmin_email: - case fld_garmin_facility: - gmsd = GMSD_FIND(wpt); - if (! gmsd) { - gmsd = garmin_fs_alloc(-1); - fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); - } - switch(unicsv_fields_tab[column]) { - case fld_garmin_city: GMSD_SETSTR(city, s); break; - case fld_garmin_postal_code: GMSD_SETSTR(postal_code, s); break; - case fld_garmin_state: GMSD_SETSTR(state, s); break; - case fld_garmin_country: GMSD_SETSTR(country, s); break; - case fld_garmin_addr: GMSD_SETSTR(addr, s); break; - case fld_garmin_phone_nr: GMSD_SETSTR(phone_nr, s); break; - case fld_garmin_phone_nr2: GMSD_SETSTR(phone_nr2, s); break; - case fld_garmin_fax_nr: GMSD_SETSTR(fax_nr, s); break; - case fld_garmin_email: GMSD_SETSTR(email, s); break; - case fld_garmin_facility: GMSD_SETSTR(facility, s); break; - default: break; - } - break; + wpt = waypt_new(); + wpt->latitude = unicsv_unknown; + wpt->longitude = unicsv_unknown; + memset(&ymd, 0, sizeof(ymd)); + + column = -1; + while ((s = csv_lineparse(ibuf, unicsv_fieldsep, "\"", 0))) { + + if (column > unicsv_fields_tab_ct) { + break; /* ignore extra fields on line */ + } + + ibuf = NULL; + + column++; + checked++; + + s = lrtrim(s); + if (! *s) { + continue; /* skip empty columns */ + } + switch (unicsv_fields_tab[column]) { + + case fld_time: + case fld_date: + case fld_datetime: + /* switch column type if it looks like an iso time string */ + if (strchr(s, 'T')) { + unicsv_fields_tab[column] = fld_iso_time; + } + break; + default: + ; + } + + + switch (unicsv_fields_tab[column]) { + + case fld_latitude: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 1); + wpt->latitude = wpt->latitude * ns; + break; + + case fld_longitude: + human_to_dec(s, &wpt->latitude, &wpt->longitude, 2); + wpt->longitude = wpt->longitude * ew; + break; + + case fld_shortname: + wpt->shortname = xstrdup(s); + break; + + case fld_description: + wpt->description = xstrdup(s); + break; + + case fld_notes: + wpt->notes = xstrdup(s); + break; + + case fld_url: + wpt->url = xstrdup(s); + break; + + case fld_altitude: + if (parse_distance(s, &d, unicsv_altscale, MYNAME)) { + if (fabs(d) < fabs(unknown_alt)) { + wpt->altitude = d; + } + } + break; + + case fld_utm_zone: + utm_zone = atoi(s); + break; + + case fld_utm_easting: + utm_easting = atof(s); + break; + + case fld_utm_northing: + utm_northing = atof(s); + break; + + case fld_utm_zone_char: + utm_zc = toupper(s[0]); + break; + + case fld_utm: + parse_coordinates(s, unicsv_datum_idx, grid_utm, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_bng: + parse_coordinates(s, DATUM_OSGB36, grid_bng, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_bng_zone: + strncpy(bng_zone, s, sizeof(bng_zone)); + strupper(bng_zone); + break; + + case fld_bng_northing: + bng_northing = atof(s); + break; + + case fld_bng_easting: + bng_easting = atof(s); + break; + + case fld_swiss: + parse_coordinates(s, DATUM_WGS84, grid_swiss, + &wpt->latitude, &wpt->longitude, MYNAME); + /* coordinates from parse_coordinates are in WGS84 + don't convert a second time */ + src_datum = DATUM_WGS84; + break; + + case fld_swiss_easting: + swiss_easting = atof(s); + break; + + case fld_swiss_northing: + swiss_northing = atof(s); + break; + + case fld_hdop: + wpt->hdop = atof(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_pdop: + wpt->pdop = atof(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_vdop: + wpt->vdop = atof(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_sat: + wpt->sat = atoi(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_fix: + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + if (case_ignore_strcmp(s, "none") == 0) { + wpt->fix = fix_none; + } else if (case_ignore_strcmp(s, "2d") == 0) { + wpt->fix = fix_2d; + } else if (case_ignore_strcmp(s, "3d") == 0) { + wpt->fix = fix_3d; + } else if (case_ignore_strcmp(s, "dgps") == 0) { + wpt->fix = fix_dgps; + } else if (case_ignore_strcmp(s, "pps") == 0) { + wpt->fix = fix_pps; + } else { + wpt->fix = fix_unknown; + } + break; + + case fld_utc_date: + if ((is_localtime < 2) && (date < 0)) { + date = unicsv_parse_date(s, NULL); + is_localtime = 0; + } + break; + + case fld_utc_time: + if ((is_localtime < 2) && (time < 0)) { + time = unicsv_parse_time(s, &msec, &date); + is_localtime = 0; + } + break; + + case fld_speed: + if (parse_speed(s, &d, 1.0, MYNAME)) { + WAYPT_SET(wpt, speed, d); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + } + break; + + case fld_course: + WAYPT_SET(wpt, course, atof(s)); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_temperature: + d = atof(s); + if (fabs(d) < 999999) { + WAYPT_SET(wpt, temperature, d); + } + break; + + case fld_temperature_f: + d = atof(s); + if (fabs(d) < 999999) { + WAYPT_SET(wpt, temperature, FAHRENHEIT_TO_CELSIUS(d)); + } + break; + + case fld_heartrate: + wpt->heartrate = atoi(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_cadence: + wpt->cadence = atoi(s); + if (unicsv_detect) { + unicsv_data_type = trkdata; + } + break; + + case fld_proximity: + if (parse_distance(s, &d, unicsv_proximityscale, MYNAME)) { + WAYPT_SET(wpt, proximity, d); + } + break; + + case fld_depth: + if (parse_distance(s, &d, unicsv_depthscale, MYNAME)) { + WAYPT_SET(wpt, depth, d); + } + break; + + case fld_symbol: + wpt->icon_descr = xstrdup(s); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + break; + + case fld_iso_time: + is_localtime = 2; /* fix result */ + wpt->creation_time = xml_parse_time(s, &wpt->microseconds); + break; + + case fld_time: + if ((is_localtime < 2) && (time < 0)) { + time = unicsv_parse_time(s, &msec, &date); + is_localtime = 1; + } + break; + + case fld_date: + if ((is_localtime < 2) && (date < 0)) { + date = unicsv_parse_date(s, NULL); + is_localtime = 1; + } + break; + + case fld_year: + ymd.tm_year = atoi(s); + break; + + case fld_month: + ymd.tm_mon = atoi(s); + break; + + case fld_day: + ymd.tm_mday = atoi(s); + break; + + case fld_hour: + ymd.tm_hour = atoi(s); + break; + + case fld_min: + ymd.tm_min = atoi(s); + break; + + case fld_sec: + ymd.tm_sec = atoi(s); + break; + + case fld_datetime: + if ((is_localtime < 2) && (date < 0) && (time < 0)) { + time = unicsv_parse_time(s, &msec, &date); + is_localtime = 1; + } + break; + + case fld_ns: + ns = tolower(s[0]) == 'n' ? 1 : -1; + wpt->latitude *= ns; + break; + + case fld_ew: + ew = tolower(s[0]) == 'e' ? 1 : -1; + wpt->longitude *= ew; + break; + + case fld_garmin_city: + case fld_garmin_postal_code: + case fld_garmin_state: + case fld_garmin_country: + case fld_garmin_addr: + case fld_garmin_phone_nr: + case fld_garmin_phone_nr2: + case fld_garmin_fax_nr: + case fld_garmin_email: + case fld_garmin_facility: + gmsd = GMSD_FIND(wpt); + if (! gmsd) { + gmsd = garmin_fs_alloc(-1); + fs_chain_add(&wpt->fs, (format_specific_data *) gmsd); + } + switch (unicsv_fields_tab[column]) { + case fld_garmin_city: + GMSD_SETSTR(city, s); + break; + case fld_garmin_postal_code: + GMSD_SETSTR(postal_code, s); + break; + case fld_garmin_state: + GMSD_SETSTR(state, s); + break; + case fld_garmin_country: + GMSD_SETSTR(country, s); + break; + case fld_garmin_addr: + GMSD_SETSTR(addr, s); + break; + case fld_garmin_phone_nr: + GMSD_SETSTR(phone_nr, s); + break; + case fld_garmin_phone_nr2: + GMSD_SETSTR(phone_nr2, s); + break; + case fld_garmin_fax_nr: + GMSD_SETSTR(fax_nr, s); + break; + case fld_garmin_email: + GMSD_SETSTR(email, s); + break; + case fld_garmin_facility: + GMSD_SETSTR(facility, s); + break; + default: + break; + } + break; #ifdef UNICSV_GC_READY - case fld_gc_id: - case fld_gc_type: - case fld_gc_container: - case fld_gc_terr: - case fld_gc_diff: - case fld_gc_is_archived: - case fld_gc_is_available: - case fld_gc_exported: - case fld_gc_last_found: - case fld_gc_placer: - case fld_gc_placer_id: - case fld_gc_hint: - - gc_data = waypt_alloc_gc_data(wpt); - - switch(unicsv_fields_tab[column]) { - - case fld_gc_id: - gc_data->id = atoi(s); - if (gc_data->id == 0) gc_data->id = unicsv_parse_gc_id(s); - break; - case fld_gc_type: gc_data->type = gs_mktype(s); break; - case fld_gc_container: gc_data->container = gs_mkcont(s); break; - case fld_gc_terr: gc_data->terr = atof(s) * 10; break; - case fld_gc_diff: gc_data->diff = atof(s) * 10; break; - case fld_gc_is_archived: gc_data->is_archived = unicsv_parse_status(s); break; - case fld_gc_is_available: gc_data->is_available = unicsv_parse_status(s); break; - case fld_gc_exported: { - time_t time, date; int msec; - time = unicsv_parse_time(s, &msec, &date); - if (date || time) gc_data->exported = unicsv_adjust_time(time, &date); - } - break; - case fld_gc_last_found: { - time_t time, date; - int msec; - time = unicsv_parse_time(s, &msec, &date); - if (date || time) gc_data->last_found = unicsv_adjust_time(time, &date); - } - break; - case fld_gc_placer: gc_data->placer = xstrdup(s); break; - case fld_gc_placer_id: gc_data->placer_id = atoi(s); break; - case fld_gc_hint: gc_data->hint = xstrdup(s); break; - - default: break; - } - break; + case fld_gc_id: + case fld_gc_type: + case fld_gc_container: + case fld_gc_terr: + case fld_gc_diff: + case fld_gc_is_archived: + case fld_gc_is_available: + case fld_gc_exported: + case fld_gc_last_found: + case fld_gc_placer: + case fld_gc_placer_id: + case fld_gc_hint: + + gc_data = waypt_alloc_gc_data(wpt); + + switch (unicsv_fields_tab[column]) { + + case fld_gc_id: + gc_data->id = atoi(s); + if (gc_data->id == 0) { + gc_data->id = unicsv_parse_gc_id(s); + } + break; + case fld_gc_type: + gc_data->type = gs_mktype(s); + break; + case fld_gc_container: + gc_data->container = gs_mkcont(s); + break; + case fld_gc_terr: + gc_data->terr = atof(s) * 10; + break; + case fld_gc_diff: + gc_data->diff = atof(s) * 10; + break; + case fld_gc_is_archived: + gc_data->is_archived = unicsv_parse_status(s); + break; + case fld_gc_is_available: + gc_data->is_available = unicsv_parse_status(s); + break; + case fld_gc_exported: { + time_t time, date; + int msec; + time = unicsv_parse_time(s, &msec, &date); + if (date || time) { + gc_data->exported = unicsv_adjust_time(time, &date); + } + } + break; + case fld_gc_last_found: { + time_t time, date; + int msec; + time = unicsv_parse_time(s, &msec, &date); + if (date || time) { + gc_data->last_found = unicsv_adjust_time(time, &date); + } + } + break; + case fld_gc_placer: + gc_data->placer = xstrdup(s); + break; + case fld_gc_placer_id: + gc_data->placer_id = atoi(s); + break; + case fld_gc_hint: + gc_data->hint = xstrdup(s); + break; + + default: + break; + } + break; #endif - case fld_terminator: /* dummy */ - checked--; - break; - } - } - - if (checked == 0) { - waypt_free(wpt); - return; - } - - if (is_localtime < 2) { /* not fixed */ - if ((time >= 0) && (date >= 0)) { - time_t t = date + time; - - if (is_localtime) { - struct tm tm; - tm = *gmtime(&t); - if (opt_utc) - wpt->creation_time = mkgmtime(&tm); - else - wpt->creation_time = mklocaltime(&tm); - } - else - wpt->creation_time = t; - } - else if (time >= 0) - wpt->creation_time = time; - else if (date >= 0) - wpt->creation_time = date; - else if (ymd.tm_year || ymd.tm_mon || ymd.tm_mday) { - if (ymd.tm_year < 100) { - if (ymd.tm_year <= 70) ymd.tm_year += 2000; - else ymd.tm_year += 1900; - } - ymd.tm_year -= 1900; - - if (ymd.tm_mon == 0) ymd.tm_mon = 1; - if (ymd.tm_mday == 0) ymd.tm_mday = 1; - - ymd.tm_mon--; - if (opt_utc) - wpt->creation_time = mkgmtime(&ymd); - else - wpt->creation_time = mklocaltime(&ymd); - } - else if (ymd.tm_hour || ymd.tm_min || ymd.tm_sec) { - if (opt_utc) - wpt->creation_time = mkgmtime(&ymd); - else - wpt->creation_time = mklocaltime(&ymd); - } - - if (msec >= 0) - wpt->microseconds = msec; - - if (opt_utc) - wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR; - } - - /* utm/bng/swiss can be optional */ - - if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) { - if (utm_zone != -9999) { - GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude, - utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx); - } - else if (bng_zone[0]) { - if (! GPS_Math_UKOSMap_To_WGS84_M( - bng_zone, bng_easting, bng_northing, - &wpt->latitude, &wpt->longitude)) - fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n", - bng_zone, bng_easting, bng_northing); - src_datum = DATUM_WGS84; /* don't convert afterwards */ - } - else if ((swiss_easting != unicsv_unknown) && (swiss_northing != unicsv_unknown)) { - GPS_Math_Swiss_EN_To_WGS84(swiss_easting, swiss_northing, - &wpt->latitude, &wpt->longitude); - src_datum = DATUM_WGS84; /* don't convert afterwards */ - } - } - - if ((src_datum != DATUM_WGS84) && - (wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) { - double alt; - GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0, - &wpt->latitude, &wpt->longitude, &alt, src_datum); - } - - switch(unicsv_data_type) { - case rtedata: - if (! unicsv_route) { - unicsv_route = route_head_alloc(); - route_add_head(unicsv_route); - } - route_add_wpt(unicsv_route, wpt); - break; - case trkdata: - if (! unicsv_track) { - unicsv_track = route_head_alloc(); - track_add_head(unicsv_track); - } - track_add_wpt(unicsv_track, wpt); - break; - default: - waypt_add(wpt); - } + case fld_terminator: /* dummy */ + checked--; + break; + } + } + + if (checked == 0) { + waypt_free(wpt); + return; + } + + if (is_localtime < 2) { /* not fixed */ + if ((time >= 0) && (date >= 0)) { + time_t t = date + time; + + if (is_localtime) { + struct tm tm; + tm = *gmtime(&t); + if (opt_utc) { + wpt->creation_time = mkgmtime(&tm); + } else { + wpt->creation_time = mklocaltime(&tm); + } + } else { + wpt->creation_time = t; + } + } else if (time >= 0) { + wpt->creation_time = time; + } else if (date >= 0) { + wpt->creation_time = date; + } else if (ymd.tm_year || ymd.tm_mon || ymd.tm_mday) { + if (ymd.tm_year < 100) { + if (ymd.tm_year <= 70) { + ymd.tm_year += 2000; + } else { + ymd.tm_year += 1900; + } + } + ymd.tm_year -= 1900; + + if (ymd.tm_mon == 0) { + ymd.tm_mon = 1; + } + if (ymd.tm_mday == 0) { + ymd.tm_mday = 1; + } + + ymd.tm_mon--; + if (opt_utc) { + wpt->creation_time = mkgmtime(&ymd); + } else { + wpt->creation_time = mklocaltime(&ymd); + } + } else if (ymd.tm_hour || ymd.tm_min || ymd.tm_sec) { + if (opt_utc) { + wpt->creation_time = mkgmtime(&ymd); + } else { + wpt->creation_time = mklocaltime(&ymd); + } + } + + if (msec >= 0) { + wpt->microseconds = msec; + } + + if (opt_utc) { + wpt->creation_time += atoi(opt_utc) * SECONDS_PER_HOUR; + } + } + + /* utm/bng/swiss can be optional */ + + if ((wpt->latitude == unicsv_unknown) && (wpt->longitude == unicsv_unknown)) { + if (utm_zone != -9999) { + GPS_Math_UTM_EN_To_Known_Datum(&wpt->latitude, &wpt->longitude, + utm_easting, utm_northing, utm_zone, utm_zc, unicsv_datum_idx); + } else if (bng_zone[0]) { + if (! GPS_Math_UKOSMap_To_WGS84_M( + bng_zone, bng_easting, bng_northing, + &wpt->latitude, &wpt->longitude)) + fatal(MYNAME ": Unable to convert BNG coordinates (%s %.f %.f)!\n", + bng_zone, bng_easting, bng_northing); + src_datum = DATUM_WGS84; /* don't convert afterwards */ + } else if ((swiss_easting != unicsv_unknown) && (swiss_northing != unicsv_unknown)) { + GPS_Math_Swiss_EN_To_WGS84(swiss_easting, swiss_northing, + &wpt->latitude, &wpt->longitude); + src_datum = DATUM_WGS84; /* don't convert afterwards */ + } + } + + if ((src_datum != DATUM_WGS84) && + (wpt->latitude != unicsv_unknown) && (wpt->longitude != unicsv_unknown)) { + double alt; + GPS_Math_Known_Datum_To_WGS84_M(wpt->latitude, wpt->longitude, (double) 0.0, + &wpt->latitude, &wpt->longitude, &alt, src_datum); + } + + switch (unicsv_data_type) { + case rtedata: + if (! unicsv_route) { + unicsv_route = route_head_alloc(); + route_add_head(unicsv_route); + } + route_add_wpt(unicsv_route, wpt); + break; + case trkdata: + if (! unicsv_track) { + unicsv_track = route_head_alloc(); + track_add_head(unicsv_track); + } + track_add_wpt(unicsv_track, wpt); + break; + default: + waypt_add(wpt); + } } static void unicsv_rd(void) { - char *buff; - - if (unicsv_fieldsep == NULL) return; - - while ((buff = gbfgetstr(fin))) { - buff = lrtrim(buff); - if ((*buff == '\0') || (*buff == '#')) continue; - unicsv_parse_one_line(buff); - } + char *buff; + + if (unicsv_fieldsep == NULL) { + return; + } + + while ((buff = gbfgetstr(fin))) { + buff = lrtrim(buff); + if ((*buff == '\0') || (*buff == '#')) { + continue; + } + unicsv_parse_one_line(buff); + } } /* =========================================================================== */ @@ -1130,60 +1260,62 @@ unicsv_rd(void) static void unicsv_fatal_outside(const waypoint *wpt) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": %s (%s) is outside of convertable area of grid \"%s\"!\n", - wpt->shortname ? wpt->shortname : "Waypoint", - pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), - gt_get_mps_grid_longname(unicsv_grid_idx, MYNAME)); + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area of grid \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(unicsv_grid_idx, MYNAME)); } static void unicsv_print_str(const char *str) { - if (str && *str) { - char *cout, *cx; - - cout = strenquote(str, UNICSV_QUOT_CHAR); - - while ((cx = strstr(cout, "\r\n"))) { - memmove(cx, cx + 1, strlen(cx)); - *cx++ = ','; - lrtrim(cx); - } - while ((cx = strchr(cout, '\r'))) { - *cx++ = ','; - lrtrim(cx); - } - while ((cx = strchr(cout, '\n'))) { - *cx++ = ','; - lrtrim(cx); - } - - gbfprintf(fout, "%s%s", unicsv_fieldsep, cout); - xfree(cout); - } - else gbfputs(unicsv_fieldsep, fout); + if (str && *str) { + char *cout, *cx; + + cout = strenquote(str, UNICSV_QUOT_CHAR); + + while ((cx = strstr(cout, "\r\n"))) { + memmove(cx, cx + 1, strlen(cx)); + *cx++ = ','; + lrtrim(cx); + } + while ((cx = strchr(cout, '\r'))) { + *cx++ = ','; + lrtrim(cx); + } + while ((cx = strchr(cout, '\n'))) { + *cx++ = ','; + lrtrim(cx); + } + + gbfprintf(fout, "%s%s", unicsv_fieldsep, cout); + xfree(cout); + } else { + gbfputs(unicsv_fieldsep, fout); + } } #ifdef UNICSV_GC_READY static void unicsv_print_data_time(const time_t atime) { - struct tm tm; - time_t time = atime; - char buf[32] = ""; - - if (time) { - if (opt_utc) { - time += atoi(opt_utc) * SECONDS_PER_HOUR; - tm = *gmtime(&time); - } - else tm = *localtime(&time); - snprintf(buf, sizeof(buf), "%04d/%02d/%02d %02d:%02d:%02d", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); - } - unicsv_print_str(buf); + struct tm tm; + time_t time = atime; + char buf[32] = ""; + + if (time) { + if (opt_utc) { + time += atoi(opt_utc) * SECONDS_PER_HOUR; + tm = *gmtime(&time); + } else { + tm = *localtime(&time); + } + snprintf(buf, sizeof(buf), "%04d/%02d/%02d %02d:%02d:%02d", + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + } + unicsv_print_str(buf); } #endif @@ -1192,381 +1324,560 @@ unicsv_print_data_time(const time_t atime) static void unicsv_waypt_enum_cb(const waypoint *wpt) { - const char *shortname; - garmin_fs_t *gmsd; - - shortname = (wpt->shortname) ? wpt->shortname : ""; - gmsd = GMSD_FIND(wpt); - - if (*shortname) gb_setbit(&unicsv_outp_flags, fld_shortname); - if (wpt->altitude != unknown_alt) gb_setbit(&unicsv_outp_flags, fld_altitude); - if (wpt->icon_descr && *wpt->icon_descr) gb_setbit(&unicsv_outp_flags, fld_symbol); - if (wpt->description && *wpt->description && (strcmp(shortname, wpt->description) != 0)) - gb_setbit(&unicsv_outp_flags, fld_description); - if (wpt->notes && *wpt->notes && (strcmp(shortname, wpt->notes) != 0)) { - if ((! wpt->description) || (strcmp(wpt->description, wpt->notes) != 0)) - gb_setbit(&unicsv_outp_flags, fld_notes); - } - if (wpt->url && *wpt->url) gb_setbit(&unicsv_outp_flags, fld_url); - if (wpt->creation_time != 0) { - gb_setbit(&unicsv_outp_flags, fld_time); - if (wpt->creation_time >= SECONDS_PER_DAY) - gb_setbit(&unicsv_outp_flags, fld_date); - } - - if (wpt->fix != fix_unknown) gb_setbit(&unicsv_outp_flags, fld_fix); - if (wpt->vdop > 0) gb_setbit(&unicsv_outp_flags, fld_vdop); - if (wpt->hdop > 0) gb_setbit(&unicsv_outp_flags, fld_hdop); - if (wpt->pdop > 0) gb_setbit(&unicsv_outp_flags, fld_pdop); - if (wpt->sat > 0) gb_setbit(&unicsv_outp_flags, fld_sat); - if (wpt->heartrate != 0) gb_setbit(&unicsv_outp_flags, fld_heartrate); - if (wpt->cadence != 0) gb_setbit(&unicsv_outp_flags, fld_cadence); - - /* "flagged" waypoint members */ - if WAYPT_HAS(wpt, course) gb_setbit(&unicsv_outp_flags, fld_course); - if WAYPT_HAS(wpt, depth) gb_setbit(&unicsv_outp_flags, fld_depth); - if WAYPT_HAS(wpt, speed) gb_setbit(&unicsv_outp_flags, fld_speed); - if WAYPT_HAS(wpt, proximity) gb_setbit(&unicsv_outp_flags, fld_proximity); - if WAYPT_HAS(wpt, temperature) gb_setbit(&unicsv_outp_flags, fld_temperature); - - if (gmsd) { - if GMSD_HAS(addr) gb_setbit(&unicsv_outp_flags, fld_garmin_addr); - if GMSD_HAS(city) gb_setbit(&unicsv_outp_flags, fld_garmin_city); - if GMSD_HAS(country) gb_setbit(&unicsv_outp_flags, fld_garmin_country); - if GMSD_HAS(phone_nr) gb_setbit(&unicsv_outp_flags, fld_garmin_phone_nr); - if GMSD_HAS(phone_nr2) gb_setbit(&unicsv_outp_flags, fld_garmin_phone_nr2); - if GMSD_HAS(fax_nr) gb_setbit(&unicsv_outp_flags, fld_garmin_fax_nr); - if GMSD_HAS(email) gb_setbit(&unicsv_outp_flags, fld_garmin_email); - if GMSD_HAS(postal_code) gb_setbit(&unicsv_outp_flags, fld_garmin_postal_code); - if GMSD_HAS(state) gb_setbit(&unicsv_outp_flags, fld_garmin_state); - if GMSD_HAS(facility) gb_setbit(&unicsv_outp_flags, fld_garmin_facility); - } + const char *shortname; + garmin_fs_t *gmsd; + + shortname = (wpt->shortname) ? wpt->shortname : ""; + gmsd = GMSD_FIND(wpt); + + if (*shortname) { + gb_setbit(&unicsv_outp_flags, fld_shortname); + } + if (wpt->altitude != unknown_alt) { + gb_setbit(&unicsv_outp_flags, fld_altitude); + } + if (wpt->icon_descr && *wpt->icon_descr) { + gb_setbit(&unicsv_outp_flags, fld_symbol); + } + if (wpt->description && *wpt->description && (strcmp(shortname, wpt->description) != 0)) { + gb_setbit(&unicsv_outp_flags, fld_description); + } + if (wpt->notes && *wpt->notes && (strcmp(shortname, wpt->notes) != 0)) { + if ((! wpt->description) || (strcmp(wpt->description, wpt->notes) != 0)) { + gb_setbit(&unicsv_outp_flags, fld_notes); + } + } + if (wpt->url && *wpt->url) { + gb_setbit(&unicsv_outp_flags, fld_url); + } + if (wpt->creation_time != 0) { + gb_setbit(&unicsv_outp_flags, fld_time); + if (wpt->creation_time >= SECONDS_PER_DAY) { + gb_setbit(&unicsv_outp_flags, fld_date); + } + } + + if (wpt->fix != fix_unknown) { + gb_setbit(&unicsv_outp_flags, fld_fix); + } + if (wpt->vdop > 0) { + gb_setbit(&unicsv_outp_flags, fld_vdop); + } + if (wpt->hdop > 0) { + gb_setbit(&unicsv_outp_flags, fld_hdop); + } + if (wpt->pdop > 0) { + gb_setbit(&unicsv_outp_flags, fld_pdop); + } + if (wpt->sat > 0) { + gb_setbit(&unicsv_outp_flags, fld_sat); + } + if (wpt->heartrate != 0) { + gb_setbit(&unicsv_outp_flags, fld_heartrate); + } + if (wpt->cadence != 0) { + gb_setbit(&unicsv_outp_flags, fld_cadence); + } + + /* "flagged" waypoint members */ + if WAYPT_HAS(wpt, course) { + gb_setbit(&unicsv_outp_flags, fld_course); + } + if WAYPT_HAS(wpt, depth) { + gb_setbit(&unicsv_outp_flags, fld_depth); + } + if WAYPT_HAS(wpt, speed) { + gb_setbit(&unicsv_outp_flags, fld_speed); + } + if WAYPT_HAS(wpt, proximity) { + gb_setbit(&unicsv_outp_flags, fld_proximity); + } + if WAYPT_HAS(wpt, temperature) { + gb_setbit(&unicsv_outp_flags, fld_temperature); + } + + if (gmsd) { + if GMSD_HAS(addr) { + gb_setbit(&unicsv_outp_flags, fld_garmin_addr); + } + if GMSD_HAS(city) { + gb_setbit(&unicsv_outp_flags, fld_garmin_city); + } + if GMSD_HAS(country) { + gb_setbit(&unicsv_outp_flags, fld_garmin_country); + } + if GMSD_HAS(phone_nr) { + gb_setbit(&unicsv_outp_flags, fld_garmin_phone_nr); + } + if GMSD_HAS(phone_nr2) { + gb_setbit(&unicsv_outp_flags, fld_garmin_phone_nr2); + } + if GMSD_HAS(fax_nr) { + gb_setbit(&unicsv_outp_flags, fld_garmin_fax_nr); + } + if GMSD_HAS(email) { + gb_setbit(&unicsv_outp_flags, fld_garmin_email); + } + if GMSD_HAS(postal_code) { + gb_setbit(&unicsv_outp_flags, fld_garmin_postal_code); + } + if GMSD_HAS(state) { + gb_setbit(&unicsv_outp_flags, fld_garmin_state); + } + if GMSD_HAS(facility) { + gb_setbit(&unicsv_outp_flags, fld_garmin_facility); + } + } #ifdef UNICSV_GC_READY - if (! waypt_empty_gc_data(wpt)) { - const geocache_data *gc_data = wpt->gc_data; - - if (gc_data->id) gb_setbit(&unicsv_outp_flags, fld_gc_id); - if (gc_data->type) gb_setbit(&unicsv_outp_flags, fld_gc_type); - if (gc_data->container) gb_setbit(&unicsv_outp_flags, fld_gc_container); - if (gc_data->terr) gb_setbit(&unicsv_outp_flags, fld_gc_terr); - if (gc_data->diff) gb_setbit(&unicsv_outp_flags, fld_gc_diff); - if (gc_data->is_archived) gb_setbit(&unicsv_outp_flags, fld_gc_is_archived); - if (gc_data->is_available) gb_setbit(&unicsv_outp_flags, fld_gc_is_available); - if (gc_data->exported) gb_setbit(&unicsv_outp_flags, fld_gc_exported); - if (gc_data->last_found) gb_setbit(&unicsv_outp_flags, fld_gc_last_found); - if (gc_data->placer && *gc_data->placer) gb_setbit(&unicsv_outp_flags, fld_gc_placer); - if (gc_data->placer_id) gb_setbit(&unicsv_outp_flags, fld_gc_placer_id); - if (gc_data->hint && *gc_data->hint) gb_setbit(&unicsv_outp_flags, fld_gc_hint); - } + if (! waypt_empty_gc_data(wpt)) { + const geocache_data *gc_data = wpt->gc_data; + + if (gc_data->id) { + gb_setbit(&unicsv_outp_flags, fld_gc_id); + } + if (gc_data->type) { + gb_setbit(&unicsv_outp_flags, fld_gc_type); + } + if (gc_data->container) { + gb_setbit(&unicsv_outp_flags, fld_gc_container); + } + if (gc_data->terr) { + gb_setbit(&unicsv_outp_flags, fld_gc_terr); + } + if (gc_data->diff) { + gb_setbit(&unicsv_outp_flags, fld_gc_diff); + } + if (gc_data->is_archived) { + gb_setbit(&unicsv_outp_flags, fld_gc_is_archived); + } + if (gc_data->is_available) { + gb_setbit(&unicsv_outp_flags, fld_gc_is_available); + } + if (gc_data->exported) { + gb_setbit(&unicsv_outp_flags, fld_gc_exported); + } + if (gc_data->last_found) { + gb_setbit(&unicsv_outp_flags, fld_gc_last_found); + } + if (gc_data->placer && *gc_data->placer) { + gb_setbit(&unicsv_outp_flags, fld_gc_placer); + } + if (gc_data->placer_id) { + gb_setbit(&unicsv_outp_flags, fld_gc_placer_id); + } + if (gc_data->hint && *gc_data->hint) { + gb_setbit(&unicsv_outp_flags, fld_gc_hint); + } + } #endif } static void unicsv_waypt_disp_cb(const waypoint *wpt) { - double lat, lon, alt; - char *cout = NULL; - const char *shortname; - garmin_fs_t *gmsd; + double lat, lon, alt; + char *cout = NULL; + const char *shortname; + garmin_fs_t *gmsd; #ifdef UNICSV_GC_READY - const geocache_data *gc_data = NULL; + const geocache_data *gc_data = NULL; #endif - unicsv_waypt_ct++; - - shortname = (wpt->shortname) ? wpt->shortname : ""; - gmsd = GMSD_FIND(wpt); - - if (unicsv_datum_idx == DATUM_WGS84) { - lat = wpt->latitude; - lon = wpt->longitude; - alt = wpt->altitude; - } - else { - GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, - &lat, &lon, &alt, unicsv_datum_idx); - } - - gbfprintf(fout, "%d%s", unicsv_waypt_ct, unicsv_fieldsep); - - switch(unicsv_grid_idx) { - - case grid_lat_lon_ddd: - cout = pretty_deg_format(lat, lon, 'd', unicsv_fieldsep, 0); - gbfputs(cout, fout); - break; - - case grid_lat_lon_dmm: - cout = pretty_deg_format(lat, lon, 'm', unicsv_fieldsep, 0); - gbfputs(cout, fout); - break; - - case grid_lat_lon_dms: { - char *sep, *tmp; - cout = pretty_deg_format(lat, lon, 's', unicsv_fieldsep, 0); - sep = strchr(cout, ','); - *sep = '\0'; - tmp = strenquote(cout, UNICSV_QUOT_CHAR); - gbfprintf(fout, "%s%s", tmp, unicsv_fieldsep); - xfree(tmp); - tmp = strenquote(sep+1, UNICSV_QUOT_CHAR); - gbfputs(tmp, fout); - xfree(tmp); - } - break; - - case grid_bng: { - char map[3]; - double north, east; - - if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) - unicsv_fatal_outside(wpt); - gbfprintf(fout, "%s%s%5.0f%s%5.0f", - map, unicsv_fieldsep, - east, unicsv_fieldsep, - north); - break; - } - case grid_utm: { - int zone; - char zonec; - double north, east; - - if (! GPS_Math_Known_Datum_To_UTM_EN(lat, lon, - &east, &north, &zone, &zonec, unicsv_datum_idx)) - unicsv_fatal_outside(wpt); - gbfprintf(fout, "%02d%s%c%s%.0f%s%.0f", - zone, unicsv_fieldsep, - zonec, unicsv_fieldsep, - east, unicsv_fieldsep, - north); - break; - } - case grid_swiss: { - double north, east; - - if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north)) - unicsv_fatal_outside(wpt); - gbfprintf(fout, "%.f%s%.f", - east, unicsv_fieldsep, north); - break; - - } - default: - gbfprintf(fout, "%.*f%s%.*f", llprec, lat, unicsv_fieldsep, llprec, lon); - break; - } - - if (cout) xfree(cout); - - if FIELD_USED(fld_shortname) unicsv_print_str(shortname); - if FIELD_USED(fld_altitude) { - if (wpt->altitude != unknown_alt) - gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->altitude); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_description) unicsv_print_str(wpt->description); - if FIELD_USED(fld_notes) unicsv_print_str(wpt->notes); - if FIELD_USED(fld_symbol) - unicsv_print_str((wpt->icon_descr != NULL) ? wpt->icon_descr : "Waypoint"); - if FIELD_USED(fld_depth) { - if WAYPT_HAS(wpt, depth) - gbfprintf(fout, "%s%.3f", unicsv_fieldsep, wpt->depth); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_proximity) { - if WAYPT_HAS(wpt, proximity) - gbfprintf(fout, "%s%.f", unicsv_fieldsep, wpt->proximity); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_temperature) { - if WAYPT_HAS(wpt, temperature) - gbfprintf(fout, "%s%.3f", unicsv_fieldsep, wpt->temperature); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_speed) { - if WAYPT_HAS(wpt, speed) - gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->speed); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_course) { - if WAYPT_HAS(wpt, course) - gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->course); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_fix) { - char *fix; - switch(wpt->fix) { - case fix_none: fix = "none"; break; - case fix_2d: fix = "2d"; break; - case fix_3d: fix = "3d"; break; - case fix_dgps: fix = "dgps"; break; - case fix_pps: fix = "pps"; break; - default: fix = NULL; - } - if (fix) unicsv_print_str(fix); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_hdop) { - if (wpt->hdop > 0) - gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->hdop); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_vdop) { - if (wpt->vdop > 0) - gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->vdop); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_pdop) { - if (wpt->pdop > 0) - gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->pdop); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_sat) { - if (wpt->sat > 0) - gbfprintf(fout, "%s%d", unicsv_fieldsep, wpt->sat); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_heartrate) { - if (wpt->heartrate != 0) - gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->heartrate); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_cadence) { - if (wpt->cadence != 0) - gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->cadence); - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_date) { - if (wpt->creation_time >= SECONDS_PER_DAY) { - struct tm tm; - char buf[32]; - time_t time = wpt->creation_time; - - if (opt_utc) { - time += atoi(opt_utc) * SECONDS_PER_HOUR; - tm = *gmtime(&time); - } - else tm = *localtime(&wpt->creation_time); - tm.tm_year += 1900; - tm.tm_mon += 1; - snprintf(buf, sizeof(buf), "%04d/%02d/%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); - gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); - } - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_time) { - if (wpt->creation_time != 0) { - struct tm tm; - char buf[32], msec[12]; - time_t time = wpt->creation_time; - - if (opt_utc) { - time += atoi(opt_utc) * SECONDS_PER_HOUR; - tm = *gmtime(&time); - } - else tm = *localtime(&wpt->creation_time); - snprintf(buf, sizeof(buf), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); - - if (wpt->microseconds > 0) { - int len = 6; - int ms = wpt->microseconds; - - while (len && (ms % 10 == 0)) { - ms /= 10; - len--; - } - snprintf(msec, sizeof(msec), ".%0*d", len, ms); - strcat(buf, msec); - } - gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); - } - else - gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_url) unicsv_print_str(wpt->url); - - if FIELD_USED(fld_garmin_facility) unicsv_print_str(GMSD_GET(facility, NULL)); - if FIELD_USED(fld_garmin_addr) unicsv_print_str(GMSD_GET(addr, NULL)); - if FIELD_USED(fld_garmin_city) unicsv_print_str(GMSD_GET(city, NULL)); - if FIELD_USED(fld_garmin_postal_code) unicsv_print_str(GMSD_GET(postal_code, NULL)); - if FIELD_USED(fld_garmin_state) unicsv_print_str(GMSD_GET(state, NULL)); - if FIELD_USED(fld_garmin_country) unicsv_print_str(GMSD_GET(country, NULL)); - if FIELD_USED(fld_garmin_phone_nr) unicsv_print_str(GMSD_GET(phone_nr, NULL)); - if FIELD_USED(fld_garmin_phone_nr2) unicsv_print_str(GMSD_GET(phone_nr2, NULL)); - if FIELD_USED(fld_garmin_fax_nr) unicsv_print_str(GMSD_GET(fax_nr, NULL)); - if FIELD_USED(fld_garmin_email) unicsv_print_str(GMSD_GET(email, NULL)); + unicsv_waypt_ct++; + + shortname = (wpt->shortname) ? wpt->shortname : ""; + gmsd = GMSD_FIND(wpt); + + if (unicsv_datum_idx == DATUM_WGS84) { + lat = wpt->latitude; + lon = wpt->longitude; + alt = wpt->altitude; + } else { + GPS_Math_WGS84_To_Known_Datum_M(wpt->latitude, wpt->longitude, 0.0, + &lat, &lon, &alt, unicsv_datum_idx); + } + + gbfprintf(fout, "%d%s", unicsv_waypt_ct, unicsv_fieldsep); + + switch (unicsv_grid_idx) { + + case grid_lat_lon_ddd: + cout = pretty_deg_format(lat, lon, 'd', unicsv_fieldsep, 0); + gbfputs(cout, fout); + break; + + case grid_lat_lon_dmm: + cout = pretty_deg_format(lat, lon, 'm', unicsv_fieldsep, 0); + gbfputs(cout, fout); + break; + + case grid_lat_lon_dms: { + char *sep, *tmp; + cout = pretty_deg_format(lat, lon, 's', unicsv_fieldsep, 0); + sep = strchr(cout, ','); + *sep = '\0'; + tmp = strenquote(cout, UNICSV_QUOT_CHAR); + gbfprintf(fout, "%s%s", tmp, unicsv_fieldsep); + xfree(tmp); + tmp = strenquote(sep+1, UNICSV_QUOT_CHAR); + gbfputs(tmp, fout); + xfree(tmp); + } + break; + + case grid_bng: { + char map[3]; + double north, east; + + if (! GPS_Math_WGS84_To_UKOSMap_M(wpt->latitude, wpt->longitude, &east, &north, map)) { + unicsv_fatal_outside(wpt); + } + gbfprintf(fout, "%s%s%5.0f%s%5.0f", + map, unicsv_fieldsep, + east, unicsv_fieldsep, + north); + break; + } + case grid_utm: { + int zone; + char zonec; + double north, east; + + if (! GPS_Math_Known_Datum_To_UTM_EN(lat, lon, + &east, &north, &zone, &zonec, unicsv_datum_idx)) { + unicsv_fatal_outside(wpt); + } + gbfprintf(fout, "%02d%s%c%s%.0f%s%.0f", + zone, unicsv_fieldsep, + zonec, unicsv_fieldsep, + east, unicsv_fieldsep, + north); + break; + } + case grid_swiss: { + double north, east; + + if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &east, &north)) { + unicsv_fatal_outside(wpt); + } + gbfprintf(fout, "%.f%s%.f", + east, unicsv_fieldsep, north); + break; + + } + default: + gbfprintf(fout, "%.*f%s%.*f", llprec, lat, unicsv_fieldsep, llprec, lon); + break; + } + + if (cout) { + xfree(cout); + } + + if FIELD_USED(fld_shortname) { + unicsv_print_str(shortname); + } + if FIELD_USED(fld_altitude) { + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->altitude); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_description) { + unicsv_print_str(wpt->description); + } + if FIELD_USED(fld_notes) { + unicsv_print_str(wpt->notes); + } + if FIELD_USED(fld_symbol) { + unicsv_print_str((wpt->icon_descr != NULL) ? wpt->icon_descr : "Waypoint"); + } + if FIELD_USED(fld_depth) { + if WAYPT_HAS(wpt, depth) { + gbfprintf(fout, "%s%.3f", unicsv_fieldsep, wpt->depth); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_proximity) { + if WAYPT_HAS(wpt, proximity) { + gbfprintf(fout, "%s%.f", unicsv_fieldsep, wpt->proximity); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_temperature) { + if WAYPT_HAS(wpt, temperature) { + gbfprintf(fout, "%s%.3f", unicsv_fieldsep, wpt->temperature); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_speed) { + if WAYPT_HAS(wpt, speed) { + gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->speed); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_course) { + if WAYPT_HAS(wpt, course) { + gbfprintf(fout, "%s%.1f", unicsv_fieldsep, wpt->course); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_fix) { + char *fix; + switch (wpt->fix) { + case fix_none: + fix = "none"; + break; + case fix_2d: + fix = "2d"; + break; + case fix_3d: + fix = "3d"; + break; + case fix_dgps: + fix = "dgps"; + break; + case fix_pps: + fix = "pps"; + break; + default: + fix = NULL; + } + if (fix) { + unicsv_print_str(fix); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_hdop) { + if (wpt->hdop > 0) { + gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->hdop); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_vdop) { + if (wpt->vdop > 0) { + gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->vdop); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_pdop) { + if (wpt->pdop > 0) { + gbfprintf(fout, "%s%.2f", unicsv_fieldsep, wpt->pdop); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_sat) { + if (wpt->sat > 0) { + gbfprintf(fout, "%s%d", unicsv_fieldsep, wpt->sat); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_heartrate) { + if (wpt->heartrate != 0) { + gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->heartrate); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_cadence) { + if (wpt->cadence != 0) { + gbfprintf(fout, "%s%u", unicsv_fieldsep, wpt->cadence); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_date) { + if (wpt->creation_time >= SECONDS_PER_DAY) { + struct tm tm; + char buf[32]; + time_t time = wpt->creation_time; + + if (opt_utc) { + time += atoi(opt_utc) * SECONDS_PER_HOUR; + tm = *gmtime(&time); + } else { + tm = *localtime(&wpt->creation_time); + } + tm.tm_year += 1900; + tm.tm_mon += 1; + snprintf(buf, sizeof(buf), "%04d/%02d/%02d", tm.tm_year, tm.tm_mon, tm.tm_mday); + gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_time) { + if (wpt->creation_time != 0) { + struct tm tm; + char buf[32], msec[12]; + time_t time = wpt->creation_time; + + if (opt_utc) { + time += atoi(opt_utc) * SECONDS_PER_HOUR; + tm = *gmtime(&time); + } else { + tm = *localtime(&wpt->creation_time); + } + snprintf(buf, sizeof(buf), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec); + + if (wpt->microseconds > 0) { + int len = 6; + int ms = wpt->microseconds; + + while (len && (ms % 10 == 0)) { + ms /= 10; + len--; + } + snprintf(msec, sizeof(msec), ".%0*d", len, ms); + strcat(buf, msec); + } + gbfprintf(fout, "%s%s", unicsv_fieldsep, buf); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_url) { + unicsv_print_str(wpt->url); + } + + if FIELD_USED(fld_garmin_facility) { + unicsv_print_str(GMSD_GET(facility, NULL)); + } + if FIELD_USED(fld_garmin_addr) { + unicsv_print_str(GMSD_GET(addr, NULL)); + } + if FIELD_USED(fld_garmin_city) { + unicsv_print_str(GMSD_GET(city, NULL)); + } + if FIELD_USED(fld_garmin_postal_code) { + unicsv_print_str(GMSD_GET(postal_code, NULL)); + } + if FIELD_USED(fld_garmin_state) { + unicsv_print_str(GMSD_GET(state, NULL)); + } + if FIELD_USED(fld_garmin_country) { + unicsv_print_str(GMSD_GET(country, NULL)); + } + if FIELD_USED(fld_garmin_phone_nr) { + unicsv_print_str(GMSD_GET(phone_nr, NULL)); + } + if FIELD_USED(fld_garmin_phone_nr2) { + unicsv_print_str(GMSD_GET(phone_nr2, NULL)); + } + if FIELD_USED(fld_garmin_fax_nr) { + unicsv_print_str(GMSD_GET(fax_nr, NULL)); + } + if FIELD_USED(fld_garmin_email) { + unicsv_print_str(GMSD_GET(email, NULL)); + } #ifdef UNICSV_GC_READY - if (waypt_empty_gc_data(wpt)) gc_data = NULL; - else gc_data = wpt->gc_data; - - if FIELD_USED(fld_gc_id) { - gbfputs(unicsv_fieldsep, fout); - if (gc_data && gc_data->id) gbfprintf(fout, "%d", gc_data->id); - } - if FIELD_USED(fld_gc_type) { - if (gc_data) unicsv_print_str(gs_get_cachetype(gc_data->type)); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_container) { - if (gc_data) unicsv_print_str(gs_get_container(gc_data->container)); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_terr) { - gbfputs(unicsv_fieldsep, fout); - if (gc_data && gc_data->terr) gbfprintf(fout, "%.1f", (double)gc_data->terr / 10); - } - if FIELD_USED(fld_gc_diff) { - gbfputs(unicsv_fieldsep, fout); - if (gc_data && gc_data->diff) gbfprintf(fout, "%.1f", (double)gc_data->diff / 10); - } - if FIELD_USED(fld_gc_is_archived) { - if (gc_data && gc_data->is_archived) unicsv_print_str((gc_data->is_archived == status_true) ? "True" : "False"); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_is_available) { - if (gc_data && gc_data->is_available) unicsv_print_str((gc_data->is_available == status_true) ? "True" : "False"); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_exported) { - if (gc_data) unicsv_print_data_time(gc_data->exported); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_last_found) { - if (gc_data) unicsv_print_data_time(gc_data->last_found); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_placer) { - if (gc_data) unicsv_print_str(gc_data->placer); - else gbfputs(unicsv_fieldsep, fout); - } - if FIELD_USED(fld_gc_placer_id) { - gbfputs(unicsv_fieldsep, fout); - if (gc_data && gc_data->placer_id) gbfprintf(fout, "%d", gc_data->placer_id); - } - if FIELD_USED(fld_gc_hint) { - if (gc_data) unicsv_print_str(gc_data->hint); - else gbfputs(unicsv_fieldsep, fout); - } + if (waypt_empty_gc_data(wpt)) { + gc_data = NULL; + } else { + gc_data = wpt->gc_data; + } + + if FIELD_USED(fld_gc_id) { + gbfputs(unicsv_fieldsep, fout); + if (gc_data && gc_data->id) { + gbfprintf(fout, "%d", gc_data->id); + } + } + if FIELD_USED(fld_gc_type) { + if (gc_data) { + unicsv_print_str(gs_get_cachetype(gc_data->type)); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_container) { + if (gc_data) { + unicsv_print_str(gs_get_container(gc_data->container)); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_terr) { + gbfputs(unicsv_fieldsep, fout); + if (gc_data && gc_data->terr) { + gbfprintf(fout, "%.1f", (double)gc_data->terr / 10); + } + } + if FIELD_USED(fld_gc_diff) { + gbfputs(unicsv_fieldsep, fout); + if (gc_data && gc_data->diff) { + gbfprintf(fout, "%.1f", (double)gc_data->diff / 10); + } + } + if FIELD_USED(fld_gc_is_archived) { + if (gc_data && gc_data->is_archived) { + unicsv_print_str((gc_data->is_archived == status_true) ? "True" : "False"); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_is_available) { + if (gc_data && gc_data->is_available) { + unicsv_print_str((gc_data->is_available == status_true) ? "True" : "False"); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_exported) { + if (gc_data) { + unicsv_print_data_time(gc_data->exported); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_last_found) { + if (gc_data) { + unicsv_print_data_time(gc_data->last_found); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_placer) { + if (gc_data) { + unicsv_print_str(gc_data->placer); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } + if FIELD_USED(fld_gc_placer_id) { + gbfputs(unicsv_fieldsep, fout); + if (gc_data && gc_data->placer_id) { + gbfprintf(fout, "%d", gc_data->placer_id); + } + } + if FIELD_USED(fld_gc_hint) { + if (gc_data) { + unicsv_print_str(gc_data->hint); + } else { + gbfputs(unicsv_fieldsep, fout); + } + } #endif - if (opt_format) unicsv_print_str(wpt->session->name); - if (opt_filename) unicsv_print_str(wpt->session->filename); - - gbfputs(UNICSV_LINE_SEP, fout); + if (opt_format) { + unicsv_print_str(wpt->session->name); + } + if (opt_filename) { + unicsv_print_str(wpt->session->filename); + } + + gbfputs(UNICSV_LINE_SEP, fout); } /* --------------------------------------------------------------------------- */ @@ -1575,165 +1886,257 @@ unicsv_waypt_disp_cb(const waypoint *wpt) static void unicsv_wr_init(const char *filename) { - fout = gbfopen(filename, "wb", MYNAME); - - memset(&unicsv_outp_flags, 0, sizeof(unicsv_outp_flags)); - unicsv_grid_idx = grid_unknown; - unicsv_datum_idx = DATUM_WGS84; - unicsv_fieldsep = UNICSV_FIELD_SEP; - unicsv_waypt_ct = 0; - - if (opt_grid != NULL) { - int i; - - if (sscanf(opt_grid, "%d", &i)) { - unicsv_grid_idx = (grid_type) i; - if ((unicsv_grid_idx < GRID_INDEX_MIN) || (unicsv_grid_idx > GRID_INDEX_MAX)) - fatal(MYNAME ": Grid index out of range (%d..%d)!\n", - (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); - } - else unicsv_grid_idx = gt_lookup_grid_type(opt_grid, MYNAME); - } - - if (unicsv_grid_idx == grid_bng) - /* force datum to "Ord Srvy Grt Britn" / OSGB36 */ - /* ! ignore parameter "Datum" ! */ - unicsv_datum_idx = DATUM_OSGB36; - else if (unicsv_grid_idx == grid_swiss) - /* ! ignore parameter "Datum" ! */ - unicsv_datum_idx = DATUM_WGS84; /* internal, becomes CH1903 */ - else - unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); - - llprec = atoi(opt_prec); + fout = gbfopen(filename, "wb", MYNAME); + + memset(&unicsv_outp_flags, 0, sizeof(unicsv_outp_flags)); + unicsv_grid_idx = grid_unknown; + unicsv_datum_idx = DATUM_WGS84; + unicsv_fieldsep = UNICSV_FIELD_SEP; + unicsv_waypt_ct = 0; + + if (opt_grid != NULL) { + int i; + + if (sscanf(opt_grid, "%d", &i)) { + unicsv_grid_idx = (grid_type) i; + if ((unicsv_grid_idx < GRID_INDEX_MIN) || (unicsv_grid_idx > GRID_INDEX_MAX)) + fatal(MYNAME ": Grid index out of range (%d..%d)!\n", + (int)GRID_INDEX_MIN, (int)GRID_INDEX_MAX); + } else { + unicsv_grid_idx = gt_lookup_grid_type(opt_grid, MYNAME); + } + } + + if (unicsv_grid_idx == grid_bng) + /* force datum to "Ord Srvy Grt Britn" / OSGB36 */ + /* ! ignore parameter "Datum" ! */ + { + unicsv_datum_idx = DATUM_OSGB36; + } else if (unicsv_grid_idx == grid_swiss) + /* ! ignore parameter "Datum" ! */ + { + unicsv_datum_idx = DATUM_WGS84; /* internal, becomes CH1903 */ + } else { + unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME); + } + + llprec = atoi(opt_prec); } static void unicsv_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void unicsv_wr(void) { - switch(global_opts.objective) { - case wptdata: - waypt_disp_all(unicsv_waypt_enum_cb); - break; - case trkdata: - track_disp_all(NULL, NULL, unicsv_waypt_enum_cb); - break; - case rtedata: - route_disp_all(NULL, NULL, unicsv_waypt_enum_cb); - break; - case posndata: - fatal(MYNAME ": Realtime positioning not supported.\n"); - } - - gbfprintf(fout, "No%s", unicsv_fieldsep); - - switch(unicsv_grid_idx) { - case grid_bng: -/* indexed parameters doesn't work under __win32__ (mingw) - gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); -*/ - gbfprintf(fout, "BNG-Zone%sBNG-East%sBNG-North", - unicsv_fieldsep, unicsv_fieldsep); - break; - case grid_utm: -/* indexed parameters doesn't work under __win32__ (mingw) - gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); -*/ - gbfprintf(fout, "UTM-Zone%sUTM-Ch%sUTM-East%sUTM-North", - unicsv_fieldsep, unicsv_fieldsep, unicsv_fieldsep); - break; - case grid_swiss: - gbfprintf(fout, "Swiss-East%sSwiss-North", - unicsv_fieldsep); - break; - default: - gbfprintf(fout, "Latitude%sLongitude", unicsv_fieldsep); - } - - if FIELD_USED(fld_shortname) gbfprintf(fout, "%sName", unicsv_fieldsep); - if FIELD_USED(fld_altitude) gbfprintf(fout, "%sAltitude", unicsv_fieldsep); - if FIELD_USED(fld_description) gbfprintf(fout, "%sDescription", unicsv_fieldsep); - if FIELD_USED(fld_notes) gbfprintf(fout, "%sNotes", unicsv_fieldsep); - if FIELD_USED(fld_symbol) gbfprintf(fout, "%sSymbol", unicsv_fieldsep); - if FIELD_USED(fld_depth) gbfprintf(fout, "%sDepth", unicsv_fieldsep); - if FIELD_USED(fld_proximity) gbfprintf(fout, "%sProximity", unicsv_fieldsep); - if FIELD_USED(fld_temperature) gbfprintf(fout, "%sTemperature", unicsv_fieldsep); - if FIELD_USED(fld_speed) gbfprintf(fout, "%sSpeed", unicsv_fieldsep); - if FIELD_USED(fld_course) gbfprintf(fout, "%sCourse", unicsv_fieldsep); - if FIELD_USED(fld_fix) gbfprintf(fout, "%sFIX", unicsv_fieldsep); - if FIELD_USED(fld_hdop) gbfprintf(fout, "%sHDOP", unicsv_fieldsep); - if FIELD_USED(fld_vdop) gbfprintf(fout, "%sVDOP", unicsv_fieldsep); - if FIELD_USED(fld_pdop) gbfprintf(fout, "%sPDOP", unicsv_fieldsep); - if FIELD_USED(fld_sat) gbfprintf(fout, "%sSatellites", unicsv_fieldsep); - if FIELD_USED(fld_heartrate) gbfprintf(fout, "%sHeartrate", unicsv_fieldsep); - if FIELD_USED(fld_cadence) gbfprintf(fout, "%sCadence", unicsv_fieldsep); - if FIELD_USED(fld_date) gbfprintf(fout, "%sDate", unicsv_fieldsep); - if FIELD_USED(fld_time) gbfprintf(fout, "%sTime", unicsv_fieldsep); - if FIELD_USED(fld_url) gbfprintf(fout, "%sURL", unicsv_fieldsep); - - if FIELD_USED(fld_garmin_facility) gbfprintf(fout, "%sFacility", unicsv_fieldsep); - if FIELD_USED(fld_garmin_addr) gbfprintf(fout, "%sAddress", unicsv_fieldsep); - if FIELD_USED(fld_garmin_city) gbfprintf(fout, "%sCity", unicsv_fieldsep); - if FIELD_USED(fld_garmin_postal_code) gbfprintf(fout, "%sPostalCode", unicsv_fieldsep); - if FIELD_USED(fld_garmin_state) gbfprintf(fout, "%sState", unicsv_fieldsep); - if FIELD_USED(fld_garmin_country) gbfprintf(fout, "%sCountry", unicsv_fieldsep); - if FIELD_USED(fld_garmin_phone_nr) gbfprintf(fout, "%sPhone", unicsv_fieldsep); - if FIELD_USED(fld_garmin_phone_nr2) gbfprintf(fout, "%sPhone2", unicsv_fieldsep); - if FIELD_USED(fld_garmin_fax_nr) gbfprintf(fout, "%sFax", unicsv_fieldsep); - if FIELD_USED(fld_garmin_email) gbfprintf(fout, "%sEmail", unicsv_fieldsep); + switch (global_opts.objective) { + case wptdata: + waypt_disp_all(unicsv_waypt_enum_cb); + break; + case trkdata: + track_disp_all(NULL, NULL, unicsv_waypt_enum_cb); + break; + case rtedata: + route_disp_all(NULL, NULL, unicsv_waypt_enum_cb); + break; + case posndata: + fatal(MYNAME ": Realtime positioning not supported.\n"); + } + + gbfprintf(fout, "No%s", unicsv_fieldsep); + + switch (unicsv_grid_idx) { + case grid_bng: + /* indexed parameters doesn't work under __win32__ (mingw) + gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); + */ + gbfprintf(fout, "BNG-Zone%sBNG-East%sBNG-North", + unicsv_fieldsep, unicsv_fieldsep); + break; + case grid_utm: + /* indexed parameters doesn't work under __win32__ (mingw) + gbfprintf(fout, "BNG-Zone%1$sBNG-East%1$sBNG-North", unicsv_fieldsep); + */ + gbfprintf(fout, "UTM-Zone%sUTM-Ch%sUTM-East%sUTM-North", + unicsv_fieldsep, unicsv_fieldsep, unicsv_fieldsep); + break; + case grid_swiss: + gbfprintf(fout, "Swiss-East%sSwiss-North", + unicsv_fieldsep); + break; + default: + gbfprintf(fout, "Latitude%sLongitude", unicsv_fieldsep); + } + + if FIELD_USED(fld_shortname) { + gbfprintf(fout, "%sName", unicsv_fieldsep); + } + if FIELD_USED(fld_altitude) { + gbfprintf(fout, "%sAltitude", unicsv_fieldsep); + } + if FIELD_USED(fld_description) { + gbfprintf(fout, "%sDescription", unicsv_fieldsep); + } + if FIELD_USED(fld_notes) { + gbfprintf(fout, "%sNotes", unicsv_fieldsep); + } + if FIELD_USED(fld_symbol) { + gbfprintf(fout, "%sSymbol", unicsv_fieldsep); + } + if FIELD_USED(fld_depth) { + gbfprintf(fout, "%sDepth", unicsv_fieldsep); + } + if FIELD_USED(fld_proximity) { + gbfprintf(fout, "%sProximity", unicsv_fieldsep); + } + if FIELD_USED(fld_temperature) { + gbfprintf(fout, "%sTemperature", unicsv_fieldsep); + } + if FIELD_USED(fld_speed) { + gbfprintf(fout, "%sSpeed", unicsv_fieldsep); + } + if FIELD_USED(fld_course) { + gbfprintf(fout, "%sCourse", unicsv_fieldsep); + } + if FIELD_USED(fld_fix) { + gbfprintf(fout, "%sFIX", unicsv_fieldsep); + } + if FIELD_USED(fld_hdop) { + gbfprintf(fout, "%sHDOP", unicsv_fieldsep); + } + if FIELD_USED(fld_vdop) { + gbfprintf(fout, "%sVDOP", unicsv_fieldsep); + } + if FIELD_USED(fld_pdop) { + gbfprintf(fout, "%sPDOP", unicsv_fieldsep); + } + if FIELD_USED(fld_sat) { + gbfprintf(fout, "%sSatellites", unicsv_fieldsep); + } + if FIELD_USED(fld_heartrate) { + gbfprintf(fout, "%sHeartrate", unicsv_fieldsep); + } + if FIELD_USED(fld_cadence) { + gbfprintf(fout, "%sCadence", unicsv_fieldsep); + } + if FIELD_USED(fld_date) { + gbfprintf(fout, "%sDate", unicsv_fieldsep); + } + if FIELD_USED(fld_time) { + gbfprintf(fout, "%sTime", unicsv_fieldsep); + } + if FIELD_USED(fld_url) { + gbfprintf(fout, "%sURL", unicsv_fieldsep); + } + + if FIELD_USED(fld_garmin_facility) { + gbfprintf(fout, "%sFacility", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_addr) { + gbfprintf(fout, "%sAddress", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_city) { + gbfprintf(fout, "%sCity", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_postal_code) { + gbfprintf(fout, "%sPostalCode", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_state) { + gbfprintf(fout, "%sState", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_country) { + gbfprintf(fout, "%sCountry", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_phone_nr) { + gbfprintf(fout, "%sPhone", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_phone_nr2) { + gbfprintf(fout, "%sPhone2", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_fax_nr) { + gbfprintf(fout, "%sFax", unicsv_fieldsep); + } + if FIELD_USED(fld_garmin_email) { + gbfprintf(fout, "%sEmail", unicsv_fieldsep); + } #ifdef UNICSV_GC_READY - if FIELD_USED(fld_gc_id) gbfprintf(fout, "%sGCID", unicsv_fieldsep); - if FIELD_USED(fld_gc_type) gbfprintf(fout, "%sType", unicsv_fieldsep); - if FIELD_USED(fld_gc_container) gbfprintf(fout, "%sContainer", unicsv_fieldsep); - if FIELD_USED(fld_gc_terr) gbfprintf(fout, "%sTerrain", unicsv_fieldsep); - if FIELD_USED(fld_gc_diff) gbfprintf(fout, "%sDifficulty", unicsv_fieldsep); - if FIELD_USED(fld_gc_is_archived) gbfprintf(fout, "%sArchived", unicsv_fieldsep); - if FIELD_USED(fld_gc_is_available) gbfprintf(fout, "%sAvailable", unicsv_fieldsep); - if FIELD_USED(fld_gc_exported) gbfprintf(fout, "%sExported", unicsv_fieldsep); - if FIELD_USED(fld_gc_last_found) gbfprintf(fout, "%sLast Found", unicsv_fieldsep); - if FIELD_USED(fld_gc_placer) gbfprintf(fout, "%sPlacer", unicsv_fieldsep); - if FIELD_USED(fld_gc_placer_id) gbfprintf(fout, "%sPlacer ID", unicsv_fieldsep); - if FIELD_USED(fld_gc_hint) gbfprintf(fout, "%sHint", unicsv_fieldsep); + if FIELD_USED(fld_gc_id) { + gbfprintf(fout, "%sGCID", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_type) { + gbfprintf(fout, "%sType", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_container) { + gbfprintf(fout, "%sContainer", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_terr) { + gbfprintf(fout, "%sTerrain", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_diff) { + gbfprintf(fout, "%sDifficulty", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_is_archived) { + gbfprintf(fout, "%sArchived", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_is_available) { + gbfprintf(fout, "%sAvailable", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_exported) { + gbfprintf(fout, "%sExported", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_last_found) { + gbfprintf(fout, "%sLast Found", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_placer) { + gbfprintf(fout, "%sPlacer", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_placer_id) { + gbfprintf(fout, "%sPlacer ID", unicsv_fieldsep); + } + if FIELD_USED(fld_gc_hint) { + gbfprintf(fout, "%sHint", unicsv_fieldsep); + } #endif - if (opt_format) gbfprintf(fout, "%sFormat", unicsv_fieldsep); - if (opt_filename) gbfprintf(fout, "%sFilename", unicsv_fieldsep); - - gbfputs(UNICSV_LINE_SEP, fout); - - switch(global_opts.objective) { - case wptdata: - waypt_disp_all(unicsv_waypt_disp_cb); - break; - case trkdata: - track_disp_all(NULL, NULL, unicsv_waypt_disp_cb); - break; - case rtedata: - route_disp_all(NULL, NULL, unicsv_waypt_disp_cb); - break; - default: - break; - } + if (opt_format) { + gbfprintf(fout, "%sFormat", unicsv_fieldsep); + } + if (opt_filename) { + gbfprintf(fout, "%sFilename", unicsv_fieldsep); + } + + gbfputs(UNICSV_LINE_SEP, fout); + + switch (global_opts.objective) { + case wptdata: + waypt_disp_all(unicsv_waypt_disp_cb); + break; + case trkdata: + track_disp_all(NULL, NULL, unicsv_waypt_disp_cb); + break; + case rtedata: + route_disp_all(NULL, NULL, unicsv_waypt_disp_cb); + break; + default: + break; + } } /* --------------------------------------------------------------------------- */ ff_vecs_t unicsv_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - unicsv_rd_init, - unicsv_wr_init, - unicsv_rd_deinit, - unicsv_wr_deinit, - unicsv_rd, - unicsv_wr, - NULL, - unicsv_args, - CET_CHARSET_ASCII, 0 /* can be changed with -c ... */ + ff_type_file, + FF_CAP_RW_ALL, + unicsv_rd_init, + unicsv_wr_init, + unicsv_rd_deinit, + unicsv_wr_deinit, + unicsv_rd, + unicsv_wr, + NULL, + unicsv_args, + CET_CHARSET_ASCII, 0 /* can be changed with -c ... */ }; diff --git a/gpsbabel/units.c b/gpsbabel/units.c index 2938bfa1f..434407f57 100644 --- a/gpsbabel/units.c +++ b/gpsbabel/units.c @@ -1,6 +1,6 @@ /* Display scaled distances in 'local' units. - + Copyright (C) 2006 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -23,112 +23,113 @@ static int units = units_statute; -int +int fmt_setunits(fmt_units u) { - switch (u) { - case units_statute: - case units_metric: - case units_nautical: - case units_aviation: - units = u; - return 0; - default: - return 1; - } + switch (u) { + case units_statute: + case units_metric: + case units_nautical: + case units_aviation: + units = u; + return 0; + default: + return 1; + } } double fmt_distance(const double distance_meters, char **tag) { - double d; - - switch (units) { - case units_statute: - d = METERS_TO_FEET(distance_meters); - if (d < 5280) { - *tag = "ft"; - } else { - d = METERS_TO_MILES(distance_meters); - *tag = "mi"; - } - break; - case units_nautical: - case units_aviation: - d = METERS_TO_NMILES(distance_meters); - *tag = "NM"; - break; - case units_metric: - d = distance_meters; - if (d < 1000) { - *tag = "meters"; - } else { - d = d / (double) 1000.0; - *tag = "km"; - } - break; - - default: - fatal("not done yet"); - break; - } - - return d; + double d; + + switch (units) { + case units_statute: + d = METERS_TO_FEET(distance_meters); + if (d < 5280) { + *tag = "ft"; + } else { + d = METERS_TO_MILES(distance_meters); + *tag = "mi"; + } + break; + case units_nautical: + case units_aviation: + d = METERS_TO_NMILES(distance_meters); + *tag = "NM"; + break; + case units_metric: + d = distance_meters; + if (d < 1000) { + *tag = "meters"; + } else { + d = d / (double) 1000.0; + *tag = "km"; + } + break; + + default: + fatal("not done yet"); + break; + } + + return d; } double fmt_altitude(const double distance_meters, char **tag) { - double d; - - switch (units) { - case units_statute: - case units_aviation: - d = METERS_TO_FEET(distance_meters); - *tag = "ft"; - break; - case units_nautical: - d = METERS_TO_NMILES(distance_meters); - *tag = "NM"; - break; - case units_metric: - d = distance_meters; - *tag = "meters"; - break; - - default: - fatal("not done yet"); - break; - } - - return d; + double d; + + switch (units) { + case units_statute: + case units_aviation: + d = METERS_TO_FEET(distance_meters); + *tag = "ft"; + break; + case units_nautical: + d = METERS_TO_NMILES(distance_meters); + *tag = "NM"; + break; + case units_metric: + d = distance_meters; + *tag = "meters"; + break; + + default: + fatal("not done yet"); + break; + } + + return d; } double fmt_speed(const double distance_meters_sec, char **tag) { - double d; - - switch (units) { - case units_statute: - d = METERS_TO_MILES(distance_meters_sec) * SECONDS_PER_HOUR ; - *tag = "mph"; - break; - case units_nautical: - case units_aviation: - d = METERS_TO_NMILES(distance_meters_sec) * SECONDS_PER_HOUR ; - *tag = "knts"; - break; - case units_metric: - d = distance_meters_sec * SECONDS_PER_HOUR; - *tag = "meters/hour"; - if (d > 1000.0) { - d /= 1000.0; - *tag = "km/hour"; - } - break; - default: fatal("not done yet"); - - } - return d; + double d; + + switch (units) { + case units_statute: + d = METERS_TO_MILES(distance_meters_sec) * SECONDS_PER_HOUR ; + *tag = "mph"; + break; + case units_nautical: + case units_aviation: + d = METERS_TO_NMILES(distance_meters_sec) * SECONDS_PER_HOUR ; + *tag = "knts"; + break; + case units_metric: + d = distance_meters_sec * SECONDS_PER_HOUR; + *tag = "meters/hour"; + if (d > 1000.0) { + d /= 1000.0; + *tag = "km/hour"; + } + break; + default: + fatal("not done yet"); + + } + return d; } diff --git a/gpsbabel/util.c b/gpsbabel/util.c index 3d7f16334..0be028193 100644 --- a/gpsbabel/util.c +++ b/gpsbabel/util.c @@ -45,31 +45,31 @@ #define DEBUG_FILENAME "/tmp/gpsbabel.debug" static FILE *debug_mem_file = NULL; -void -debug_mem_open() +void +debug_mem_open() { - debug_mem_file = xfopen( DEBUG_FILENAME, "a", "debug" ); + debug_mem_file = xfopen(DEBUG_FILENAME, "a", "debug"); } void -debug_mem_output(char *format, ...) +debug_mem_output(char *format, ...) { - va_list args; - va_start( args, format ); - if ( debug_mem_file ) { - vfprintf( debug_mem_file, format, args ); - fflush( debug_mem_file ); - } - va_end( args ); + va_list args; + va_start(args, format); + if (debug_mem_file) { + vfprintf(debug_mem_file, format, args); + fflush(debug_mem_file); + } + va_end(args); } void debug_mem_close() { - if ( debug_mem_file ) { - fclose(debug_mem_file); - } - debug_mem_file = NULL; + if (debug_mem_file) { + fclose(debug_mem_file); + } + debug_mem_file = NULL; } #endif @@ -80,17 +80,17 @@ XMALLOC(size_t size, DEBUG_PARAMS) xmalloc(size_t size) #endif { - void *obj = malloc(size); + void *obj = malloc(size); #ifdef DEBUG_MEM - debug_mem_output( "malloc, %x, %d, %s, %d\n", - obj, size, file, line ); + debug_mem_output("malloc, %x, %d, %s, %d\n", + obj, size, file, line); #endif - if (!obj) { - fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) size); - } + if (!obj) { + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) size); + } - return obj; + return obj; } void * @@ -100,51 +100,51 @@ XCALLOC(size_t nmemb, size_t size, DEBUG_PARAMS) xcalloc(size_t nmemb, size_t size) #endif { - void *obj = calloc(nmemb, size); + void *obj = calloc(nmemb, size); #ifdef DEBUG_MEM - debug_mem_output( "calloc, %x, %d, %d, %s, %d\n", - obj, nmemb, size, file, line ); + debug_mem_output("calloc, %x, %d, %d, %s, %d\n", + obj, nmemb, size, file, line); #endif - if (!obj) { - fatal("gpsbabel: Unable to allocate %ld units of %ld bytes of memory.\n", (unsigned long) nmemb, (unsigned long) size); - } + if (!obj) { + fatal("gpsbabel: Unable to allocate %ld units of %ld bytes of memory.\n", (unsigned long) nmemb, (unsigned long) size); + } - return obj; + return obj; } void #ifdef DEBUG_MEM -XFREE( void *mem, DEBUG_PARAMS ) +XFREE(void *mem, DEBUG_PARAMS) #else -xfree( void *mem ) +xfree(void *mem) #endif { - free(mem); + free(mem); #ifdef DEBUG_MEM - debug_mem_output( "free, %x, %s, %d\n", - mem, file, line ); + debug_mem_output("free, %x, %s, %d\n", + mem, file, line); #endif } char * #ifdef DEBUG_MEM -XSTRDUP(const char *s, DEBUG_PARAMS ) +XSTRDUP(const char *s, DEBUG_PARAMS) #else xstrdup(const char *s) #endif { - char *o = s ? strdup(s) : strdup(""); + char *o = s ? strdup(s) : strdup(""); #ifdef DEBUG_MEM - debug_mem_output( "strdup, %x, %x, %s, %d\n", - o, s, file, line ); + debug_mem_output("strdup, %x, %x, %s, %d\n", + o, s, file, line); #endif - if (!o) { - fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) strlen(s)); - } + if (!o) { + fatal("gpsbabel: Unable to allocate %ld bytes of memory.\n", (unsigned long) strlen(s)); + } - return o; + return o; } /* @@ -152,75 +152,76 @@ xstrdup(const char *s) */ char * #ifdef DEBUG_MEM -XSTRNDUP(const char *str, size_t sz, DEBUG_PARAMS ) +XSTRNDUP(const char *str, size_t sz, DEBUG_PARAMS) #else xstrndup(const char *str, size_t sz) #endif { - size_t newlen = 0; - char *cin = (char *)str; - char *newstr; + size_t newlen = 0; + char *cin = (char *)str; + char *newstr; - while ((newlen < sz) && (*cin != '\0')) { - newlen++; - cin++; - } - - newstr = (char *) xmalloc(newlen + 1); - memcpy(newstr, str, newlen); - newstr[newlen] = 0; + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; + } + + newstr = (char *) xmalloc(newlen + 1); + memcpy(newstr, str, newlen); + newstr[newlen] = 0; - return newstr; + return newstr; } /* - * Lazily trim whitespace (though not from allocated version) + * Lazily trim whitespace (though not from allocated version) * while copying. */ char * #ifdef DEBUG_MEM -XSTRNDUPT(const char *str, size_t sz, DEBUG_PARAMS ) +XSTRNDUPT(const char *str, size_t sz, DEBUG_PARAMS) #else xstrndupt(const char *str, size_t sz) #endif { - size_t newlen = 0; - char *cin = (char *)str; - char *newstr; + size_t newlen = 0; + char *cin = (char *)str; + char *newstr; - while ((newlen < sz) && (*cin != '\0')) { - newlen++; - cin++; - } - - newstr = (char *) xmalloc(newlen + 1); - memcpy(newstr, str, newlen); - newstr[newlen] = 0; - rtrim(newstr); + while ((newlen < sz) && (*cin != '\0')) { + newlen++; + cin++; + } - return newstr; + newstr = (char *) xmalloc(newlen + 1); + memcpy(newstr, str, newlen); + newstr[newlen] = 0; + rtrim(newstr); + + return newstr; } void * #ifdef DEBUG_MEM -XREALLOC(void *p, size_t s, DEBUG_PARAMS ) +XREALLOC(void *p, size_t s, DEBUG_PARAMS) #else xrealloc(void *p, size_t s) #endif { - char *o = (char *) realloc(p,s); + char *o = (char *) realloc(p,s); #ifdef DEBUG_MEM - if (p != NULL) - debug_mem_output( "realloc, %x, %x, %x, %s, %d\n", o, p, s, file, line ); - else - debug_mem_output( "malloc, %x, %d, %s, %d\n", o, s, file, line ); + if (p != NULL) { + debug_mem_output("realloc, %x, %x, %x, %s, %d\n", o, p, s, file, line); + } else { + debug_mem_output("malloc, %x, %d, %s, %d\n", o, s, file, line); + } #endif - if (!o) { - fatal("gpsbabel: Unable to realloc %ld bytes of memory.\n", (unsigned long) s); - } + if (!o) { + fatal("gpsbabel: Unable to realloc %ld bytes of memory.\n", (unsigned long) s); + } - return o; + return o; } /* @@ -233,20 +234,20 @@ XSTRAPPEND(char *src, const char *newd, DEBUG_PARAMS) xstrappend(char *src, const char *newd) #endif { - size_t newsz; + size_t newsz; - if (!src) { - return xxstrdup(newd, file, line); - } - if (!newd) { - return xxstrdup(src, file, line); - } + if (!src) { + return xxstrdup(newd, file, line); + } + if (!newd) { + return xxstrdup(src, file, line); + } - newsz = strlen(src) + strlen(newd) + 1; - src = (char *) xxrealloc(src, newsz, file, line); - strcat(src, newd); + newsz = strlen(src) + strlen(newd) + 1; + src = (char *) xxrealloc(src, newsz, file, line); + strcat(src, newd); - return src; + return src; } /* @@ -255,45 +256,46 @@ xstrappend(char *src, const char *newd) FILE * xfopen(const char *fname, const char *type, const char *errtxt) { - FILE *f; - int am_writing = strchr(type, 'w') != NULL; + FILE *f; + int am_writing = strchr(type, 'w') != NULL; - if (fname == NULL) { - fatal("%s must have a filename specified for %s.\n", - errtxt, am_writing ? "write" : "read"); - } + if (fname == NULL) { + fatal("%s must have a filename specified for %s.\n", + errtxt, am_writing ? "write" : "read"); + } - if (0 == strcmp(fname, "-")) - return am_writing ? stdout : stdin; - f = fopen(fname, type); - if (NULL == f) { - fatal("%s cannot open '%s' for %s. Error was '%s'.\n", - errtxt, fname, - am_writing ? "write" : "read", - strerror(errno)); - } - return f; + if (0 == strcmp(fname, "-")) { + return am_writing ? stdout : stdin; + } + f = fopen(fname, type); + if (NULL == f) { + fatal("%s cannot open '%s' for %s. Error was '%s'.\n", + errtxt, fname, + am_writing ? "write" : "read", + strerror(errno)); + } + return f; } void xfprintf(const char *errtxt, FILE *stream, const char *format, ...) { - va_list ap; - va_start(ap, format); - if (vfprintf(stream, format, ap) < 0) { - fatal("%s writing output file. Error was '%s'.\n", - errtxt, strerror(errno)); - } - va_end(ap); + va_list ap; + va_start(ap, format); + if (vfprintf(stream, format, ap) < 0) { + fatal("%s writing output file. Error was '%s'.\n", + errtxt, strerror(errno)); + } + va_end(ap); } void xfputs(const char *errtxt, const char *s, FILE *stream) { - if (fputs(s, stream) < 0) { - fatal("%s Writing output file. Error was '%s'.\n", - errtxt, strerror(errno)); - } + if (fputs(s, stream) < 0) { + fatal("%s Writing output file. Error was '%s'.\n", + errtxt, strerror(errno)); + } } /* @@ -301,143 +303,144 @@ xfputs(const char *errtxt, const char *s, FILE *stream) * Returns -1 on error. * If return value is anything else, *strp will be populated with an * allocated string containging the formatted buffer. - * + * * Freeing that is the responsbility of the caller. */ int xasprintf(char **strp, const char *fmt, ...) { - va_list args; - int res; - - va_start(args, fmt); - res = xvasprintf(strp, fmt, args); - va_end(args); - - return res; + va_list args; + int res; + + va_start(args, fmt); + res = xvasprintf(strp, fmt, args); + va_end(args); + + return res; } int xvasprintf(char **strp, const char *fmt, va_list ap) { -/* From http://perfec.to/vsnprintf/pasprintf.c */ -/* size of first buffer malloc; start small to exercise grow routines */ + /* From http://perfec.to/vsnprintf/pasprintf.c */ + /* size of first buffer malloc; start small to exercise grow routines */ #ifdef DEBUG_MEM # define FIRSTSIZE 64 #else # define FIRSTSIZE 1 #endif - char *buf = NULL; - int bufsize; - char *newbuf; - size_t nextsize = 0; - int outsize; - va_list args; - - bufsize = 0; - for (;;) { - if (bufsize == 0) { - if ((buf = (char *) xmalloc(FIRSTSIZE)) == NULL) { - *strp = NULL; - return -1; - } - bufsize = FIRSTSIZE; - } else if ((newbuf = (char *) xrealloc(buf, nextsize)) != NULL) { - buf = newbuf; - bufsize = nextsize; - } else { - xfree(buf); - *strp = NULL; - return -1; - } - - va_copy(args, ap); - outsize = vsnprintf(buf, bufsize, fmt, args); - va_end(args); - - if (outsize == -1) { - /* Clear indication that output was truncated, but no - * clear indication of how big buffer needs to be, so - * simply double existing buffer size for next time. - */ - nextsize = bufsize * 2; - - } else if (outsize == bufsize) { - /* Output was truncated (since at least the \0 could - * not fit), but no indication of how big the buffer - * needs to be, so just double existing buffer size - * for next time. - */ - nextsize = bufsize * 2; - - } else if (outsize > bufsize) { - /* Output was truncated, but we were told exactly how - * big the buffer needs to be next time. Add two chars - * to the returned size. One for the \0, and one to - * prevent ambiguity in the next case below. - */ - nextsize = outsize + 2; - - } else if (outsize == bufsize - 1) { - /* This is ambiguous. May mean that the output string - * exactly fits, but on some systems the output string - * may have been trucated. We can't tell. - * Just double the buffer size for next time. - */ - nextsize = bufsize * 2; - - } else { - /* Output was not truncated */ - break; - } - } - /* Prevent us from allocating millions of unused bytes. */ - /* O.K.: I think this is not the final solution. */ - if (bufsize > outsize + 1) { - const unsigned ptrsz = sizeof(buf); - if (((bufsize + ptrsz + 1) / ptrsz) > ((outsize + ptrsz + 1) / ptrsz)) - buf = (char *) xrealloc(buf, outsize + 1); - - } - *strp = buf; - return outsize; -} - - -/* + char *buf = NULL; + int bufsize; + char *newbuf; + size_t nextsize = 0; + int outsize; + va_list args; + + bufsize = 0; + for (;;) { + if (bufsize == 0) { + if ((buf = (char *) xmalloc(FIRSTSIZE)) == NULL) { + *strp = NULL; + return -1; + } + bufsize = FIRSTSIZE; + } else if ((newbuf = (char *) xrealloc(buf, nextsize)) != NULL) { + buf = newbuf; + bufsize = nextsize; + } else { + xfree(buf); + *strp = NULL; + return -1; + } + + va_copy(args, ap); + outsize = vsnprintf(buf, bufsize, fmt, args); + va_end(args); + + if (outsize == -1) { + /* Clear indication that output was truncated, but no + * clear indication of how big buffer needs to be, so + * simply double existing buffer size for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize == bufsize) { + /* Output was truncated (since at least the \0 could + * not fit), but no indication of how big the buffer + * needs to be, so just double existing buffer size + * for next time. + */ + nextsize = bufsize * 2; + + } else if (outsize > bufsize) { + /* Output was truncated, but we were told exactly how + * big the buffer needs to be next time. Add two chars + * to the returned size. One for the \0, and one to + * prevent ambiguity in the next case below. + */ + nextsize = outsize + 2; + + } else if (outsize == bufsize - 1) { + /* This is ambiguous. May mean that the output string + * exactly fits, but on some systems the output string + * may have been trucated. We can't tell. + * Just double the buffer size for next time. + */ + nextsize = bufsize * 2; + + } else { + /* Output was not truncated */ + break; + } + } + /* Prevent us from allocating millions of unused bytes. */ + /* O.K.: I think this is not the final solution. */ + if (bufsize > outsize + 1) { + const unsigned ptrsz = sizeof(buf); + if (((bufsize + ptrsz + 1) / ptrsz) > ((outsize + ptrsz + 1) / ptrsz)) { + buf = (char *) xrealloc(buf, outsize + 1); + } + + } + *strp = buf; + return outsize; +} + + +/* * Duplicate a pascal string into a normal C string. */ char * pstrdup(char *src) { - int len = src[0]; - char *obuf = (char *) xmalloc(len + 1); + int len = src[0]; + char *obuf = (char *) xmalloc(len + 1); - memcpy(obuf, src + 1, len); - obuf[len] = 0; + memcpy(obuf, src + 1, len); + obuf[len] = 0; - return obuf; + return obuf; } -void +void rtrim(char *s) { - char *t = s; + char *t = s; - if (!s || !*s) { - return; - } + if (!s || !*s) { + return; + } - while (*s) { - s++; - } + while (*s) { + s++; + } - s--; - while ((s >= t) && isspace (*s)) { - *s = 0; - s--; - } + s--; + while ((s >= t) && isspace(*s)) { + *s = 0; + s--; + } } /* @@ -446,55 +449,63 @@ rtrim(char *s) char * lrtrim(char *buff) { - char *c; + char *c; - if (buff[0] == '\0') - return buff; + if (buff[0] == '\0') { + return buff; + } + + c = buff + strlen(buff); + while ((c >= buff) && ((unsigned char)*c <= ' ')) { + *c-- = '\0'; + } + + c = buff; + while ((*c != '\0') && ((unsigned char)*c <= ' ')) { + c++; + } - c = buff + strlen(buff); - while ((c >= buff) && ((unsigned char)*c <= ' ')) *c-- = '\0'; + if (c != buff) { + char *src = c; + char *dst = buff; - c = buff; - while ((*c != '\0') && ((unsigned char)*c <= ' ')) c++; - - if (c != buff) { - char *src = c; - char *dst = buff; - - while (*src) *dst++ = *src++; - *dst = '\0'; - } + while (*src) { + *dst++ = *src++; + } + *dst = '\0'; + } - return buff; + return buff; } /* * Like strcmp, but case insensitive. Like Berkeley's strcasecmp. */ -int +int case_ignore_strcmp(const char *s1, const char *s2) { - for(;toupper(*s1) == toupper(*s2); ++ s1, ++s2) { - if (*s1 == 0) - return 0; - } - return (toupper(*s1) < toupper(*s2)) ? -1 : +1; + for (; toupper(*s1) == toupper(*s2); ++ s1, ++s2) { + if (*s1 == 0) { + return 0; + } + } + return (toupper(*s1) < toupper(*s2)) ? -1 : +1; } -int +int case_ignore_strncmp(const char *s1, const char *s2, int n) { - int rv = 0; + int rv = 0; - while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) - && *s1) { - s1++; - s2++; - n--; - } - return rv; + while (n && ((rv = toupper(*s1) - toupper(*s2)) == 0) + && *s1) { + s1++; + s2++; + n--; + } + return rv; } /* @@ -507,169 +518,193 @@ case_ignore_strncmp(const char *s1, const char *s2, int n) * str_match("?ABCDE", "\\?A*") -> 1 * str_match("", "*A") -> 0 */ - + int str_match(const char *str, const char *match) { - char *m, *s; - - s = (char *)str; - m = (char *)match; - - while (*m || *s) - { - switch(*m) - { - - case '\0': - /* there is something left in s, FAIL */ - return 0; - - case '*': - /* skip all wildcards */ - while ((*m == '*') || (*m == '?')) m++; - if (*m == '\0') return 1; - - if (*m == '\\') /* ? escaped ? */ - { - m++; - if (*m == '\0') return 0; - } - - do - { - char *mx, *sx; - - while (*s && (*s != *m)) s++; - if (*s == '\0') return 0; - - sx = s + 1; - mx = m + 1; - - while (*sx) - { - if (*mx == '\\') /* ? escaped ? */ - { - mx++; - if (*mx == '\0') return 0; - - } - if (*sx == *mx) - { - sx++; - mx++; - } - else - break; - } - if (*mx == '\0') /* end of match */ - { - if (*sx == '\0') return 1; - s++; - } - else if ((*mx == '?') || (*mx == '*')) - { - s = sx; - m = mx; - break; - } - else - s++; - } while (*s); - break; - - case '?': - if (*s == '\0') return 0; /* no character left */ - m++; - s++; - break; - - case '\\': - m++; - if (*m == '\0') return 0; /* incomplete escape sequence */ - /* pass-through next character */ - - default: - if (*m != *s) return 0; - m++; - s++; - } - } - return ((*s == '\0') && (*m == '\0')); + char *m, *s; + + s = (char *)str; + m = (char *)match; + + while (*m || *s) { + switch (*m) { + + case '\0': + /* there is something left in s, FAIL */ + return 0; + + case '*': + /* skip all wildcards */ + while ((*m == '*') || (*m == '?')) { + m++; + } + if (*m == '\0') { + return 1; + } + + if (*m == '\\') { /* ? escaped ? */ + m++; + if (*m == '\0') { + return 0; + } + } + + do { + char *mx, *sx; + + while (*s && (*s != *m)) { + s++; + } + if (*s == '\0') { + return 0; + } + + sx = s + 1; + mx = m + 1; + + while (*sx) { + if (*mx == '\\') { /* ? escaped ? */ + mx++; + if (*mx == '\0') { + return 0; + } + + } + if (*sx == *mx) { + sx++; + mx++; + } else { + break; + } + } + if (*mx == '\0') { /* end of match */ + if (*sx == '\0') { + return 1; + } + s++; + } else if ((*mx == '?') || (*mx == '*')) { + s = sx; + m = mx; + break; + } else { + s++; + } + } while (*s); + break; + + case '?': + if (*s == '\0') { + return 0; /* no character left */ + } + m++; + s++; + break; + + case '\\': + m++; + if (*m == '\0') { + return 0; /* incomplete escape sequence */ + } + /* pass-through next character */ + + default: + if (*m != *s) { + return 0; + } + m++; + s++; + } + } + return ((*s == '\0') && (*m == '\0')); } /* - * as str_match, but case insensitive + * as str_match, but case insensitive */ - + int case_ignore_str_match(const char *str, const char *match) { - char *s1, *s2; - int res; - - s1 = strupper(xstrdup(str)); - s2 = strupper(xstrdup(match)); - res = str_match(s1, s2); - xfree(s1); - xfree(s2); - - return res; + char *s1, *s2; + int res; + + s1 = strupper(xstrdup(str)); + s2 = strupper(xstrdup(match)); + res = str_match(s1, s2); + xfree(s1); + xfree(s2); + + return res; } char * strenquote(const char *str, const char quot_char) { - int len; - const char *cin; - char *cout; - char *tmp; - - if (str == NULL) cin = ""; - else cin = (char *)str; - - len = strlen(cin); - cout = tmp = (char *) xmalloc((len * 2) + 3); - - *cout++ = quot_char; - while (*cin) { - *cout++ = *cin; - if (*cin++ == quot_char) - *cout++ = quot_char; - } - *cout++ = quot_char; - *cout = '\0'; - - cout = xstrdup(tmp); - xfree(tmp); - return cout; + int len; + const char *cin; + char *cout; + char *tmp; + + if (str == NULL) { + cin = ""; + } else { + cin = (char *)str; + } + + len = strlen(cin); + cout = tmp = (char *) xmalloc((len * 2) + 3); + + *cout++ = quot_char; + while (*cin) { + *cout++ = *cin; + if (*cin++ == quot_char) { + *cout++ = quot_char; + } + } + *cout++ = quot_char; + *cout = '\0'; + + cout = xstrdup(tmp); + xfree(tmp); + return cout; } void printposn(const double c, int is_lat) { - char d; - if (is_lat) { - if (c < 0) d = 'S'; else d = 'N'; - } else { - if (c < 0) d = 'W'; else d = 'E'; - } - printf("%f%c ", fabs(c), d); + char d; + if (is_lat) { + if (c < 0) { + d = 'S'; + } else { + d = 'N'; + } + } else { + if (c < 0) { + d = 'W'; + } else { + d = 'E'; + } + } + printf("%f%c ", fabs(c), d); } void is_fatal(const int condition, const char *fmt, ...) { - va_list args; - char buff[128]; + va_list args; + char buff[128]; - if (condition == 0) return; + if (condition == 0) { + return; + } - va_start(args, fmt); - vsnprintf(buff, sizeof(buff), fmt, args); - va_end(args); + va_start(args, fmt); + vsnprintf(buff, sizeof(buff), fmt, args); + va_end(args); - fatal("%s\n", buff); + fatal("%s\n", buff); } /* @@ -678,120 +713,119 @@ is_fatal(const int condition, const char *fmt, ...) signed int be_read32(const void *p) { - unsigned char *i = (unsigned char *) p; - return i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3]; + unsigned char *i = (unsigned char *) p; + return i[0] << 24 | i[1] << 16 | i[2] << 8 | i[3]; } signed int be_read16(const void *p) { - unsigned char *i = (unsigned char *) p; - return i[0] << 8 | i[1]; + unsigned char *i = (unsigned char *) p; + return i[0] << 8 | i[1]; } unsigned int be_readu16(const void *p) { - const unsigned char *i = (unsigned char *) p; - return i[0] << 8 | i[1]; + const unsigned char *i = (unsigned char *) p; + return i[0] << 8 | i[1]; } void be_write16(void *addr, const unsigned value) { - unsigned char *p = (unsigned char *) addr; - p[0] = value >> 8; - p[1] = value; - + unsigned char *p = (unsigned char *) addr; + p[0] = value >> 8; + p[1] = value; + } void be_write32(void *pp, const unsigned i) { - char *p = (char *)pp; + char *p = (char *)pp; - p[0] = (i >> 24) & 0xff; - p[1] = (i >> 16) & 0xff; - p[2] = (i >> 8) & 0xff; - p[3] = i & 0xff; + p[0] = (i >> 24) & 0xff; + p[1] = (i >> 16) & 0xff; + p[2] = (i >> 8) & 0xff; + p[3] = i & 0xff; } signed int le_read16(const void *addr) { - const unsigned char *p = (const unsigned char *) addr; - return p[0] | (p[1] << 8); + const unsigned char *p = (const unsigned char *) addr; + return p[0] | (p[1] << 8); } unsigned int le_readu16(const void *addr) { - const unsigned char *p = (const unsigned char *) addr; - return p[0] | (p[1] << 8); + const unsigned char *p = (const unsigned char *) addr; + return p[0] | (p[1] << 8); } signed int le_read32(const void *addr) { - const unsigned char *p = (const unsigned char *) addr; - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + const unsigned char *p = (const unsigned char *) addr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); } unsigned int le_readu32(const void *addr) { - const unsigned char *p = (const unsigned char *) addr; - return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); + const unsigned char *p = (const unsigned char *) addr; + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); } /* - * Read a little-endian 64-bit value from 'src' and return it in 'dest' + * Read a little-endian 64-bit value from 'src' and return it in 'dest' * in host endianness. */ void le_read64(void *dest, const void *src) { - char *cdest = (char *) dest; - const char *csrc = (const char *) src; + char *cdest = (char *) dest; + const char *csrc = (const char *) src; - if (i_am_little_endian) { - memcpy(dest, src, 8); - } else { - int i; - for (i = 0; i < 8; i++) { - cdest[i] = csrc[7-i]; - } - } + if (i_am_little_endian) { + memcpy(dest, src, 8); + } else { + int i; + for (i = 0; i < 8; i++) { + cdest[i] = csrc[7-i]; + } + } } void le_write16(void *addr, const unsigned value) { - unsigned char *p = (unsigned char *) addr; - p[0] = value; - p[1] = value >> 8; - + unsigned char *p = (unsigned char *) addr; + p[0] = value; + p[1] = value >> 8; + } -void +void le_write32(void *addr, const unsigned value) { - unsigned char *p = (unsigned char *) addr; - p[0] = value; - p[1] = value >> 8; - p[2] = value >> 16; - p[3] = value >> 24; + unsigned char *p = (unsigned char *) addr; + p[0] = value; + p[1] = value >> 8; + p[2] = value >> 16; + p[3] = value >> 24; } -signed int -si_round( double d ) +signed int +si_round(double d) { - if ( d < 0 ) { - return (signed int)(d-0.5); - } - else { - return (signed int)(d+0.5); - } + if (d < 0) { + return (signed int)(d-0.5); + } else { + return (signed int)(d+0.5); + } } /* @@ -799,17 +833,17 @@ si_round( double d ) * make it a local time. * Obsolete: to use mkgmtime instead. */ -signed int +signed int get_tz_offset(void) { - time_t now = current_time(); - time_t later = mktime(gmtime(&now)); + time_t now = current_time(); + time_t later = mktime(gmtime(&now)); - if (later == -1) { - return 0; - } else { - return (signed int) difftime(now, later); - } + if (later == -1) { + return 0; + } else { + return (signed int) difftime(now, later); + } } /* @@ -829,34 +863,34 @@ get_tz_offset(void) time_t mkgmtime(struct tm *t) { - short month, year; - time_t result; - static int m_to_d[12] = - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; - - month = t->tm_mon; - year = t->tm_year + month / 12 + 1900; - month %= 12; - if (month < 0) - { - year -= 1; - month += 12; - } - result = (year - 1970) * 365 + m_to_d[month]; - if (month <= 1) - year -= 1; - result += (year - 1968) / 4; - result -= (year - 1900) / 100; - result += (year - 1600) / 400; - result += t->tm_mday; - result -= 1; - result *= 24; - result += t->tm_hour; - result *= 60; - result += t->tm_min; - result *= 60; - result += t->tm_sec; - return(result); + short month, year; + time_t result; + static int m_to_d[12] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + month = t->tm_mon; + year = t->tm_year + month / 12 + 1900; + month %= 12; + if (month < 0) { + year -= 1; + month += 12; + } + result = (year - 1970) * 365 + m_to_d[month]; + if (month <= 1) { + year -= 1; + } + result += (year - 1968) / 4; + result -= (year - 1900) / 100; + result += (year - 1600) / 400; + result += t->tm_mday; + result -= 1; + result *= 24; + result += t->tm_hour; + result *= 60; + result += t->tm_min; + result *= 60; + result += t->tm_sec; + return(result); } /* @@ -866,18 +900,18 @@ mkgmtime(struct tm *t) time_t mklocaltime(struct tm *t) { - time_t result; - struct tm check = *t; - - check.tm_isdst = 0; - result = mktime(&check); - check = *localtime(&result); - if (check.tm_isdst == 1) { /* DST is in effect */ - check = *t; - check.tm_isdst = 1; - result = mktime(&check); - } - return result; + time_t result; + struct tm check = *t; + + check.tm_isdst = 0; + result = mktime(&check); + check = *localtime(&result); + if (check.tm_isdst == 1) { /* DST is in effect */ + check = *t; + check.tm_isdst = 1; + result = mktime(&check); + } + return result; } /* @@ -886,11 +920,11 @@ mklocaltime(struct tm *t) time_t current_time(void) { - if (getenv("GPSBABEL_FREEZE_TIME")) { - return 0; - } + if (getenv("GPSBABEL_FREEZE_TIME")) { + return 0; + } - return time(NULL); + return time(NULL); } /* @@ -899,21 +933,23 @@ current_time(void) signed int month_lookup(const char *m) { - static const char *months[] = { - "JAN", "FEB", "MAR", "APR", "MAY", "JUN", - "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", NULL }; - const char **mp; + static const char *months[] = { + "JAN", "FEB", "MAR", "APR", "MAY", "JUN", + "JUL", "AUG", "SEP", "OCT", "NOV", "DEC", NULL + }; + const char **mp; - for (mp = months; *mp; mp++) { - if (0 == case_ignore_strcmp(*mp, m)) - return mp - months; - } - return -1; + for (mp = months; *mp; mp++) { + if (0 == case_ignore_strcmp(*mp, m)) { + return mp - months; + } + } + return -1; } /* * Microsoft dot net's time format is the number of 100 nanosecond intervals - * since midnight Jan 1, 0001. We have time_t deeply ingrained into our + * since midnight Jan 1, 0001. We have time_t deeply ingrained into our * internals and since we're in the GPS biz, timestamps before 1/1/1970 aren't * that interesting to us anyway. */ @@ -932,48 +968,49 @@ void dotnet_time_to_time_t(double dotnet, time_t *t, int *ms) /* * Return a pointer to a constant string that is suitable for icon lookup - * based on geocache attributes. The strings used are those present in - * a GPX file from geocaching.com. Thus we sort of make all the other + * based on geocache attributes. The strings used are those present in + * a GPX file from geocaching.com. Thus we sort of make all the other * formats do lookups based on these strings. */ const char * get_cache_icon(const waypoint *waypointp) { - if (!global_opts.smart_icons) - return NULL; - - /* - * For icons, type overwrites container. So a multi-micro will - * get the icons for "multi". - */ - switch (waypointp->gc_data->type) { - case gt_virtual: - return "Virtual cache"; - case gt_multi: - return "Multi-Cache"; - case gt_event: - return "Event Cache"; - case gt_suprise: - return "Unknown Cache"; - case gt_webcam: - return "Webcam Cache"; - default: - break; - } - - switch (waypointp->gc_data->container) { - case gc_micro: - return "Micro-Cache"; - break; - default: - break; - } - - if (waypointp->gc_data->diff > 1) { - return "Geocache"; - } - - return NULL; + if (!global_opts.smart_icons) { + return NULL; + } + + /* + * For icons, type overwrites container. So a multi-micro will + * get the icons for "multi". + */ + switch (waypointp->gc_data->type) { + case gt_virtual: + return "Virtual cache"; + case gt_multi: + return "Multi-Cache"; + case gt_event: + return "Event Cache"; + case gt_suprise: + return "Unknown Cache"; + case gt_webcam: + return "Webcam Cache"; + default: + break; + } + + switch (waypointp->gc_data->container) { + case gc_micro: + return "Micro-Cache"; + break; + default: + break; + } + + if (waypointp->gc_data->diff > 1) { + return "Geocache"; + } + + return NULL; } double @@ -983,19 +1020,17 @@ endian_read_double(const void* ptr, int read_le) char r[8]; const void *p; int i; - - if ( i_am_little_endian == read_le ) { - p = ptr; - } - else { - for (i = 0; i < 8; i++) - { - r[i] = ((char*)ptr)[7-i]; - } - p = r; + + if (i_am_little_endian == read_le) { + p = ptr; + } else { + for (i = 0; i < 8; i++) { + r[i] = ((char*)ptr)[7-i]; + } + p = r; } -// Word order is different on arm, but not on arm-eabi. +// Word order is different on arm, but not on arm-eabi. #if defined(__arm__) && !defined(__ARM_EABI__) memcpy(&ret, p + 4, 4); memcpy(((void *)&ret) + 4, p, 4); @@ -1013,18 +1048,16 @@ endian_read_float(const void* ptr, int read_le) char r[4]; const void *p; int i; - - if ( i_am_little_endian == read_le ) { - p = ptr; - } - else { - for (i = 0; i < 4; i++) - { - r[i] = ((char*)ptr)[3-i]; - } - p = r; - } - + + if (i_am_little_endian == read_le) { + p = ptr; + } else { + for (i = 0; i < 4; i++) { + r[i] = ((char*)ptr)[3-i]; + } + p = r; + } + memcpy(&ret, p, 4); return ret; } @@ -1034,24 +1067,22 @@ endian_write_double(void* ptr, double d, int write_le) { int i; char *optr = (char *) ptr; -// Word order is different on arm, but not on arm-eabi. +// Word order is different on arm, but not on arm-eabi. #if defined(__arm__) && !defined(__ARM_EABI__) char r[8]; - memcpy( r + 4, &d, 4); - memcpy( r, ((void *)&d) + 4, 4); -#else + memcpy(r + 4, &d, 4); + memcpy(r, ((void *)&d) + 4, 4); +#else char *r = (char *)(void *)&d; #endif - if ( i_am_little_endian == write_le ) { - memcpy( ptr, r, 8); - } - else { - for (i = 0; i < 8; i++) - { - *optr++ = r[7-i]; - } + if (i_am_little_endian == write_le) { + memcpy(ptr, r, 8); + } else { + for (i = 0; i < 8; i++) { + *optr++ = r[7-i]; + } } } @@ -1062,55 +1093,79 @@ endian_write_float(void* ptr, float f, int write_le) int i; char *optr = (char *) ptr; - if ( i_am_little_endian == write_le ) { - memcpy( ptr, &f, 4); - } - else { - for (i = 0; i < 4; i++) - { - *optr++ = r[3-i]; - } + if (i_am_little_endian == write_le) { + memcpy(ptr, &f, 4); + } else { + for (i = 0; i < 4; i++) { + *optr++ = r[3-i]; + } } } float -le_read_float( const void *ptr ) {return endian_read_float(ptr, 1);} +le_read_float(const void *ptr) +{ + return endian_read_float(ptr, 1); +} void -le_write_float( void *ptr, float f ) {endian_write_float(ptr,f,1);} +le_write_float(void *ptr, float f) +{ + endian_write_float(ptr,f,1); +} float -be_read_float( void *ptr ) {return endian_read_float(ptr, 0);} +be_read_float(void *ptr) +{ + return endian_read_float(ptr, 0); +} void -be_write_float( void *ptr, float f ) {endian_write_float(ptr,f,0);} +be_write_float(void *ptr, float f) +{ + endian_write_float(ptr,f,0); +} -double -le_read_double( const void *ptr ) {return endian_read_double(ptr,1);} +double +le_read_double(const void *ptr) +{ + return endian_read_double(ptr,1); +} void -le_write_double( void *ptr, double d ) {endian_write_double(ptr,d,1);} +le_write_double(void *ptr, double d) +{ + endian_write_double(ptr,d,1); +} -double -be_read_double( void *ptr ) {return endian_read_double(ptr,0);} +double +be_read_double(void *ptr) +{ + return endian_read_double(ptr,0); +} void -be_write_double( void *ptr, double d ) {endian_write_double(ptr,d,0);} +be_write_double(void *ptr, double d) +{ + endian_write_double(ptr,d,0); +} /* Magellan and PCX formats use this DDMM.mm format */ -double ddmm2degrees(double pcx_val) { - double minutes; - signed int deg; - deg = (signed int) (pcx_val / 100.0); - minutes = (((pcx_val / 100.0) - deg) * 100.0) / 60.0; - return (double) deg + minutes; +double ddmm2degrees(double pcx_val) +{ + double minutes; + signed int deg; + deg = (signed int)(pcx_val / 100.0); + minutes = (((pcx_val / 100.0) - deg) * 100.0) / 60.0; + return (double) deg + minutes; } -double degrees2ddmm(double deg_val) { - signed int deg; - deg = (signed int) deg_val; - return (double) (deg * 100.0) + ((deg_val - deg) * 60.0); +double degrees2ddmm(double deg_val) +{ + signed int deg; + deg = (signed int) deg_val; + return (double)(deg * 100.0) + ((deg_val - deg) * 60.0); } /* @@ -1121,30 +1176,30 @@ double degrees2ddmm(double deg_val) { char * strsub(const char *s, const char *search, const char *replace) { - char *p; - int len = strlen(s); - int slen = strlen(search); - int rlen = strlen(replace); - char *d; + char *p; + int len = strlen(s); + int slen = strlen(search); + int rlen = strlen(replace); + char *d; - p = strstr(s, search); - if (!slen || !p) { - return NULL; - } - - d = (char *) xmalloc(len + rlen); + p = strstr(s, search); + if (!slen || !p) { + return NULL; + } - /* Copy first part */ - len = p - s; - memcpy(d, s, len); - d[len] = 0; + d = (char *) xmalloc(len + rlen); - /* Copy replacement */ - strcat(d, replace); + /* Copy first part */ + len = p - s; + memcpy(d, s, len); + d[len] = 0; - /* Copy last part */ - strcat(d, p + slen); - return d; + /* Copy replacement */ + strcat(d, replace); + + /* Copy last part */ + strcat(d, p + slen); + return d; } /* @@ -1153,46 +1208,47 @@ strsub(const char *s, const char *search, const char *replace) char * gstrsub(const char *s, const char *search, const char *replace) { - int ooffs = 0; - char *o, *c; - char *src = (char *)s; - int olen = strlen(src); - int slen = strlen(search); - int rlen = strlen(replace); - - o = (char *) xmalloc(olen + 1); - - while ((c = strstr(src, search))) { - olen += (rlen - slen); - o = (char *) xrealloc(o, olen + 1); - memcpy(o + ooffs, src, c - src); - ooffs += (c - src); - src = c + slen; - if (rlen) { - memcpy(o + ooffs, replace, rlen); - ooffs += rlen; - } - } - - if (ooffs < olen) - memcpy(o + ooffs, src, olen - ooffs); - o[olen] = '\0'; - return o; + int ooffs = 0; + char *o, *c; + char *src = (char *)s; + int olen = strlen(src); + int slen = strlen(search); + int rlen = strlen(replace); + + o = (char *) xmalloc(olen + 1); + + while ((c = strstr(src, search))) { + olen += (rlen - slen); + o = (char *) xrealloc(o, olen + 1); + memcpy(o + ooffs, src, c - src); + ooffs += (c - src); + src = c + slen; + if (rlen) { + memcpy(o + ooffs, replace, rlen); + ooffs += rlen; + } + } + + if (ooffs < olen) { + memcpy(o + ooffs, src, olen - ooffs); + } + o[olen] = '\0'; + return o; } /* * Like strstr, but starts from back of string. */ char * -xstrrstr(const char *s1, const char *s2) +xstrrstr(const char *s1, const char *s2) { - char *r = NULL, *next = NULL; + char *r = NULL, *next = NULL; - while (next = strstr(s1, s2), NULL != next) { - r = next; - s1 = next + 1; - } - return r; + while (next = strstr(s1, s2), NULL != next) { + r = next; + s1 = next + 1; + } + return r; } /* @@ -1201,12 +1257,12 @@ xstrrstr(const char *s1, const char *s2) char * strupper(char *src) { - char *c; - - for (c = src; *c; c++) { - *c = toupper(*c); - } - return src; + char *c; + + for (c = src; *c; c++) { + *c = toupper(*c); + } + return src; } /* @@ -1215,102 +1271,103 @@ strupper(char *src) char * strlower(char *src) { - char *c; - - for (c = src; *c; c++) { - *c = tolower(*c); - } - return src; + char *c; + + for (c = src; *c; c++) { + *c = tolower(*c); + } + return src; } char * -rot13( const char *s ) -{ - char *result = xstrdup( s ); - char *cur = result; - int flip = 1; - while (cur && *cur ) { - if ( flip ) { - if (*cur == '[') flip = 0; - else if ( *cur >= 'A' && *cur <= 'Z' ) { - *cur = 'A' + ((*cur-'A')+13)%26; - } - else if ( *cur >= 'a' && *cur <= 'z' ) { - *cur = 'a' + ((*cur-'a')+13)%26; - } - } - else if ( *cur == ']' ) flip = 1; - cur++; - } - return result; +rot13(const char *s) +{ + char *result = xstrdup(s); + char *cur = result; + int flip = 1; + while (cur && *cur) { + if (flip) { + if (*cur == '[') { + flip = 0; + } else if (*cur >= 'A' && *cur <= 'Z') { + *cur = 'A' + ((*cur-'A')+13)%26; + } else if (*cur >= 'a' && *cur <= 'z') { + *cur = 'a' + ((*cur-'a')+13)%26; + } + } else if (*cur == ']') { + flip = 1; + } + cur++; + } + return result; } /* * Convert a human readable date format (i.e. "YYYY/MM/DD") into - * a format usable for strftime and others + * a format usable for strftime and others */ - + char * convert_human_date_format(const char *human_datef) { - char *result, *cin, *cout; - char prev; - int ylen; - - result = (char *) xcalloc((2*strlen(human_datef)) + 1, 1); - cout = result; - prev = '\0'; - ylen = 0; - - for (cin = (char *)human_datef; *cin; cin++) - { - char okay = 1; - - if (toupper(*cin) != 'Y') ylen = 0; - if (isalpha(*cin)) - { - switch(*cin) - { - case 'y': case 'Y': - if (prev != 'Y') - { - strcat(cout, "%y"); - cout += 2; - prev = 'Y'; - } - ylen++; - if (ylen > 2) *(cout-1) = 'Y'; - break; - case 'm': case 'M': - if (prev != 'M') - { - strcat(cout, "%m"); - cout += 2; - prev = 'M'; - } - break; - case 'd': case 'D': - if (prev != 'D') - { - strcat(cout, "%d"); - cout += 2; - prev = 'D'; - } - break; - default: - okay = 0; - } - } - else if (ispunct(*cin)) - { - *cout++ = *cin; - prev = '\0'; - } - else okay = 0; - - is_fatal(okay == 0, "Invalid character \"%c\" in date format!", *cin); - } - return result; + char *result, *cin, *cout; + char prev; + int ylen; + + result = (char *) xcalloc((2*strlen(human_datef)) + 1, 1); + cout = result; + prev = '\0'; + ylen = 0; + + for (cin = (char *)human_datef; *cin; cin++) { + char okay = 1; + + if (toupper(*cin) != 'Y') { + ylen = 0; + } + if (isalpha(*cin)) { + switch (*cin) { + case 'y': + case 'Y': + if (prev != 'Y') { + strcat(cout, "%y"); + cout += 2; + prev = 'Y'; + } + ylen++; + if (ylen > 2) { + *(cout-1) = 'Y'; + } + break; + case 'm': + case 'M': + if (prev != 'M') { + strcat(cout, "%m"); + cout += 2; + prev = 'M'; + } + break; + case 'd': + case 'D': + if (prev != 'D') { + strcat(cout, "%d"); + cout += 2; + prev = 'D'; + } + break; + default: + okay = 0; + } + } else if (ispunct(*cin)) { + *cout++ = *cin; + prev = '\0'; + } else { + okay = 0; + } + + is_fatal(okay == 0, "Invalid character \"%c\" in date format!", *cin); + } + return result; } /* @@ -1321,91 +1378,93 @@ convert_human_date_format(const char *human_datef) char * convert_human_time_format(const char *human_timef) { - char *result, *cin, *cout; - char prev; - - result = (char *) xcalloc((2*strlen(human_timef)) + 1, 1); - cout = result; - prev = '\0'; - - for (cin = (char *)human_timef; *cin; cin++) - { - int okay = 1; - - if (isalpha(*cin)) - { - switch(*cin) - { - case 'S': case 's': - if (prev != 'S') { - strcat(cout, "%S"); - cout += 2; - prev = 'S'; - } - break; - - case 'M': case 'm': - if (prev != 'M') { - strcat(cout, "%M"); - cout += 2; - prev = 'M'; - } - break; - - case 'h': /* 12-hour-clock */ - if (prev != 'H') { - strcat(cout, "%l"); /* 1 .. 12 */ - cout += 2; - prev = 'H'; - } - else *(cout-1) = 'I'; /* 01 .. 12 */ - break; - - case 'H': /* 24-hour-clock */ - if (prev != 'H') { - strcat(cout, "%k"); - cout += 2; - prev = 'H'; - } - else *(cout-1) = 'H'; - break; - - case 'x': - if (prev != 'X') { - strcat(cout, "%P"); - cout += 2; - prev = 'X'; - } - else *(cout-1) = 'P'; - break; - - case 'X': - if (prev != 'X') { - strcat(cout, "%p"); - cout += 2; - prev = 'X'; - } - else *(cout-1) = 'p'; - break; - - default: - okay = 0; - } - } - else if (ispunct(*cin) || isspace(*cin)) - { - *cout++ = *cin; - prev = '\0'; - } - else okay = 0; - - is_fatal(okay == 0, "Invalid character \"%c\" in time format!", *cin); - } - return result; -} - - -/* + char *result, *cin, *cout; + char prev; + + result = (char *) xcalloc((2*strlen(human_timef)) + 1, 1); + cout = result; + prev = '\0'; + + for (cin = (char *)human_timef; *cin; cin++) { + int okay = 1; + + if (isalpha(*cin)) { + switch (*cin) { + case 'S': + case 's': + if (prev != 'S') { + strcat(cout, "%S"); + cout += 2; + prev = 'S'; + } + break; + + case 'M': + case 'm': + if (prev != 'M') { + strcat(cout, "%M"); + cout += 2; + prev = 'M'; + } + break; + + case 'h': /* 12-hour-clock */ + if (prev != 'H') { + strcat(cout, "%l"); /* 1 .. 12 */ + cout += 2; + prev = 'H'; + } else { + *(cout-1) = 'I'; /* 01 .. 12 */ + } + break; + + case 'H': /* 24-hour-clock */ + if (prev != 'H') { + strcat(cout, "%k"); + cout += 2; + prev = 'H'; + } else { + *(cout-1) = 'H'; + } + break; + + case 'x': + if (prev != 'X') { + strcat(cout, "%P"); + cout += 2; + prev = 'X'; + } else { + *(cout-1) = 'P'; + } + break; + + case 'X': + if (prev != 'X') { + strcat(cout, "%p"); + cout += 2; + prev = 'X'; + } else { + *(cout-1) = 'p'; + } + break; + + default: + okay = 0; + } + } else if (ispunct(*cin) || isspace(*cin)) { + *cout++ = *cin; + prev = '\0'; + } else { + okay = 0; + } + + is_fatal(okay == 0, "Invalid character \"%c\" in time format!", *cin); + } + return result; +} + + +/* * Return a decimal degree pair as * DD.DDDDD DD MM.MMM or DD MM SS.S * fmt = ['d', 'm', 's'] @@ -1413,42 +1472,42 @@ convert_human_time_format(const char *human_timef) * html = 1 for html output otherwise text */ char * -pretty_deg_format(double lat, double lon, char fmt, const char *sep, int html) -{ - double latmin, lonmin, latsec, lonsec; - int latint, lonint; - char latsig, lonsig; - char *result; - latsig = lat < 0 ? 'S':'N'; - lonsig = lon < 0 ? 'W':'E'; - latint = abs((int) lat); - lonint = abs((int) lon); - latmin = 60.0 * (fabs(lat) - latint); - lonmin = 60.0 * (fabs(lon) - lonint); - latsec = 60.0 * (latmin - floor(latmin)); - lonsec = 60.0 * (lonmin - floor(lonmin)); - if (sep == NULL) sep = " "; /* default " " */ - if (fmt == 'd') { /* ddd */ - xasprintf ( &result, "%c%6.5f%s%s%c%6.5f%s", - latsig, fabs(lat), html?"°":"", sep, - lonsig, fabs(lon), html?"°":"" ); - } - else if (fmt == 's') { /* dms */ - xasprintf ( &result, "%c%d%s%02d'%04.1f\"%s%c%d%s%02d'%04.1f\"", - latsig, latint, html?"°":" ", (int)latmin, latsec, sep, - lonsig, lonint, html?"°":" ", (int)lonmin, lonsec); - } - else { /* default dmm */ - xasprintf ( &result, "%c%d%s%06.3f%s%c%d%s%06.3f", - latsig, latint, html?"°":" ", latmin, sep, - lonsig, lonint, html?"°":" ", lonmin); - } - return result; -} - - - -/* +pretty_deg_format(double lat, double lon, char fmt, const char *sep, int html) +{ + double latmin, lonmin, latsec, lonsec; + int latint, lonint; + char latsig, lonsig; + char *result; + latsig = lat < 0 ? 'S':'N'; + lonsig = lon < 0 ? 'W':'E'; + latint = abs((int) lat); + lonint = abs((int) lon); + latmin = 60.0 * (fabs(lat) - latint); + lonmin = 60.0 * (fabs(lon) - lonint); + latsec = 60.0 * (latmin - floor(latmin)); + lonsec = 60.0 * (lonmin - floor(lonmin)); + if (sep == NULL) { + sep = " "; /* default " " */ + } + if (fmt == 'd') { /* ddd */ + xasprintf(&result, "%c%6.5f%s%s%c%6.5f%s", + latsig, fabs(lat), html?"°":"", sep, + lonsig, fabs(lon), html?"°":""); + } else if (fmt == 's') { /* dms */ + xasprintf(&result, "%c%d%s%02d'%04.1f\"%s%c%d%s%02d'%04.1f\"", + latsig, latint, html?"°":" ", (int)latmin, latsec, sep, + lonsig, lonint, html?"°":" ", (int)lonmin, lonsec); + } else { /* default dmm */ + xasprintf(&result, "%c%d%s%06.3f%s%c%d%s%06.3f", + latsig, latint, html?"°":" ", latmin, sep, + lonsig, lonint, html?"°":" ", lonmin); + } + return result; +} + + + +/* * Get rid of potentially nasty HTML that would influence another record * that includes; * - to stop backgrounds/background colours from being loaded @@ -1458,327 +1517,366 @@ pretty_deg_format(double lat, double lon, char fmt, const char *sep, int html) char * strip_nastyhtml(const char * in) { - char *returnstr, *sp; - char *lcstr, *lcp; - - sp = returnstr = xstrdup(in); - lcp = lcstr = strlower(xstrdup(in)); - - while (lcp = strstr(lcstr, ""), NULL != lcp) { - sp = returnstr + (lcp - lcstr) ; /* becomes */ - sp++; *sp++ = '!'; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; - *lcp = '*'; /* so we wont find it again */ - } - while (lcp = strstr(lcstr, " */ - sp = returnstr + (lcp - lcstr) ; - sp++; *sp++ = '!'; *sp++ = '-'; *sp++ = '-'; - while ( (*sp) && (*sp != '>') ) { - sp++; - } - *--sp = '-'; *--sp = '-'; - *lcp = '*'; /* so we wont find it again */ - } - while (lcp = strstr(lcstr, ""), NULL != lcp) { - sp = returnstr + (lcp - lcstr) ; /* becomes */ - *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = ' '; *sp++ = '-'; *sp++ = '-'; - *lcp = '*'; /* so we wont find it again */ - } - while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + sp++; + *sp++ = '!'; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, " */ + sp = returnstr + (lcp - lcstr) ; + sp++; + *sp++ = '!'; + *sp++ = '-'; + *sp++ = '-'; + while ((*sp) && (*sp != '>')) { + sp++; + } + *--sp = '-'; + *--sp = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, ""), NULL != lcp) { + sp = returnstr + (lcp - lcstr) ; /* becomes */ + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = ' '; + *sp++ = '-'; + *sp++ = '-'; + *lcp = '*'; /* so we wont find it again */ + } + while (lcp = strstr(lcstr, "utfstring; - char tag[8]; - unsigned short int taglen = 0; - - if (!in->is_html) - return xstrdup(in->utfstring); - /* - * We only shorten, so just dupe the input buf for space. - */ - - outstring = out = xstrdup(in->utfstring); - - tag[0] = 0; - while (*instr) { - if ((*instr == '<') || (*instr == '&')) { - tag[0] = *instr; - taglen = 0; - } - - if (! tag[0]) { - if (*instr == '\n') { - *out++ = ' '; - do { - instr++; - } while (isspace(*instr)); - continue; - } else { - *out++ = *instr; - } - } - else { - if (taglen < (sizeof(tag)-1)) { - tag[taglen++] = tolower(*instr); - tag[taglen] = 0; - } - } - - if ( ((tag[0] == '<') && (*instr == '>')) || - ((tag[0] == '&') && (*instr == ';')) ) { - if (! strcmp(tag,"&")) - *out++ = '&'; - else if (! strcmp (tag, "<")) - *out++ = '<'; - else if (! strcmp (tag, ">")) - *out++ = '>'; - else if (! strcmp (tag, """)) - *out++ = '"'; - else if (! strcmp (tag, " ")) - *out++ = ' '; - else if (! strcmp (tag, "°")) { - *out++ = 'd'; *out++ = 'e'; *out++ = 'g'; - } - else if ((tag[0]=='<') && (tag[1]=='p')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='b') && (tag[2]=='r')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='r')) - *out++ = '\n'; - else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='d')) - *out++ = ' '; - else if ((tag[0]=='<') && (tag[1]=='i') && (tag[2]=='m') && (tag[3]=='g')) { - *out++ = '['; *out++ = 'I'; *out++ = 'M'; *out++ = 'G'; *out++ = ']'; - } - - tag[0] = 0; - } - instr++; - } - *out++ = 0; - return (outstring); + char *outstring, *out; + char *instr = in->utfstring; + char tag[8]; + unsigned short int taglen = 0; + + if (!in->is_html) { + return xstrdup(in->utfstring); + } + /* + * We only shorten, so just dupe the input buf for space. + */ + + outstring = out = xstrdup(in->utfstring); + + tag[0] = 0; + while (*instr) { + if ((*instr == '<') || (*instr == '&')) { + tag[0] = *instr; + taglen = 0; + } + + if (! tag[0]) { + if (*instr == '\n') { + *out++ = ' '; + do { + instr++; + } while (isspace(*instr)); + continue; + } else { + *out++ = *instr; + } + } else { + if (taglen < (sizeof(tag)-1)) { + tag[taglen++] = tolower(*instr); + tag[taglen] = 0; + } + } + + if (((tag[0] == '<') && (*instr == '>')) || + ((tag[0] == '&') && (*instr == ';'))) { + if (! strcmp(tag,"&")) { + *out++ = '&'; + } else if (! strcmp(tag, "<")) { + *out++ = '<'; + } else if (! strcmp(tag, ">")) { + *out++ = '>'; + } else if (! strcmp(tag, """)) { + *out++ = '"'; + } else if (! strcmp(tag, " ")) { + *out++ = ' '; + } else if (! strcmp(tag, "°")) { + *out++ = 'd'; + *out++ = 'e'; + *out++ = 'g'; + } else if ((tag[0]=='<') && (tag[1]=='p')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='b') && (tag[2]=='r')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='r')) { + *out++ = '\n'; + } else if ((tag[0]=='<') && (tag[1]=='/') && (tag[2]=='t') && (tag[3]=='d')) { + *out++ = ' '; + } else if ((tag[0]=='<') && (tag[1]=='i') && (tag[2]=='m') && (tag[3]=='g')) { + *out++ = '['; + *out++ = 'I'; + *out++ = 'M'; + *out++ = 'G'; + *out++ = ']'; + } + + tag[0] = 0; + } + instr++; + } + *out++ = 0; + return (outstring); } typedef struct { - const char * text; - const char * entity; - int not_html; + const char * text; + const char * entity; + int not_html; } entity_types; -static +static entity_types stdentities[] = { - { "&", "&", 0 }, - { "'", "'", 1 }, - { "<", "<", 0 }, - { ">", ">", 0 }, - { "\"", """, 0 }, - { NULL, NULL, 0 } + { "&", "&", 0 }, + { "'", "'", 1 }, + { "<", "<", 0 }, + { ">", ">", 0 }, + { "\"", """, 0 }, + { NULL, NULL, 0 } }; -static -char * -entitize(const char * str, int is_html) -{ - int elen, ecount, nsecount; - entity_types *ep; - const char * cp; - char * p, * tmp, * xstr; - - int bytes = 0; - int value = 0; - ep = stdentities; - elen = ecount = nsecount = 0; - - /* figure # of entity replacements and additional size. */ - while (ep->text) { - cp = str; - while ((cp = strstr(cp, ep->text)) != NULL) { - elen += strlen(ep->entity) - strlen(ep->text); - ecount++; - cp += strlen(ep->text); - } - ep++; - } - - /* figure the same for other than standard entities (i.e. anything - * that isn't in the range U+0000 to U+007F */ - +static +char * +entitize(const char * str, int is_html) +{ + int elen, ecount, nsecount; + entity_types *ep; + const char * cp; + char * p, * tmp, * xstr; + + int bytes = 0; + int value = 0; + ep = stdentities; + elen = ecount = nsecount = 0; + + /* figure # of entity replacements and additional size. */ + while (ep->text) { + cp = str; + while ((cp = strstr(cp, ep->text)) != NULL) { + elen += strlen(ep->entity) - strlen(ep->text); + ecount++; + cp += strlen(ep->text); + } + ep++; + } + + /* figure the same for other than standard entities (i.e. anything + * that isn't in the range U+0000 to U+007F */ + #if 0 - for ( cp = str; *cp; cp++ ) { - if ( *cp & 0x80 ) { - cet_utf8_to_ucs4( cp, &bytes, &value ); - cp += bytes-1; - elen += sprintf( tmpsub, "&#x%x;", value ) - bytes; - nsecount++; - } - } + for (cp = str; *cp; cp++) { + if (*cp & 0x80) { + cet_utf8_to_ucs4(cp, &bytes, &value); + cp += bytes-1; + elen += sprintf(tmpsub, "&#x%x;", value) - bytes; + nsecount++; + } + } #endif - /* enough space for the whole string plus entity replacements, if any */ - tmp = (char *) xcalloc((strlen(str) + elen + 1), 1); - strcpy(tmp, str); - - /* no entity replacements */ - if (ecount == 0 && nsecount == 0) - return (tmp); - - if ( ecount != 0 ) { - for (ep = stdentities; ep->text; ep++) { - p = tmp; - if (is_html && ep->not_html) { - continue; - } - while ((p = strstr(p, ep->text)) != NULL) { - elen = strlen(ep->entity); - - xstr = xstrdup(p + strlen(ep->text)); - - strcpy(p, ep->entity); - strcpy(p + elen, xstr); - - xfree(xstr); - - p += elen; - } - } - } - - if ( nsecount != 0 ) { - p = tmp; - while (*p) { - if ( *p & 0x80 ) { - cet_utf8_to_ucs4( p, &bytes, &value ); - if ( p[bytes] ) { - xstr = xstrdup( p + bytes ); - } - else { - xstr = NULL; - } - sprintf( p, "&#x%x;", value ); - p = p+strlen(p); - if ( xstr ) { - strcpy( p, xstr ); - xfree(xstr); - } - } - else { - p++; - } - } - } - return (tmp); + /* enough space for the whole string plus entity replacements, if any */ + tmp = (char *) xcalloc((strlen(str) + elen + 1), 1); + strcpy(tmp, str); + + /* no entity replacements */ + if (ecount == 0 && nsecount == 0) { + return (tmp); + } + + if (ecount != 0) { + for (ep = stdentities; ep->text; ep++) { + p = tmp; + if (is_html && ep->not_html) { + continue; + } + while ((p = strstr(p, ep->text)) != NULL) { + elen = strlen(ep->entity); + + xstr = xstrdup(p + strlen(ep->text)); + + strcpy(p, ep->entity); + strcpy(p + elen, xstr); + + xfree(xstr); + + p += elen; + } + } + } + + if (nsecount != 0) { + p = tmp; + while (*p) { + if (*p & 0x80) { + cet_utf8_to_ucs4(p, &bytes, &value); + if (p[bytes]) { + xstr = xstrdup(p + bytes); + } else { + xstr = NULL; + } + sprintf(p, "&#x%x;", value); + p = p+strlen(p); + if (xstr) { + strcpy(p, xstr); + xfree(xstr); + } + } else { + p++; + } + } + } + return (tmp); } /* * Public callers for the above to hide the absence of &apos from HTML */ -char * xml_entitize(const char * str) +char * xml_entitize(const char * str) { - return entitize(str, 0); + return entitize(str, 0); } -char * html_entitize(const char * str) +char * html_entitize(const char * str) { - return entitize(str, 1); + return entitize(str, 1); } /* * xml_tag utilities */ -xml_tag *xml_next( xml_tag *root, xml_tag *cur ) -{ - if ( cur->child ) { - cur = cur->child; - } - else if ( cur->sibling ) { - cur = cur->sibling; - } - else { - cur = cur->parent; - if ( cur == root ) { - cur = NULL; - } - if ( cur ) { - cur = cur->sibling; - } - } - return cur; +xml_tag *xml_next(xml_tag *root, xml_tag *cur) +{ + if (cur->child) { + cur = cur->child; + } else if (cur->sibling) { + cur = cur->sibling; + } else { + cur = cur->parent; + if (cur == root) { + cur = NULL; + } + if (cur) { + cur = cur->sibling; + } + } + return cur; } -xml_tag *xml_findnext( xml_tag *root, xml_tag *cur, const char *tagname ) +xml_tag *xml_findnext(xml_tag *root, xml_tag *cur, const char *tagname) { - xml_tag *result = cur; - do { - result = xml_next( root, result ); - } while ( result && case_ignore_strcmp( result->tagname, tagname )); - return result; + xml_tag *result = cur; + do { + result = xml_next(root, result); + } while (result && case_ignore_strcmp(result->tagname, tagname)); + return result; } -xml_tag *xml_findfirst( xml_tag *root, const char *tagname ) +xml_tag *xml_findfirst(xml_tag *root, const char *tagname) { - return xml_findnext( root, root, tagname ); + return xml_findnext(root, root, tagname); } -char *xml_attribute( xml_tag *tag, const char *attrname ) +char *xml_attribute(xml_tag *tag, const char *attrname) { - char *result = NULL; - if ( tag->attributes ) { - char **attr = tag->attributes; - while ( attr && *attr ) { - if ( 0 == case_ignore_strcmp( *attr, attrname )) { - result = attr[1]; - break; - } - attr+=2; - } - } - return result; + char *result = NULL; + if (tag->attributes) { + char **attr = tag->attributes; + while (attr && *attr) { + if (0 == case_ignore_strcmp(*attr, attrname)) { + result = attr[1]; + break; + } + attr+=2; + } + } + return result; } char *get_filename(const char *fname) { - char *res, *cb, *cs; - - cb = strrchr(fname, '\\'); - cs = strrchr(fname, '/'); - - if (cb == NULL) res = cs; - else if (cs == NULL) res = cb; - else res = (cs > cb) ? cs : cb; - - return (res == NULL) ? (char *) fname : ++res; + char *res, *cb, *cs; + + cb = strrchr(fname, '\\'); + cs = strrchr(fname, '/'); + + if (cb == NULL) { + res = cs; + } else if (cs == NULL) { + res = cb; + } else { + res = (cs > cb) ? cs : cb; + } + + return (res == NULL) ? (char *) fname : ++res; } /* bit manipulation functions */ @@ -1788,8 +1886,8 @@ char *get_filename(const char *fname) */ void gb_setbit(void *buf, const gbuint32 nr) { - unsigned char *bytes = (unsigned char *) buf; - bytes[nr / 8] |= (1 << (nr % 8)); + unsigned char *bytes = (unsigned char *) buf; + bytes[nr / 8] |= (1 << (nr % 8)); } /* @@ -1797,9 +1895,9 @@ void gb_setbit(void *buf, const gbuint32 nr) */ char gb_getbit(const void *buf, const gbuint32 nr) { - const unsigned char *bytes = (const unsigned char *) buf; - return (bytes[nr / 8] & (1 << (nr % 8))); - + const unsigned char *bytes = (const unsigned char *) buf; + return (bytes[nr / 8] & (1 << (nr % 8))); + } /* @@ -1807,13 +1905,13 @@ char gb_getbit(const void *buf, const gbuint32 nr) */ void *gb_int2ptr(const int i) { - union { - void *p; - int i; - } x = { NULL }; + union { + void *p; + int i; + } x = { NULL }; - x.i = i; - return x.p; + x.i = i; + return x.p; } /* @@ -1821,10 +1919,10 @@ void *gb_int2ptr(const int i) */ int gb_ptr2int(const void *p) { - union { - const void *p; - int i; - } x = { p }; + union { + const void *p; + int i; + } x = { p }; - return x.i; + return x.i; } diff --git a/gpsbabel/util_crc.c b/gpsbabel/util_crc.c index cba43adcb..4e91871d2 100644 --- a/gpsbabel/util_crc.c +++ b/gpsbabel/util_crc.c @@ -19,65 +19,64 @@ */ -static unsigned long crc32_table[256] = -{ - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, - 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, - 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, - 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, - 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, - 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, - 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, - 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, - 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, - 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, - 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, - 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, - 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, - 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, - 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, - 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, - 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, - 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, - 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, - 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, - 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, - 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +static unsigned long crc32_table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, + 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, + 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, + 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C, + 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, + 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, + 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, + 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, + 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, + 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, + 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, + 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, + 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, + 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E, + 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, + 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, + 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, + 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, + 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, + 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, + 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, + 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; unsigned long get_crc32(const void * data, int datalen) { - unsigned long crc = 0xFFFFFFFF; - const unsigned char * cp = (unsigned char *)data; + unsigned long crc = 0xFFFFFFFF; + const unsigned char * cp = (unsigned char *)data; - while (cp < ((unsigned char *)data + datalen)) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; - cp++; - } + while (cp < ((unsigned char *)data + datalen)) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + cp++; + } - return (crc ^ 0xFFFFFFFF); + return (crc ^ 0xFFFFFFFF); } /* @@ -86,11 +85,11 @@ get_crc32(const void * data, int datalen) unsigned long get_crc32_s(const void *data) { - unsigned long crc = 0xFFFFFFFF; - const unsigned char* cp = (unsigned char *)data; + unsigned long crc = 0xFFFFFFFF; + const unsigned char* cp = (unsigned char *)data; - for (;*cp;cp++) { - crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; - } - return (crc ^ 0xFFFFFFFF); + for (; *cp; cp++) { + crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc ^ *cp) &0xFF]; + } + return (crc ^ 0xFFFFFFFF); } diff --git a/gpsbabel/uuid.c b/gpsbabel/uuid.c index cba1d65ff..9ad956fb4 100755 --- a/gpsbabel/uuid.c +++ b/gpsbabel/uuid.c @@ -23,15 +23,15 @@ void gb_uuid_generate(uuid_t uu) { - unsigned char *cp; - int i; - for (cp = uu, i = 0; i < 16; i++) { - if (getenv("GPSBABEL_FREEZE_TIME")) { - static unsigned char blech = 0; - *cp++ = blech++; - } else { - *cp++ ^= (rand() >> 7) & 0xFF; - } - } + unsigned char *cp; + int i; + for (cp = uu, i = 0; i < 16; i++) { + if (getenv("GPSBABEL_FREEZE_TIME")) { + static unsigned char blech = 0; + *cp++ = blech++; + } else { + *cp++ ^= (rand() >> 7) & 0xFF; + } + } } diff --git a/gpsbabel/v900.c b/gpsbabel/v900.c index 6eae4643f..7c894fcb7 100644 --- a/gpsbabel/v900.c +++ b/gpsbabel/v900.c @@ -1,4 +1,4 @@ -/* +/* Support for Columbus/Visiontac V900 csv format This format pads fields with NULL up to a fixed per field length. Because of that, and because xcsv does not allows a regex as a field delimiter, @@ -40,17 +40,17 @@ Two modes are available: basic and advanced. The following two examples show "*" where null appears. -------basic mode - start------------------------- +------basic mode - start------------------------- INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX 1*****,T,090404,063401,31.765931N,035.206969E,821**,0***,0**,********* 2*****,T,090404,063402,31.765931N,035.206969E,821**,0***,0**,********* 3*****,T,090404,063403,31.765933N,035.206971E,821**,0***,0**,********* 4*****,T,090404,063404,31.765933N,035.206971E,822**,0***,0**,********* 5*****,T,090404,063407,31.765934N,035.206971E,824**,0***,0**,********* -------basic mode - end--------------------------- +------basic mode - end--------------------------- -------advanced mode - start------------------------- +------advanced mode - start------------------------- INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX 1*****,T,090204,055722,31.768380N,035.209656E,149**,0***,0**,3D,SPS ,2.6**,2.4**,1.0**,********* 2*****,T,090204,055723,31.768380N,035.209656E,149**,0***,0**,3D,SPS ,2.5**,2.3**,0.9**,********* @@ -65,9 +65,9 @@ INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VAL 11****,T,090204,055739,31.768338N,035.209991E,155**,0***,0**,3D,SPS ,2.5**,2.3**,0.9**,********* 42****,C,090724,162320,31.763841N,035.205461E,788**,9***,344,3D,SPS ,1.2**,0.9**,0.8**,********* 121***,V,090724,162502,31.769619N,035.208964E,786**,16**,306,3D,SPS ,1.1**,0.8**,0.8**,VOX00003* -------advanced mode - end--------------------------- +------advanced mode - end--------------------------- -for a little more info, see structures: +for a little more info, see structures: one_line_advanced_mode, one_line_basic_mode, one_line_common_start. ******************************************************************************/ @@ -76,70 +76,67 @@ for a little more info, see structures: #include #if _MSC_VER - #define __func__ __FUNCTION__ +#define __func__ __FUNCTION__ #endif /* the start of each record (line) is common to both advanced and basic mode. it will be parsed by a single common code. hence, it will be easier and clearer to have a common structure for it. */ -struct one_line_common_start -{ - char index[6]; /* record number */ - char comma1; /* ',' */ - char tag; /* tag type. T=trackpoint. TODO: more options??? */ - char comma2; /* ',' */ - char date[6]; /* YYMMDD. YY=09 is 2009. */ - char comma3; /* ',' */ - char time[6]; /* HHMMSS */ - char comma4; /* ',' */ - char latitude_num[9]; /* example: "31.768380" */ - char latitude_NS; /* 'N' or 'S' */ - char comma5; /* ',' */ - char longitude_num[10]; /* example: "035.209656" */ - char longitude_EW; /* 'E' or 'W' */ - char comma6; /* ',' */ - char height[5]; /* Altitude in meters. +struct one_line_common_start { + char index[6]; /* record number */ + char comma1; /* ',' */ + char tag; /* tag type. T=trackpoint. TODO: more options??? */ + char comma2; /* ',' */ + char date[6]; /* YYMMDD. YY=09 is 2009. */ + char comma3; /* ',' */ + char time[6]; /* HHMMSS */ + char comma4; /* ',' */ + char latitude_num[9]; /* example: "31.768380" */ + char latitude_NS; /* 'N' or 'S' */ + char comma5; /* ',' */ + char longitude_num[10]; /* example: "035.209656" */ + char longitude_EW; /* 'E' or 'W' */ + char comma6; /* ',' */ + char height[5]; /* Altitude in meters. * (not corrected to WGS84 ??) */ - char comma7; /* ',' */ - char speed[4]; /* speed in km/h. no decimal point. */ - char comma8; /* ',' */ - char heading[3]; /* heading in degrees */ - char comma9; /* ',' */ + char comma7; /* ',' */ + char speed[4]; /* speed in km/h. no decimal point. */ + char comma8; /* ',' */ + char heading[3]; /* heading in degrees */ + char comma9; /* ',' */ }; /* this structure holds one record (line) in advanced logging mode. advanced mode lines looks like this ('*' means NULL): 1717**,T,090204,062634,31.765528N,035.207730E,772**,0***,0**,2D,SPS ,2.1**,1.9**,1.0**,********* */ -struct one_line_advanced_mode -{ - struct one_line_common_start common; - char fixmode[2]; /* "2D" or "3D" */ - char comma10; /* ',' */ - char valid[4]; /* "SPS " or "DGPS" */ - char comma11; /* ',' */ - char pdop[5]; - char comma12; /* ',' */ - char hdop[5]; - char comma13; /* ',' */ - char vdop[5]; - char comma14; /* ',' */ - char vox[9]; /* voicetag recorded */ - char cr; /* '\r' */ - char lf; /* '\n' */ +struct one_line_advanced_mode { + struct one_line_common_start common; + char fixmode[2]; /* "2D" or "3D" */ + char comma10; /* ',' */ + char valid[4]; /* "SPS " or "DGPS" */ + char comma11; /* ',' */ + char pdop[5]; + char comma12; /* ',' */ + char hdop[5]; + char comma13; /* ',' */ + char vdop[5]; + char comma14; /* ',' */ + char vox[9]; /* voicetag recorded */ + char cr; /* '\r' */ + char lf; /* '\n' */ }; /* this structure holds one record (line) in basic logging mode. basic mode lines looks like this ('*' means NULL): 1*****,T,090404,063401,31.765931N,035.206969E,821**,0***,0**,********* */ -struct one_line_basic_mode -{ - struct one_line_common_start common; - char vox[9]; /* voicetag recorded */ - char cr; /* '\r' */ - char lf; /* '\n' */ +struct one_line_basic_mode { + struct one_line_common_start common; + char vox[9]; /* voicetag recorded */ + char cr; /* '\r' */ + char lf; /* '\n' */ }; @@ -149,36 +146,38 @@ static FILE* fin = NULL; static void v900_log(const char *fmt, ...) { - va_list ap; + va_list ap; - if (global_opts.debug_level < 1) { - return; - } + if (global_opts.debug_level < 1) { + return; + } - va_start (ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); } static void v900_rd_init(const char *fname) { - v900_log("%s(%s)\n",__func__,fname); - /* note: file is opened in binary mode, since lines end with \r\n, and in windows text mode - that will be translated to a single \n, making the line len one character shorter than - on linux machines. - */ - fin = fopen(fname,"rb"); - if (!fin) - fatal("v900: could not open '%s'.\n", fname); + v900_log("%s(%s)\n",__func__,fname); + /* note: file is opened in binary mode, since lines end with \r\n, and in windows text mode + that will be translated to a single \n, making the line len one character shorter than + on linux machines. + */ + fin = fopen(fname,"rb"); + if (!fin) { + fatal("v900: could not open '%s'.\n", fname); + } } static void v900_rd_deinit(void) { - v900_log("%s\n",__func__); - if (fin) - fclose(fin); + v900_log("%s\n",__func__); + if (fin) { + fclose(fin); + } } @@ -186,210 +185,206 @@ v900_rd_deinit(void) static time_t bintime2utc(int date, int time) { - struct tm gpstime; - - gpstime.tm_sec = time % 100; - time /= 100; - gpstime.tm_min = time % 100; - time /= 100; - gpstime.tm_hour = time; - - /* - * GPS year: 2000+; struct tm year: 1900+ - * GPS month: 1-12, struct tm month: 0-11 - */ - gpstime.tm_mday = date % 100; - date /= 100; - gpstime.tm_mon = date % 100 - 1; - date /= 100; - gpstime.tm_year = date + 100; - - return(mkgmtime(&gpstime)); + struct tm gpstime; + + gpstime.tm_sec = time % 100; + time /= 100; + gpstime.tm_min = time % 100; + time /= 100; + gpstime.tm_hour = time; + + /* + * GPS year: 2000+; struct tm year: 1900+ + * GPS month: 1-12, struct tm month: 0-11 + */ + gpstime.tm_mday = date % 100; + date /= 100; + gpstime.tm_mon = date % 100 - 1; + date /= 100; + gpstime.tm_year = date + 100; + + return(mkgmtime(&gpstime)); } static void v900_read(void) { - /* use line buffer large enough to hold either basic or advanced mode lines. */ - union - { - struct one_line_basic_mode bas; - struct one_line_advanced_mode adv; - char text[200]; /* used to read the header line, which is normal text */ - } line; - int is_advanced_mode = 0; - int lc = 0; - route_head *track; - - v900_log("%s\n",__func__); - -/* -Basic mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX -Advanced mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX -*/ - /* first, determine if this is advanced mode by reading the first line. + /* use line buffer large enough to hold either basic or advanced mode lines. */ + union { + struct one_line_basic_mode bas; + struct one_line_advanced_mode adv; + char text[200]; /* used to read the header line, which is normal text */ + } line; + int is_advanced_mode = 0; + int lc = 0; + route_head *track; + + v900_log("%s\n",__func__); + + /* + Basic mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,VOX + Advanced mode: INDEX,TAG,DATE,TIME,LATITUDE N/S,LONGITUDE E/W,HEIGHT,SPEED,HEADING,FIX MODE,VALID,PDOP,HDOP,VDOP,VOX + */ + /* first, determine if this is advanced mode by reading the first line. since the first line does not contain any nulls, it can be safely read by fgets(). */ - if (!fgets(line.text, sizeof(line), fin)) - fatal("v900: error reading header (first) line from input file\n"); - is_advanced_mode = (NULL != strstr(line.text,"PDOP")); /* PDOP field appears only in advanced mode */ - - v900_log("header line: %s",line.text); - v900_log("is_advance_mode=%d\n",is_advanced_mode); - - track = route_head_alloc(); - track->rte_name = xstrdup("V900 tracklog"); - track->rte_desc = xstrdup("V900 GPS tracklog data"); - track_add_head(track); - - while (1) - { - waypoint *wpt; - char c; - int bad = 0; - int record_len = is_advanced_mode ? sizeof(line.adv) : sizeof(line.bas); - if (fread ( &line, record_len, 1, fin ) != 1) - { - break; - } - lc++; - - /* change all "," characters to NULLs. + if (!fgets(line.text, sizeof(line), fin)) { + fatal("v900: error reading header (first) line from input file\n"); + } + is_advanced_mode = (NULL != strstr(line.text,"PDOP")); /* PDOP field appears only in advanced mode */ + + v900_log("header line: %s",line.text); + v900_log("is_advance_mode=%d\n",is_advanced_mode); + + track = route_head_alloc(); + track->rte_name = xstrdup("V900 tracklog"); + track->rte_desc = xstrdup("V900 GPS tracklog data"); + track_add_head(track); + + while (1) { + waypoint *wpt; + char c; + int bad = 0; + int record_len = is_advanced_mode ? sizeof(line.adv) : sizeof(line.bas); + if (fread(&line, record_len, 1, fin) != 1) { + break; + } + lc++; + + /* change all "," characters to NULLs. so every field is null terminated. */ - bad |= (line.bas.common.comma1 != ','); - bad |= (line.bas.common.comma2 != ','); - bad |= (line.bas.common.comma3 != ','); - bad |= (line.bas.common.comma4 != ','); - bad |= (line.bas.common.comma5 != ','); - bad |= (line.bas.common.comma6 != ','); - bad |= (line.bas.common.comma7 != ','); - bad |= (line.bas.common.comma8 != ','); - bad |= (line.bas.common.comma9 != ','); - - if (bad) { - warning("v900: skipping malformed record at line %d\n", lc); - } - - line.bas.common.comma1 = 0; - line.bas.common.comma2 = 0; - line.bas.common.comma3 = 0; - line.bas.common.comma4 = 0; - line.bas.common.comma5 = 0; - line.bas.common.comma6 = 0; - line.bas.common.comma7 = 0; - line.bas.common.comma8 = 0; - line.bas.common.comma9 = 0; - if(is_advanced_mode) - { - /* change all "," characters to NULLs. - so every field is null terminated. - */ - assert(line.adv.comma10==','); // TODO: abort with fatal() - assert(line.adv.comma11==','); - assert(line.adv.comma12==','); - assert(line.adv.comma13==','); - assert(line.adv.comma14==','); - assert(line.adv.cr=='\r'); - assert(line.adv.lf=='\n'); - line.adv.comma10 = 0; - line.adv.comma11 = 0; - line.adv.comma12 = 0; - line.adv.comma13 = 0; - line.adv.comma14 = 0; - line.adv.cr = 0; /* null terminate vox field */ - - } - else - { - assert(line.bas.cr=='\r'); - assert(line.bas.lf=='\n'); - line.bas.cr = 0; /* null terminate vox field */ - } - - wpt = waypt_new(); - - /* lat is a string in the form: 31.768380N */ - c = line.bas.common.latitude_NS; /* N/S */ - assert(c == 'N' || c == 'S'); - wpt->latitude = atof(line.bas.common.latitude_num); - if (c == 'S') - wpt->latitude = -wpt->latitude; - - /* lon is a string in the form: 035.209656E */ - c = line.bas.common.longitude_EW; /* get E/W */ - assert(c == 'E' || c == 'W'); - line.bas.common.longitude_EW = 0; /* the E will confuse atof(), if not removed */ - wpt->longitude = atof(line.bas.common.longitude_num); - if (c == 'W') - wpt->longitude = -wpt->longitude; - - wpt->altitude = atoi(line.bas.common.height); - - /* handle date/time fields */ - { - int date, time; - date = atoi(line.bas.common.date); - time = atoi(line.bas.common.time); - wpt->creation_time = bintime2utc(date, time); - } - - wpt->speed = KPH_TO_MPS(atoi(line.bas.common.speed)); - wpt->wpt_flags.speed = 1; - - wpt->course = atoi(line.bas.common.heading); - wpt->wpt_flags.course = 1; - - if(is_advanced_mode) - { - wpt->hdop = atof(line.adv.hdop); - wpt->vdop = atof(line.adv.vdop); - wpt->pdop = atof(line.adv.pdop); - - /* handle fix mode (2d, 3d, etc.) */ - if (!strcmp(line.adv.valid,"DGPS")) - wpt->fix = fix_dgps; - else if (!strcmp(line.adv.fixmode,"3D")) - wpt->fix = fix_3d; - else if (!strcmp(line.adv.fixmode,"2D")) - wpt->fix = fix_2d; - else - /* possible values: fix_unknown,fix_none,fix_2d,fix_3d,fix_dgps,fix_pps */ - wpt->fix = fix_unknown; - } - - track_add_wpt(track, wpt); - if(line.bas.common.tag != 'T') - { - waypoint *wpt2; - assert(line.bas.common.tag == 'C' || line.bas.common.tag == 'V'); - wpt2 = waypt_dupe(wpt); - if(line.bas.common.tag == 'V') // waypoint with voice recording? - { - char vox_file_name[sizeof(line.adv.vox)+5]; - const char *vox = is_advanced_mode ? line.adv.vox : line.bas.vox; - assert(vox[0] != '\0'); - strcpy(vox_file_name,vox); - strcat(vox_file_name,".WAV"); - wpt2->shortname = xstrdup(vox_file_name); - wpt2->description = xstrdup(vox_file_name); - waypt_add_url(wpt2, xstrdup(vox_file_name), xstrdup(vox_file_name)); - } - waypt_add(wpt2); - } - } + bad |= (line.bas.common.comma1 != ','); + bad |= (line.bas.common.comma2 != ','); + bad |= (line.bas.common.comma3 != ','); + bad |= (line.bas.common.comma4 != ','); + bad |= (line.bas.common.comma5 != ','); + bad |= (line.bas.common.comma6 != ','); + bad |= (line.bas.common.comma7 != ','); + bad |= (line.bas.common.comma8 != ','); + bad |= (line.bas.common.comma9 != ','); + + if (bad) { + warning("v900: skipping malformed record at line %d\n", lc); + } + + line.bas.common.comma1 = 0; + line.bas.common.comma2 = 0; + line.bas.common.comma3 = 0; + line.bas.common.comma4 = 0; + line.bas.common.comma5 = 0; + line.bas.common.comma6 = 0; + line.bas.common.comma7 = 0; + line.bas.common.comma8 = 0; + line.bas.common.comma9 = 0; + if (is_advanced_mode) { + /* change all "," characters to NULLs. + so every field is null terminated. + */ + assert(line.adv.comma10==','); // TODO: abort with fatal() + assert(line.adv.comma11==','); + assert(line.adv.comma12==','); + assert(line.adv.comma13==','); + assert(line.adv.comma14==','); + assert(line.adv.cr=='\r'); + assert(line.adv.lf=='\n'); + line.adv.comma10 = 0; + line.adv.comma11 = 0; + line.adv.comma12 = 0; + line.adv.comma13 = 0; + line.adv.comma14 = 0; + line.adv.cr = 0; /* null terminate vox field */ + + } else { + assert(line.bas.cr=='\r'); + assert(line.bas.lf=='\n'); + line.bas.cr = 0; /* null terminate vox field */ + } + + wpt = waypt_new(); + + /* lat is a string in the form: 31.768380N */ + c = line.bas.common.latitude_NS; /* N/S */ + assert(c == 'N' || c == 'S'); + wpt->latitude = atof(line.bas.common.latitude_num); + if (c == 'S') { + wpt->latitude = -wpt->latitude; + } + + /* lon is a string in the form: 035.209656E */ + c = line.bas.common.longitude_EW; /* get E/W */ + assert(c == 'E' || c == 'W'); + line.bas.common.longitude_EW = 0; /* the E will confuse atof(), if not removed */ + wpt->longitude = atof(line.bas.common.longitude_num); + if (c == 'W') { + wpt->longitude = -wpt->longitude; + } + + wpt->altitude = atoi(line.bas.common.height); + + /* handle date/time fields */ + { + int date, time; + date = atoi(line.bas.common.date); + time = atoi(line.bas.common.time); + wpt->creation_time = bintime2utc(date, time); + } + + wpt->speed = KPH_TO_MPS(atoi(line.bas.common.speed)); + wpt->wpt_flags.speed = 1; + + wpt->course = atoi(line.bas.common.heading); + wpt->wpt_flags.course = 1; + + if (is_advanced_mode) { + wpt->hdop = atof(line.adv.hdop); + wpt->vdop = atof(line.adv.vdop); + wpt->pdop = atof(line.adv.pdop); + + /* handle fix mode (2d, 3d, etc.) */ + if (!strcmp(line.adv.valid,"DGPS")) { + wpt->fix = fix_dgps; + } else if (!strcmp(line.adv.fixmode,"3D")) { + wpt->fix = fix_3d; + } else if (!strcmp(line.adv.fixmode,"2D")) { + wpt->fix = fix_2d; + } else + /* possible values: fix_unknown,fix_none,fix_2d,fix_3d,fix_dgps,fix_pps */ + { + wpt->fix = fix_unknown; + } + } + + track_add_wpt(track, wpt); + if (line.bas.common.tag != 'T') { + waypoint *wpt2; + assert(line.bas.common.tag == 'C' || line.bas.common.tag == 'V'); + wpt2 = waypt_dupe(wpt); + if (line.bas.common.tag == 'V') { // waypoint with voice recording? + char vox_file_name[sizeof(line.adv.vox)+5]; + const char *vox = is_advanced_mode ? line.adv.vox : line.bas.vox; + assert(vox[0] != '\0'); + strcpy(vox_file_name,vox); + strcat(vox_file_name,".WAV"); + wpt2->shortname = xstrdup(vox_file_name); + wpt2->description = xstrdup(vox_file_name); + waypt_add_url(wpt2, xstrdup(vox_file_name), xstrdup(vox_file_name)); + } + waypt_add(wpt2); + } + } } ff_vecs_t v900_vecs = { - ff_type_file, - {ff_cap_read, ff_cap_read, ff_cap_none}, /* Read only format. May only read trackpoints and waypoints. */ - v900_rd_init, - NULL, /* wr_init */ - v900_rd_deinit, - NULL, /* wr_deinit */ - v900_read, - NULL, /* write */ - NULL, - NULL, /* args */ - CET_CHARSET_UTF8, 1, /* Could be US-ASCII, since we only read "0-9,A-Z\n\r" */ - {NULL,NULL,NULL,NULL,NULL,NULL} + ff_type_file, + {ff_cap_read, ff_cap_read, ff_cap_none}, /* Read only format. May only read trackpoints and waypoints. */ + v900_rd_init, + NULL, /* wr_init */ + v900_rd_deinit, + NULL, /* wr_deinit */ + v900_read, + NULL, /* write */ + NULL, + NULL, /* args */ + CET_CHARSET_UTF8, 1, /* Could be US-ASCII, since we only read "0-9,A-Z\n\r" */ + {NULL,NULL,NULL,NULL,NULL,NULL} }; diff --git a/gpsbabel/vcf.c b/gpsbabel/vcf.c index 9067a976b..9fee87eaa 100644 --- a/gpsbabel/vcf.c +++ b/gpsbabel/vcf.c @@ -32,23 +32,25 @@ static char *vcf_encrypt = NULL; static arglist_t vcf_args[] = { - { "encrypt", &vcf_encrypt, - "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "encrypt", &vcf_encrypt, + "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static void wr_init(const char *fname) { - file_out = gbfopen(fname, "w", MYNAME); - mkshort_handle = mkshort_new_handle(); + file_out = gbfopen(fname, "w", MYNAME); + mkshort_handle = mkshort_new_handle(); } static void wr_deinit(void) { - gbfclose(file_out); - mkshort_del_handle(&mkshort_handle); + gbfclose(file_out); + mkshort_del_handle(&mkshort_handle); } /* @@ -58,86 +60,88 @@ wr_deinit(void) static void vcf_print_utf(const utf_string *s) { - char *p, *p2, *p3; - char *stripped_html; - - if (!s) - return; - - stripped_html = strip_html(s); - p = gstrsub(stripped_html, "\n", "\\n"); - p2 = gstrsub(p, "

", "\\n"); - p3 = gstrsub(p2, ";", "\\;"); - gbfputs(p3, file_out); - xfree(p); - xfree(p2); - xfree(p3); - xfree(stripped_html); + char *p, *p2, *p3; + char *stripped_html; + + if (!s) { + return; + } + + stripped_html = strip_html(s); + p = gstrsub(stripped_html, "\n", "\\n"); + p2 = gstrsub(p, "

", "\\n"); + p3 = gstrsub(p2, ";", "\\;"); + gbfputs(p3, file_out); + xfree(p); + xfree(p2); + xfree(p3); + xfree(stripped_html); } static void vcf_print(const char *s) { - char *p; + char *p; - if (!s) - return; + if (!s) { + return; + } - p = gstrsub(s, "\n", "\\n"); - gbfputs(p, file_out); - xfree(p); + p = gstrsub(s, "\n", "\\n"); + gbfputs(p, file_out); + xfree(p); } static void vcf_disp(const waypoint *wpt) { - int latint, lonint; - - lonint = abs((int) wpt->longitude); - latint = abs((int) wpt->latitude); - - gbfprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n"); - gbfprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname); - gbfprintf(file_out, "ADR:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint)); - - if (wpt->url) { - gbfprintf(file_out, "URL:%s\n", wpt->url); - } - - gbfprintf(file_out, "NOTE:"); - vcf_print_utf(&wpt->gc_data->desc_short); - gbfprintf(file_out, "\\n"); - vcf_print_utf(&wpt->gc_data->desc_long); - gbfprintf(file_out, "\\n\\nHINT:\\n"); - if (vcf_encrypt) { - char *s = rot13(wpt->gc_data->hint); - vcf_print(s); - xfree(s); - } else { - vcf_print(wpt->gc_data->hint); - } - - gbfprintf(file_out, "\nEND:VCARD\n"); + int latint, lonint; + + lonint = abs((int) wpt->longitude); + latint = abs((int) wpt->latitude); + + gbfprintf(file_out, "BEGIN:VCARD\nVERSION:3.0\n"); + gbfprintf(file_out, "N:%s;%s;;;\n", wpt->description,wpt->shortname); + gbfprintf(file_out, "ADR:%c%d %06.3f %c%d %06.3f\n", wpt->latitude < 0 ? 'S' : 'N', abs(latint), 60.0 * (fabs(wpt->latitude) - latint), wpt->longitude < 0 ? 'W' : 'E', abs(lonint), 60.0 * (fabs(wpt->longitude) - lonint)); + + if (wpt->url) { + gbfprintf(file_out, "URL:%s\n", wpt->url); + } + + gbfprintf(file_out, "NOTE:"); + vcf_print_utf(&wpt->gc_data->desc_short); + gbfprintf(file_out, "\\n"); + vcf_print_utf(&wpt->gc_data->desc_long); + gbfprintf(file_out, "\\n\\nHINT:\\n"); + if (vcf_encrypt) { + char *s = rot13(wpt->gc_data->hint); + vcf_print(s); + xfree(s); + } else { + vcf_print(wpt->gc_data->hint); + } + + gbfprintf(file_out, "\nEND:VCARD\n"); } static void data_write(void) { - setshort_length(mkshort_handle, 6); - waypt_disp_all(vcf_disp); + setshort_length(mkshort_handle, 6); + waypt_disp_all(vcf_disp); } ff_vecs_t vcf_vecs = { - ff_type_file, - { ff_cap_write, ff_cap_none, ff_cap_none}, - NULL, - wr_init, - NULL, - wr_deinit, - NULL, - data_write, - NULL, - vcf_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_write, ff_cap_none, ff_cap_none}, + NULL, + wr_init, + NULL, + wr_deinit, + NULL, + data_write, + NULL, + vcf_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; diff --git a/gpsbabel/vecs.c b/gpsbabel/vecs.c index 3539c695e..b7f8c4efc 100644 --- a/gpsbabel/vecs.c +++ b/gpsbabel/vecs.c @@ -1,6 +1,6 @@ /* Describe vectors containing file operations. - + Copyright (C) 2002, 2004, 2005, 2006, 2007 Robert Lipe, robertlipe@usa.net This program is free software; you can redistribute it and/or modify @@ -28,11 +28,11 @@ #define MYNAME "vecs.c" typedef struct { - ff_vecs_t *vec; - const char *name; - const char *desc; - const char *extension; - const char *parent; + ff_vecs_t *vec; + const char *name; + const char *desc; + const char *extension; + const char *parent; } vecs_t; extern ff_vecs_t an1_vecs; @@ -178,1123 +178,1153 @@ extern ff_vecs_t format_garmin_xt_vecs; static vecs_t vec_list[] = { #if CSVFMTS_ENABLED - /* XCSV must be the first entry in this table. */ - { - &xcsv_vecs, - "xcsv", - "? Character Separated Values", - NULL - }, + /* XCSV must be the first entry in this table. */ + { + &xcsv_vecs, + "xcsv", + "? Character Separated Values", + NULL + }, #endif - { - &geo_vecs, - "geo", - "Geocaching.com .loc", - "loc" - }, - { - &gpx_vecs, - "gpx", - "GPX XML", - "gpx" - }, - { - &mag_svecs, - "magellan", - "Magellan serial protocol", - NULL - }, - { - &mag_fvecs, - "magellan", - "Magellan SD files (as for Meridian)", - NULL - }, - { - &magX_fvecs, - "magellanx", - "Magellan SD files (as for eXplorist)", - "upt" - }, - { - &garmin_vecs, - "garmin", - "Garmin serial/USB protocol", - NULL - }, - { - &gdb_vecs, - "gdb", - "Garmin MapSource - gdb", - "gdb" - }, - { - >c_vecs, - "gtrnctr", - "Garmin Training Center", - "xml" - }, - { - &mapsend_vecs, - "mapsend", - "Magellan Mapsend", - NULL - }, - { - &mps_vecs, - "mapsource", - "Garmin MapSource - mps", - "mps" - }, - { - &nmea_vecs, - "nmea", - "NMEA 0183 sentences", - NULL - }, - { - &ozi_vecs, - "ozi", - "OziExplorer", - NULL - }, - { - &pcx_vecs, - "pcx", - "Garmin PCX5", - "pcx" - }, - { - &kml_vecs, - "kml", - "Google Earth (Keyhole) Markup Language", - "kml" - }, + { + &geo_vecs, + "geo", + "Geocaching.com .loc", + "loc" + }, + { + &gpx_vecs, + "gpx", + "GPX XML", + "gpx" + }, + { + &mag_svecs, + "magellan", + "Magellan serial protocol", + NULL + }, + { + &mag_fvecs, + "magellan", + "Magellan SD files (as for Meridian)", + NULL + }, + { + &magX_fvecs, + "magellanx", + "Magellan SD files (as for eXplorist)", + "upt" + }, + { + &garmin_vecs, + "garmin", + "Garmin serial/USB protocol", + NULL + }, + { + &gdb_vecs, + "gdb", + "Garmin MapSource - gdb", + "gdb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center", + "xml" + }, + { + &mapsend_vecs, + "mapsend", + "Magellan Mapsend", + NULL + }, + { + &mps_vecs, + "mapsource", + "Garmin MapSource - mps", + "mps" + }, + { + &nmea_vecs, + "nmea", + "NMEA 0183 sentences", + NULL + }, + { + &ozi_vecs, + "ozi", + "OziExplorer", + NULL + }, + { + &pcx_vecs, + "pcx", + "Garmin PCX5", + "pcx" + }, + { + &kml_vecs, + "kml", + "Google Earth (Keyhole) Markup Language", + "kml" + }, #if MAXIMAL_ENABLED - { - &gpsutil_vecs, - "gpsutil", - "gpsutil", - NULL - }, - { - &psp_vecs, - "psp", - "MS PocketStreets 2002 Pushpin", - "psp" - }, - { - &lowranceusr_vecs, - "lowranceusr", - "Lowrance USR", - "usr" - }, + { + &gpsutil_vecs, + "gpsutil", + "gpsutil", + NULL + }, + { + &psp_vecs, + "psp", + "MS PocketStreets 2002 Pushpin", + "psp" + }, + { + &lowranceusr_vecs, + "lowranceusr", + "Lowrance USR", + "usr" + }, #if PDBFMTS_ENABLED - { - &cetus_vecs, - "cetus", - "Cetus for Palm/OS", - "pdb" - }, - { - &copilot_vecs, - "copilot", - "CoPilot Flight Planner for Palm/OS", - "pdb" - }, - { - &gpspilot_vecs, - "gpspilot", - "GPSPilot Tracker for Palm/OS", - "pdb" - }, - { - &magnav_vec, - "magnav", - "Magellan NAV Companion for Palm/OS", - "pdb" - }, + { + &cetus_vecs, + "cetus", + "Cetus for Palm/OS", + "pdb" + }, + { + &copilot_vecs, + "copilot", + "CoPilot Flight Planner for Palm/OS", + "pdb" + }, + { + &gpspilot_vecs, + "gpspilot", + "GPSPilot Tracker for Palm/OS", + "pdb" + }, + { + &magnav_vec, + "magnav", + "Magellan NAV Companion for Palm/OS", + "pdb" + }, #endif /* PDBFMTS_ENABLED */ - { - &holux_vecs, - "holux", - "Holux (gm-100) .wpo Format", - "wpo" - }, - { - &tpg_vecs, - "tpg", - "National Geographic Topo .tpg (waypoints)", - "tpg" - }, - { - &tpo2_vecs, - "tpo2", - "National Geographic Topo 2.x .tpo", - "tpo" - }, - { - &tpo3_vecs, - "tpo3", - "National Geographic Topo 3.x/4.x .tpo", - "tpo" - }, - { - &tmpro_vecs, - "tmpro", - "TopoMapPro Places File", - "tmpro" - }, + { + &holux_vecs, + "holux", + "Holux (gm-100) .wpo Format", + "wpo" + }, + { + &tpg_vecs, + "tpg", + "National Geographic Topo .tpg (waypoints)", + "tpg" + }, + { + &tpo2_vecs, + "tpo2", + "National Geographic Topo 2.x .tpo", + "tpo" + }, + { + &tpo3_vecs, + "tpo3", + "National Geographic Topo 3.x/4.x .tpo", + "tpo" + }, + { + &tmpro_vecs, + "tmpro", + "TopoMapPro Places File", + "tmpro" + }, #if PDBFMTS_ENABLED - { - &gcdb_vecs, - "gcdb", - "GeocachingDB for Palm/OS", - "pdb" - }, + { + &gcdb_vecs, + "gcdb", + "GeocachingDB for Palm/OS", + "pdb" + }, #endif - { - &tiger_vecs, - "tiger", - "U.S. Census Bureau Tiger Mapping Service", - NULL - }, - { - &easygps_vecs, - "easygps", - "EasyGPS binary format", - "loc" - }, + { + &tiger_vecs, + "tiger", + "U.S. Census Bureau Tiger Mapping Service", + NULL + }, + { + &easygps_vecs, + "easygps", + "EasyGPS binary format", + "loc" + }, #if PDBFMTS_ENABLED - { - &quovadis_vecs, - "quovadis", - "Quovadis", - "pdb" - }, - { - &gpilots_vecs, - "gpilots", - "GpilotS", - "pdb" - }, + { + &quovadis_vecs, + "quovadis", + "Quovadis", + "pdb" + }, + { + &gpilots_vecs, + "gpilots", + "GpilotS", + "pdb" + }, #endif - { - &saroute_vecs, - "saroute", - "DeLorme Street Atlas Route", - "anr" - }, - { - &navicache_vecs, - "navicache", - "Navicache.com XML", - NULL - }, - { - &coastexp_vecs, - "coastexp", - "CoastalExplorer XML", - NULL - }, - { /* MRCB */ - &psit_vecs, - "psitrex", - "KuDaTa PsiTrex text", - NULL - }, + { + &saroute_vecs, + "saroute", + "DeLorme Street Atlas Route", + "anr" + }, + { + &navicache_vecs, + "navicache", + "Navicache.com XML", + NULL + }, + { + &coastexp_vecs, + "coastexp", + "CoastalExplorer XML", + NULL + }, + { /* MRCB */ + &psit_vecs, + "psitrex", + "KuDaTa PsiTrex text", + NULL + }, #if SHAPELIB_ENABLED - { - &shape_vecs, - "shape", - "ESRI shapefile", - "shp" - }, + { + &shape_vecs, + "shape", + "ESRI shapefile", + "shp" + }, #endif #if PDBFMTS_ENABLED - { - &geoniche_vecs, - "geoniche", - "GeoNiche .pdb", - "pdb" - }, + { + &geoniche_vecs, + "geoniche", + "GeoNiche .pdb", + "pdb" + }, #endif - { - &gpl_vecs, - "gpl", - "DeLorme GPL", - "gpl" - }, - { - &text_vecs, - "text", - "Textual Output", - "txt" - }, - { - &html_vecs, - "html", - "HTML Output", - "html" - }, + { + &gpl_vecs, + "gpl", + "DeLorme GPL", + "gpl" + }, + { + &text_vecs, + "text", + "Textual Output", + "txt" + }, + { + &html_vecs, + "html", + "HTML Output", + "html" + }, #if PDBFMTS_ENABLED - { - &palmdoc_vecs, - "palmdoc", - "PalmDoc Output", - "pdb" - }, + { + &palmdoc_vecs, + "palmdoc", + "PalmDoc Output", + "pdb" + }, #endif - { - &netstumbler_vecs, - "netstumbler", - "NetStumbler Summary File (text)", - NULL - }, - { - &HsaEndeavourNavigator_vecs, - "hsandv", - "HSA Endeavour Navigator export File", - NULL - }, - { - &igc_vecs, - "igc", - "FAI/IGC Flight Recorder Data Format", - NULL - }, - { - &brauniger_iq_vecs, - "baroiq", - "Brauniger IQ Series Barograph Download", - NULL - }, - { - &mtk_vecs, - "mtk", - "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", - NULL - }, - { - &mtk_fvecs, - "mtk-bin", - "MTK Logger (iBlue 747,...) Binary File Format", - "bin" - }, - { - &mtk_m241_vecs, - "m241", - "Holux M-241 (MTK based) download", - NULL - }, - { - &mtk_m241_fvecs, - "m241-bin", - "Holux M-241 (MTK based) Binary File Format", - "bin" - }, + { + &netstumbler_vecs, + "netstumbler", + "NetStumbler Summary File (text)", + NULL + }, + { + &HsaEndeavourNavigator_vecs, + "hsandv", + "HSA Endeavour Navigator export File", + NULL + }, + { + &igc_vecs, + "igc", + "FAI/IGC Flight Recorder Data Format", + NULL + }, + { + &brauniger_iq_vecs, + "baroiq", + "Brauniger IQ Series Barograph Download", + NULL + }, + { + &mtk_vecs, + "mtk", + "MTK Logger (iBlue 747,Qstarz BT-1000,...) download", + NULL + }, + { + &mtk_fvecs, + "mtk-bin", + "MTK Logger (iBlue 747,...) Binary File Format", + "bin" + }, + { + &mtk_m241_vecs, + "m241", + "Holux M-241 (MTK based) download", + NULL + }, + { + &mtk_m241_fvecs, + "m241-bin", + "Holux M-241 (MTK based) Binary File Format", + "bin" + }, #endif // MAXIMAL_ENABLED - { - &wbt_svecs, - "wbt", - "Wintec WBT-100/200 GPS Download", - NULL - }, + { + &wbt_svecs, + "wbt", + "Wintec WBT-100/200 GPS Download", + NULL + }, #if MAXIMAL_ENABLED - { - &vpl_vecs, - "vpl", - "Honda/Acura Navigation System VP Log File Format", - NULL - }, - { - &wbt_fvecs, - "wbt-bin", - "Wintec WBT-100/200 Binary File Format", - "bin" - }, - { - &wbt_fvecs, - "wbt-tk1", - "Wintec WBT-201/G-Rays 2 Binary File Format", - "tk1" - }, - { - &hiketech_vecs, - "hiketech", - "HikeTech", - "gps" - }, - { - &glogbook_vecs, - "glogbook", - "Garmin Logbook XML", - "xml" - }, - { - &vcf_vecs, - "vcard", - "Vcard Output (for iPod)", - "vcf", - }, + { + &vpl_vecs, + "vpl", + "Honda/Acura Navigation System VP Log File Format", + NULL + }, + { + &wbt_fvecs, + "wbt-bin", + "Wintec WBT-100/200 Binary File Format", + "bin" + }, + { + &wbt_fvecs, + "wbt-tk1", + "Wintec WBT-201/G-Rays 2 Binary File Format", + "tk1" + }, + { + &hiketech_vecs, + "hiketech", + "HikeTech", + "gps" + }, + { + &glogbook_vecs, + "glogbook", + "Garmin Logbook XML", + "xml" + }, + { + &vcf_vecs, + "vcard", + "Vcard Output (for iPod)", + "vcf", + }, #if 0 - { - &overlay_vecs, - "overlay", - "Geogrid-Viewer", - "ovl" - }, + { + &overlay_vecs, + "overlay", + "Geogrid-Viewer", + "ovl" + }, #endif - { - &google_vecs, - "google", - "Google Maps XML", - "xml" - }, - { - &maggeo_vecs, - "maggeo", - "Magellan Explorist Geocaching", - "gs" - }, - { - &an1_vecs, - "an1", - "DeLorme .an1 (drawing) file", - "an1" - }, - { - &tomtom_vecs, - "tomtom", - "TomTom POI file (.ov2)", - "ov2" - }, - { - &tef_xml_vecs, - "tef", - "Map&Guide 'TourExchangeFormat' XML", - "xml" - }, + { + &google_vecs, + "google", + "Google Maps XML", + "xml" + }, + { + &maggeo_vecs, + "maggeo", + "Magellan Explorist Geocaching", + "gs" + }, + { + &an1_vecs, + "an1", + "DeLorme .an1 (drawing) file", + "an1" + }, + { + &tomtom_vecs, + "tomtom", + "TomTom POI file (.ov2)", + "ov2" + }, + { + &tef_xml_vecs, + "tef", + "Map&Guide 'TourExchangeFormat' XML", + "xml" + }, #if PDBFMTS_ENABLED - { - &ppdb_vecs, - "pathaway", - "PathAway Database for Palm/OS", - "pdb" - }, + { + &ppdb_vecs, + "pathaway", + "PathAway Database for Palm/OS", + "pdb" + }, #endif - { - &vitosmt_vecs, - "vitosmt", - "Vito Navigator II tracks", - "smt" - }, - { - &wfff_xml_vecs, - "wfff", - "WiFiFoFum 2.0 for PocketPC XML", - "xml" - }, - { - &bcr_vecs, - "bcr", - "Motorrad Routenplaner (Map&Guide) .bcr files", - "bcr" - }, + { + &vitosmt_vecs, + "vitosmt", + "Vito Navigator II tracks", + "smt" + }, + { + &wfff_xml_vecs, + "wfff", + "WiFiFoFum 2.0 for PocketPC XML", + "xml" + }, + { + &bcr_vecs, + "bcr", + "Motorrad Routenplaner (Map&Guide) .bcr files", + "bcr" + }, #if PDBFMTS_ENABLED - { - &coto_vecs, - "coto", - "cotoGPS for Palm/OS", - "pdb" - }, + { + &coto_vecs, + "coto", + "cotoGPS for Palm/OS", + "pdb" + }, #endif - { - &ignr_vecs, - "ignrando", - "IGN Rando track files", - "rdn" - }, + { + &ignr_vecs, + "ignrando", + "IGN Rando track files", + "rdn" + }, #if CSVFMTS_ENABLED - { - &stmsdf_vecs, - "stmsdf", - "Suunto Trek Manager (STM) .sdf files", - "sdf" - }, + { + &stmsdf_vecs, + "stmsdf", + "Suunto Trek Manager (STM) .sdf files", + "sdf" + }, #endif #if CSVFMTS_ENABLED - { - &stmwpp_vecs, - "stmwpp", - "Suunto Trek Manager (STM) WaypointPlus files", - "txt" - }, + { + &stmwpp_vecs, + "stmwpp", + "Suunto Trek Manager (STM) WaypointPlus files", + "txt" + }, #endif // CSVFMTS_ENABLED - { - &msroute_vecs, - "msroute", - "Microsoft AutoRoute 2002 (pin/route reader)", - "axe" - }, - { - &msroute_vecs, - "msroute", - "Microsoft Streets and Trips (pin/route reader)" , - "est" - }, - { - &cst_vecs, - "cst", - "CarteSurTable data file", - "cst" - }, - { - &nmn4_vecs, - "nmn4", - "Navigon Mobile Navigator .rte files", - "rte" - }, + { + &msroute_vecs, + "msroute", + "Microsoft AutoRoute 2002 (pin/route reader)", + "axe" + }, + { + &msroute_vecs, + "msroute", + "Microsoft Streets and Trips (pin/route reader)" , + "est" + }, + { + &cst_vecs, + "cst", + "CarteSurTable data file", + "cst" + }, + { + &nmn4_vecs, + "nmn4", + "Navigon Mobile Navigator .rte files", + "rte" + }, #if PDBFMTS_ENABLED - { - &magpdb_vecs, - "mag_pdb", - "Map&Guide to Palm/OS exported files (.pdb)", - "pdb" - }, + { + &magpdb_vecs, + "mag_pdb", + "Map&Guide to Palm/OS exported files (.pdb)", + "pdb" + }, #endif #if CSVFMTS_ENABLED - { - &compegps_vecs, - "compegps", - "CompeGPS data files (.wpt/.trk/.rte)", - NULL - }, + { + &compegps_vecs, + "compegps", + "CompeGPS data files (.wpt/.trk/.rte)", + NULL + }, #endif //CSVFMTS_ENABLED - { - &yahoo_vecs, - "yahoo", - "Yahoo Geocode API data", - NULL - }, - { - &unicsv_vecs, - "unicsv", - "Universal csv with field structure in first line", - NULL - }, - { - >m_vecs, - "gtm", - "GPS TrackMaker", - "gtm" - }, - { - &gpssim_vecs, - "gpssim", - "Franson GPSGate Simulation", - "gpssim" - }, + { + &yahoo_vecs, + "yahoo", + "Yahoo Geocode API data", + NULL + }, + { + &unicsv_vecs, + "unicsv", + "Universal csv with field structure in first line", + NULL + }, + { + >m_vecs, + "gtm", + "GPS TrackMaker", + "gtm" + }, + { + &gpssim_vecs, + "gpssim", + "Franson GPSGate Simulation", + "gpssim" + }, #if CSVFMTS_ENABLED - { - &garmin_txt_vecs, - "garmin_txt", - "Garmin MapSource - txt (tab delimited)", - "txt" - }, + { + &garmin_txt_vecs, + "garmin_txt", + "Garmin MapSource - txt (tab delimited)", + "txt" + }, #endif // CSVFMTS_ENABLED - { - &axim_gpb_vecs, - "axim_gpb", - "Dell Axim Navigation System (.gpb) file format", - "gpb" - }, - { - >c_vecs, - "gtrnctr", - "Garmin Training Center (.tcx)", - "xml" - }, - { - &dmtlog_vecs, - "dmtlog", - "TrackLogs digital mapping (.trl)", - "trl" - }, - { - &raymarine_vecs, - "raymarine", - "Raymarine Waypoint File (.rwf)", - "rwf" - }, - { - &alanwpr_vecs, - "alanwpr", - "Alan Map500 waypoints and routes (.wpr)", - "wpr" - }, - { - &alantrl_vecs, - "alantrl", - "Alan Map500 tracklogs (.trl)", - "trl" - }, - { - &vitovtt_vecs, - "vitovtt", - "Vito SmartMap tracks (.vtt)", - "vtt" - }, - { - &ggv_log_vecs, - "ggv_log", - "Geogrid-Viewer tracklogs (.log)", - "log" - }, + { + &axim_gpb_vecs, + "axim_gpb", + "Dell Axim Navigation System (.gpb) file format", + "gpb" + }, + { + >c_vecs, + "gtrnctr", + "Garmin Training Center (.tcx)", + "xml" + }, + { + &dmtlog_vecs, + "dmtlog", + "TrackLogs digital mapping (.trl)", + "trl" + }, + { + &raymarine_vecs, + "raymarine", + "Raymarine Waypoint File (.rwf)", + "rwf" + }, + { + &alanwpr_vecs, + "alanwpr", + "Alan Map500 waypoints and routes (.wpr)", + "wpr" + }, + { + &alantrl_vecs, + "alantrl", + "Alan Map500 tracklogs (.trl)", + "trl" + }, + { + &vitovtt_vecs, + "vitovtt", + "Vito SmartMap tracks (.vtt)", + "vtt" + }, + { + &ggv_log_vecs, + "ggv_log", + "Geogrid-Viewer tracklogs (.log)", + "log" + }, #if CSVFMTS_ENABLED - { - &g7towin_vecs, - "g7towin", - "G7ToWin data files (.g7t)", - "g7t" - }, + { + &g7towin_vecs, + "g7towin", + "G7ToWin data files (.g7t)", + "g7t" + }, #endif - { - &garmin_gpi_vecs, - "garmin_gpi", - "Garmin Points of Interest (.gpi)", - "gpi" - }, - { - &lmx_vecs, - "lmx", - "Nokia Landmark Exchange", - NULL - }, - { - &random_vecs, - "random", - "Internal GPS data generator", - NULL - }, - { - &xol_vecs, - "xol", - "Swiss Map 25/50/100 (.xol)", - "xol" - }, - { - &dg100_vecs, - "dg-100", - "GlobalSat DG-100/BT-335 Download", - NULL - }, - { - &navilink_vecs, - "navilink", - "NaviGPS GT-11/BGT-11 Download", - NULL - }, - { - &ik3d_vecs, - "ik3d", - "MagicMaps IK3D project file (.ikt)", - "ikt" - }, - { - &osm_vecs, - "osm", - "OpenStreetMap data files", - "osm" - }, - { - &destinator_poi_vecs, - "destinator_poi", - "Destinator Points of Interest (.dat)", - "dat" - }, - { - &destinator_itn_vecs, - "destinator_itn", - "Destinator Itineraries (.dat)", - "dat" - }, - { - &destinator_trl_vecs, - "destinator_trl", - "Destinator TrackLogs (.dat)", - "dat" - }, - { - &exif_vecs, - "exif", - "Embedded Exif-GPS data (.jpg)", - "jpg" - }, - { - &vidaone_vecs, - "vidaone", - "VidaOne GPS for Pocket PC (.gpb)", - "gpb" - }, - { - &igo8_vecs, - "igo8", - "IGO8 .trk", - "trk" - }, - { - &gopal_vecs, - "gopal", - "GoPal GPS track log (.trk)", - "trk" - }, - { - &humminbird_vecs, - "humminbird", - "Humminbird waypoints and routes (.hwr)", - "hwr" - }, - { - &humminbird_ht_vecs, - "humminbird_ht", - "Humminbird tracks (.ht)", - "ht" - }, - { - &mapasia_tr7_vecs, - "mapasia_tr7", - "MapAsia track file (.tr7)", - "tr7" - }, - { - &gnav_trl_vecs, - "gnav_trl", - "Google Navigator Tracklines (.trl)", - "trl" - }, - { - &navitel_trk_vecs, - "navitel_trk", - "Navitel binary track (.bin)", - "bin" - }, - { - &ggv_ovl_vecs, - "ggv_ovl", - "Geogrid-Viewer ascii overlay file (.ovl)", - "ovl" - }, + { + &garmin_gpi_vecs, + "garmin_gpi", + "Garmin Points of Interest (.gpi)", + "gpi" + }, + { + &lmx_vecs, + "lmx", + "Nokia Landmark Exchange", + NULL + }, + { + &random_vecs, + "random", + "Internal GPS data generator", + NULL + }, + { + &xol_vecs, + "xol", + "Swiss Map 25/50/100 (.xol)", + "xol" + }, + { + &dg100_vecs, + "dg-100", + "GlobalSat DG-100/BT-335 Download", + NULL + }, + { + &navilink_vecs, + "navilink", + "NaviGPS GT-11/BGT-11 Download", + NULL + }, + { + &ik3d_vecs, + "ik3d", + "MagicMaps IK3D project file (.ikt)", + "ikt" + }, + { + &osm_vecs, + "osm", + "OpenStreetMap data files", + "osm" + }, + { + &destinator_poi_vecs, + "destinator_poi", + "Destinator Points of Interest (.dat)", + "dat" + }, + { + &destinator_itn_vecs, + "destinator_itn", + "Destinator Itineraries (.dat)", + "dat" + }, + { + &destinator_trl_vecs, + "destinator_trl", + "Destinator TrackLogs (.dat)", + "dat" + }, + { + &exif_vecs, + "exif", + "Embedded Exif-GPS data (.jpg)", + "jpg" + }, + { + &vidaone_vecs, + "vidaone", + "VidaOne GPS for Pocket PC (.gpb)", + "gpb" + }, + { + &igo8_vecs, + "igo8", + "IGO8 .trk", + "trk" + }, + { + &gopal_vecs, + "gopal", + "GoPal GPS track log (.trk)", + "trk" + }, + { + &humminbird_vecs, + "humminbird", + "Humminbird waypoints and routes (.hwr)", + "hwr" + }, + { + &humminbird_ht_vecs, + "humminbird_ht", + "Humminbird tracks (.ht)", + "ht" + }, + { + &mapasia_tr7_vecs, + "mapasia_tr7", + "MapAsia track file (.tr7)", + "tr7" + }, + { + &gnav_trl_vecs, + "gnav_trl", + "Google Navigator Tracklines (.trl)", + "trl" + }, + { + &navitel_trk_vecs, + "navitel_trk", + "Navitel binary track (.bin)", + "bin" + }, + { + &ggv_ovl_vecs, + "ggv_ovl", + "Geogrid-Viewer ascii overlay file (.ovl)", + "ovl" + }, #if CSVFMTS_ENABLED - { - &jtr_vecs, - "jtr", - "Jelbert GeoTagger data file", - "jtr" - }, + { + &jtr_vecs, + "jtr", + "Jelbert GeoTagger data file", + "jtr" + }, #endif - { - &itracku_vecs, - "itracku", - "XAiOX iTrackU Logger", - NULL - }, - - { - &itracku_fvecs, - "itracku-bin", - "XAiOX iTrackU Logger Binary File Format", - "bin" - }, - { - &sbp_vecs, - "sbp", - "NaviGPS GT-31/BGT-31 datalogger (.sbp)", - "sbp" - }, - { - &sbn_vecs, - "sbn", - "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)", - "sbn" - }, - { - &mmo_vecs, - "mmo", - "Memory-Map Navigator overlay files (.mmo)", - "mmo" - }, - { - &bushnell_vecs, - "bushnell", - "Bushnell GPS Waypoint file", - "wpt" - }, - { - &bushnell_trl_vecs, - "bushnell_trl", - "Bushnell GPS Trail file", - "trl" - }, - { - &skyforce_vecs, - "skyforce", - "Skymap / KMD150 ascii files", - NULL - }, - { - &pocketfms_bc_vecs, - "pocketfms_bc", - "PocketFMS breadcrumbs", - NULL - }, - { - &pocketfms_fp_vecs, - "pocketfms_fp", - "PocketFMS flightplan (.xml)", - "xml" - }, - { - &pocketfms_wp_vecs, - "pocketfms_wp", - "PocketFMS waypoints (.txt)", - "txt" - }, - { - &v900_vecs, - "v900", - "Columbus/Visiontac V900 files (.csv)", - NULL - }, - { - &ng_vecs, - "naviguide", - "Naviguide binary route file (.twl)", - "twl" - }, - { - &enigma_vecs, - "enigma", - "Enigma binary waypoint file (.ert)", - "ert" - }, - { - &delbin_vecs, - "delbin", - "DeLorme PN-20/PN-30/PN-40 USB protocol", - NULL - }, - { - &skytraq_vecs, - "skytraq", - "SkyTraq Venus based loggers (download)", - NULL - }, - { - &teletype_vecs, - "teletype", - "Teletype [ Get Jonathon Johnson to describe", - NULL - }, - { - &skytraq_fvecs, - "skytraq-bin", - "SkyTraq Venus based loggers Binary File Format", - "bin" - }, - { - &miniHomer_vecs, - "miniHomer", - "MiniHomer, a skyTraq Venus 6 based logger (download tracks, waypoints and get/set POI)", - NULL - }, - { - &jogmap_vecs, - "jogmap", - "Jogmap.de XML format", - "xml" - }, - { - &wintec_tes_vecs, - "wintec_tes", - "Wintec TES file", - "tes" - }, - { - &subrip_vecs, - "subrip", - "SubRip subtitles for video mapping (.srt)", - "srt" - }, - { - &format_garmin_xt_vecs, - "garmin_xt", - "Mobile Garmin XT Track files", - NULL - }, + { + &itracku_vecs, + "itracku", + "XAiOX iTrackU Logger", + NULL + }, + + { + &itracku_fvecs, + "itracku-bin", + "XAiOX iTrackU Logger Binary File Format", + "bin" + }, + { + &sbp_vecs, + "sbp", + "NaviGPS GT-31/BGT-31 datalogger (.sbp)", + "sbp" + }, + { + &sbn_vecs, + "sbn", + "NaviGPS GT-31/BGT-31 SiRF binary logfile (.sbn)", + "sbn" + }, + { + &mmo_vecs, + "mmo", + "Memory-Map Navigator overlay files (.mmo)", + "mmo" + }, + { + &bushnell_vecs, + "bushnell", + "Bushnell GPS Waypoint file", + "wpt" + }, + { + &bushnell_trl_vecs, + "bushnell_trl", + "Bushnell GPS Trail file", + "trl" + }, + { + &skyforce_vecs, + "skyforce", + "Skymap / KMD150 ascii files", + NULL + }, + { + &pocketfms_bc_vecs, + "pocketfms_bc", + "PocketFMS breadcrumbs", + NULL + }, + { + &pocketfms_fp_vecs, + "pocketfms_fp", + "PocketFMS flightplan (.xml)", + "xml" + }, + { + &pocketfms_wp_vecs, + "pocketfms_wp", + "PocketFMS waypoints (.txt)", + "txt" + }, + { + &v900_vecs, + "v900", + "Columbus/Visiontac V900 files (.csv)", + NULL + }, + { + &ng_vecs, + "naviguide", + "Naviguide binary route file (.twl)", + "twl" + }, + { + &enigma_vecs, + "enigma", + "Enigma binary waypoint file (.ert)", + "ert" + }, + { + &delbin_vecs, + "delbin", + "DeLorme PN-20/PN-30/PN-40 USB protocol", + NULL + }, + { + &skytraq_vecs, + "skytraq", + "SkyTraq Venus based loggers (download)", + NULL + }, + { + &teletype_vecs, + "teletype", + "Teletype [ Get Jonathon Johnson to describe", + NULL + }, + { + &skytraq_fvecs, + "skytraq-bin", + "SkyTraq Venus based loggers Binary File Format", + "bin" + }, + { + &miniHomer_vecs, + "miniHomer", + "MiniHomer, a skyTraq Venus 6 based logger (download tracks, waypoints and get/set POI)", + NULL + }, + { + &jogmap_vecs, + "jogmap", + "Jogmap.de XML format", + "xml" + }, + { + &wintec_tes_vecs, + "wintec_tes", + "Wintec TES file", + "tes" + }, + { + &subrip_vecs, + "subrip", + "SubRip subtitles for video mapping (.srt)", + "srt" + }, + { + &format_garmin_xt_vecs, + "garmin_xt", + "Mobile Garmin XT Track files", + NULL + }, #endif // MAXIMAL_ENABLED - { - NULL, - NULL, - NULL, - NULL - } + { + NULL, + NULL, + NULL, + NULL + } }; void init_vecs(void) { - vecs_t *vec = vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - ap->argvalptr = NULL; - if (ap->argval) *ap->argval = NULL; - } - } - vec++; - } + vecs_t *vec = vec_list; + while (vec->vec) { + arglist_t *ap; + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + ap->argvalptr = NULL; + if (ap->argval) { + *ap->argval = NULL; + } + } + } + vec++; + } } int is_integer(const char *c) { - return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1])); + return isdigit(c[0]) || ((c[0] == '+' || c[0] == '-') && isdigit(c[1])); } -void -exit_vecs( void ) +void +exit_vecs(void) { - vecs_t *vec = vec_list; - while ( vec->vec ) { - arglist_t *ap; - if ( vec->vec->exit ) { - (*vec->vec->exit)(); - } - if ( vec->vec->args ) { - for ( ap = vec->vec->args; ap->argstring; ap++ ) { - if ( ap->defaultvalue && - ( ap->argtype == ARGTYPE_INT ) && - ! is_integer(ap->defaultvalue)) { - warning("%s: not an integer\n", ap->argstring); - } - if ( ap->argvalptr ) { - xfree(ap->argvalptr); - *ap->argval = ap->argvalptr = NULL; - } - } - } - vec++; - } + vecs_t *vec = vec_list; + while (vec->vec) { + arglist_t *ap; + if (vec->vec->exit) { + (*vec->vec->exit)(); + } + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + if (ap->defaultvalue && + (ap->argtype == ARGTYPE_INT) && + ! is_integer(ap->defaultvalue)) { + warning("%s: not an integer\n", ap->argstring); + } + if (ap->argvalptr) { + xfree(ap->argvalptr); + *ap->argval = ap->argvalptr = NULL; + } + } + } + vec++; + } } void assign_option(const char *module, arglist_t *ap, const char *val) { - char *c; - - if (ap->argval == NULL) - fatal("%s: No local variable defined for option \"%s\"!", module, ap->argstring); - - if (ap->argvalptr != NULL) { - xfree(ap->argvalptr); - ap->argvalptr = NULL; - } - if (ap->argval) *ap->argval = NULL; - - if (val == NULL) return; - - if (case_ignore_strcmp(val, ap->argstring) == 0) c = ""; - else c = (char *)val; - - switch(ap->argtype & ARGTYPE_TYPEMASK) { - case ARGTYPE_INT: - if (*c == '\0') c = "0"; - else { - int test; - is_fatal(1 != sscanf(c, "%d", &test), - "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); - } - break; - case ARGTYPE_FLOAT: - if (*c == '\0') c = "0"; - else { - double test; - is_fatal(1 != sscanf(c, "%lf", &test), - "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); - } - break; - case ARGTYPE_BOOL: - if (*c == '\0') c = "1"; - else { - switch(*c) { - case 'Y': - case 'y': c = "1"; break; - case 'N': - case 'n': c = "0"; break; - default: - if (isdigit(*c)) { - if (*c == '0') c = "0"; - else c = "1"; - } - else { - warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); - c = "0"; - } - break; - } - } - break; - } - - /* for bool options without default: don't set argval if "FALSE" */ - - if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && - (*c == '0') && (ap->defaultvalue == NULL)) { - return; - } - *ap->argval = ap->argvalptr = xstrdup(c); + char *c; + + if (ap->argval == NULL) { + fatal("%s: No local variable defined for option \"%s\"!", module, ap->argstring); + } + + if (ap->argvalptr != NULL) { + xfree(ap->argvalptr); + ap->argvalptr = NULL; + } + if (ap->argval) { + *ap->argval = NULL; + } + + if (val == NULL) { + return; + } + + if (case_ignore_strcmp(val, ap->argstring) == 0) { + c = ""; + } else { + c = (char *)val; + } + + switch (ap->argtype & ARGTYPE_TYPEMASK) { + case ARGTYPE_INT: + if (*c == '\0') { + c = "0"; + } else { + int test; + is_fatal(1 != sscanf(c, "%d", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_FLOAT: + if (*c == '\0') { + c = "0"; + } else { + double test; + is_fatal(1 != sscanf(c, "%lf", &test), + "%s: Invalid parameter value %s for option %s", module, val, ap->argstring); + } + break; + case ARGTYPE_BOOL: + if (*c == '\0') { + c = "1"; + } else { + switch (*c) { + case 'Y': + case 'y': + c = "1"; + break; + case 'N': + case 'n': + c = "0"; + break; + default: + if (isdigit(*c)) { + if (*c == '0') { + c = "0"; + } else { + c = "1"; + } + } else { + warning(MYNAME ": Invalid logical value '%s' (%s)!\n", c, module); + c = "0"; + } + break; + } + } + break; + } + + /* for bool options without default: don't set argval if "FALSE" */ + + if (((ap->argtype & ARGTYPE_TYPEMASK) == ARGTYPE_BOOL) && + (*c == '0') && (ap->defaultvalue == NULL)) { + return; + } + *ap->argval = ap->argvalptr = xstrdup(c); } void disp_vec_options(const char *vecname, arglist_t *ap) { - for (ap = ap; ap && ap->argstring; ap++) { - if (*ap->argval && ap->argval) { - printf("options: module/option=value: %s/%s=\"%s\"", - vecname, ap->argstring, *ap->argval); - if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) - printf(" (=default)"); - printf("\n"); - } - } + for (ap = ap; ap && ap->argstring; ap++) { + if (*ap->argval && ap->argval) { + printf("options: module/option=value: %s/%s=\"%s\"", + vecname, ap->argstring, *ap->argval); + if (ap->defaultvalue && (case_ignore_strcmp(ap->defaultvalue, *ap->argval) == 0)) { + printf(" (=default)"); + } + printf("\n"); + } + } } ff_vecs_t * find_vec(char *const vecname, char **opts) { - vecs_t *vec = vec_list; - style_vecs_t *svec = style_list; - char *v = xstrdup(vecname); - char *svecname = strtok(v, ","); - int found = 0; - - if (vecname == NULL) { - fatal("A format name is required.\n"); - } - - while (vec->vec) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, vec->name)) { - vec++; - continue; - } - - res = strchr(vecname, ','); - if (res) { - *opts = strchr(vecname, ',')+1; - } else { - *opts = NULL; - } - - if (vec->vec->args) { - for (ap = vec->vec->args; ap->argstring; ap++) { - const char *opt; - - if ( res ) { - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(svecname, ap, opt); - xfree((char *)opt); - continue; - } - } - opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); - if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); - if (opt == NULL) opt = ap->defaultvalue; - assign_option(vec->name, ap, opt); - } - } - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, vec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(vec->name, vec->vec->args); - -#if CSVFMTS_ENABLED - // xcsv_setup_internal_style( NULL ); + vecs_t *vec = vec_list; + style_vecs_t *svec = style_list; + char *v = xstrdup(vecname); + char *svecname = strtok(v, ","); + int found = 0; + + if (vecname == NULL) { + fatal("A format name is required.\n"); + } + + while (vec->vec) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, vec->name)) { + vec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',')+1; + } else { + *opts = NULL; + } + + if (vec->vec->args) { + for (ap = vec->vec->args; ap->argstring; ap++) { + const char *opt; + + if (res) { + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(svecname, ap, opt); + xfree((char *)opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, vec->name, ap->argstring); + if (opt == NULL) { + opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + } + if (opt == NULL) { + opt = ap->defaultvalue; + } + assign_option(vec->name, ap, opt); + } + } + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, vec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(vec->name, vec->vec->args); + } + +#if CSVFMTS_ENABLED + // xcsv_setup_internal_style( NULL ); #endif // CSVFMTS_ENABLED - xfree(v); - vec->vec->name = vec->name; /* needed for session information */ - return vec->vec; - - } - - /* - * Didn't find it in the table of "real" file types, so plan B - * is to search the list of xcsv styles. - */ - while (svec->name) { - arglist_t *ap; - char *res; - - if (case_ignore_strcmp(svecname, svec->name)) { - svec++; - continue; - } - - res = strchr(vecname, ','); - if (res) { - *opts = strchr(vecname, ',') + 1; - } else { - *opts = NULL; - } - - if (vec_list[0].vec->args) { - for (ap = vec_list[0].vec->args; ap->argstring; ap++) { - const char *opt; - - if ( res ) { - opt = get_option(*opts, ap->argstring); - if ( opt ) { - found = 1; - assign_option(svecname, ap, opt); - xfree((char *)opt); - continue; - } - } - opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); - if (opt == NULL) opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); - if (opt == NULL) opt = ap->defaultvalue; - assign_option(svec->name, ap, opt); - } - } - - if (opts && opts[0] && !found) { - warning("'%s' is an unknown option to %s.\n", *opts, svec->name); - } - - if (global_opts.debug_level >= 1) - disp_vec_options(svec->name, vec_list[0].vec->args); + xfree(v); + vec->vec->name = vec->name; /* needed for session information */ + return vec->vec; + + } + + /* + * Didn't find it in the table of "real" file types, so plan B + * is to search the list of xcsv styles. + */ + while (svec->name) { + arglist_t *ap; + char *res; + + if (case_ignore_strcmp(svecname, svec->name)) { + svec++; + continue; + } + + res = strchr(vecname, ','); + if (res) { + *opts = strchr(vecname, ',') + 1; + } else { + *opts = NULL; + } + + if (vec_list[0].vec->args) { + for (ap = vec_list[0].vec->args; ap->argstring; ap++) { + const char *opt; + + if (res) { + opt = get_option(*opts, ap->argstring); + if (opt) { + found = 1; + assign_option(svecname, ap, opt); + xfree((char *)opt); + continue; + } + } + opt = inifile_readstr(global_opts.inifile, svec->name, ap->argstring); + if (opt == NULL) { + opt = inifile_readstr(global_opts.inifile, "Common format settings", ap->argstring); + } + if (opt == NULL) { + opt = ap->defaultvalue; + } + assign_option(svec->name, ap, opt); + } + } + + if (opts && opts[0] && !found) { + warning("'%s' is an unknown option to %s.\n", *opts, svec->name); + } + + if (global_opts.debug_level >= 1) { + disp_vec_options(svec->name, vec_list[0].vec->args); + } #if CSVFMTS_ENABLED - xcsv_setup_internal_style(svec->style_buf); + xcsv_setup_internal_style(svec->style_buf); #endif // CSVFMTS_ENABLED - xfree(v); - vec_list[0].vec->name = svec->name; /* needed for session information */ - return vec_list[0].vec; - } - - /* - * Not found. - */ - xfree(v); - return NULL; + xfree(v); + vec_list[0].vec->name = svec->name; /* needed for session information */ + return vec_list[0].vec; + } + + /* + * Not found. + */ + xfree(v); + return NULL; } /* @@ -1308,60 +1338,59 @@ GET_OPTION(const char *iarglist, const char *argname, DEBUG_PARAMS) get_option(const char *iarglist, const char *argname) #endif { - size_t arglen = strlen(argname); - char *arglist; - char *rval = NULL; - char *arg; - char *argp; - - if (!iarglist) { - return NULL; - } - - arglen = strlen(argname); - arglist = xstrdup(iarglist); - - for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { - if (0 == case_ignore_strncmp(argp, argname, arglen)) { - /* - * If we have something of the form "foo=bar" - * return "bar". Otherwise, we assume we have - * simply "foo" so we return that. - */ - if (argp[arglen] == '=') { - rval = argp + arglen + 1; - break; - } - else if (argp[arglen] == '\0') { - rval = argp; - break; - } - } - } - /* - * Return an offset into the allocated copy. - * The caller mustn't free or otherwise get froggy with - * this data. - */ - if ( rval ) { - rval = xxstrdup(rval,file, line); - } - xfree(arglist); - return rval; + size_t arglen = strlen(argname); + char *arglist; + char *rval = NULL; + char *arg; + char *argp; + + if (!iarglist) { + return NULL; + } + + arglen = strlen(argname); + arglist = xstrdup(iarglist); + + for (arg = arglist; argp = strtok(arg, ","), NULL != argp; arg = NULL) { + if (0 == case_ignore_strncmp(argp, argname, arglen)) { + /* + * If we have something of the form "foo=bar" + * return "bar". Otherwise, we assume we have + * simply "foo" so we return that. + */ + if (argp[arglen] == '=') { + rval = argp + arglen + 1; + break; + } else if (argp[arglen] == '\0') { + rval = argp; + break; + } + } + } + /* + * Return an offset into the allocated copy. + * The caller mustn't free or otherwise get froggy with + * this data. + */ + if (rval) { + rval = xxstrdup(rval,file, line); + } + xfree(arglist); + return rval; } /* * Display the available formats in a format that's easy for humans to * parse for help on available command line options. */ -static signed int -alpha (const void *a, const void *b) +static signed int +alpha(const void *a, const void *b) { - const vecs_t *const *ap = (const vecs_t *const*) a; - const vecs_t *const *bp = (const vecs_t *const*) b; - - return case_ignore_strcmp((*ap)->desc , (*bp)->desc); + const vecs_t *const *ap = (const vecs_t *const*) a; + const vecs_t *const *bp = (const vecs_t *const*) b; + + return case_ignore_strcmp((*ap)->desc , (*bp)->desc); } /* @@ -1372,75 +1401,79 @@ alpha (const void *a, const void *b) vecs_t ** sort_and_unify_vecs(int *ctp) { - int vc; - vecs_t **svp; - vecs_t *vec; + int vc; + vecs_t **svp; + vecs_t *vec; #if CSVFMTS_ENABLED - style_vecs_t *svec; + style_vecs_t *svec; #endif - int i = 0; + int i = 0; - /* Get a count from both the vec (normal) and the svec (csv) lists */ + /* Get a count from both the vec (normal) and the svec (csv) lists */ #if CSVFMTS_ENABLED - extern size_t nstyles; - vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; + extern size_t nstyles; + vc = sizeof vec_list / sizeof vec_list[0] - 1 + nstyles; #else - vc = sizeof vec_list / sizeof vec_list[0] - 1; + vc = sizeof vec_list / sizeof vec_list[0] - 1; #endif // CSVFMTS_ENABLED - svp = (vecs_t **)xcalloc(vc, sizeof(style_vecs_t *)); - /* Normal vecs are easy; populate the first part of the array. */ - for (vec = vec_list; vec->vec; vec++, i++) { - svp[i] = vec; - if (svp[i]->parent == NULL) { - svp[i]->parent = svp[i]->name; - } - } + svp = (vecs_t **)xcalloc(vc, sizeof(style_vecs_t *)); + /* Normal vecs are easy; populate the first part of the array. */ + for (vec = vec_list; vec->vec; vec++, i++) { + svp[i] = vec; + if (svp[i]->parent == NULL) { + svp[i]->parent = svp[i]->name; + } + } #if CSVFMTS_ENABLED - /* Walk the style list, parse the entries, dummy up a "normal" vec */ - for (svec = style_list; svec->name; svec++, i++) { - xcsv_read_internal_style(svec->style_buf); - svp[i] = (vecs_t*) xcalloc(1, sizeof **svp); - svp[i]->name = svec->name; - svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec)); - svp[i]->extension = xcsv_file.extension; - *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */ - /* Reset file type to inherit ff_type from xcsv for everything - * except the xcsv format itself, which we leave as "internal" - */ - if (case_ignore_strcmp(svec->name, "xcsv")) { - svp[i]->vec->type = xcsv_file.type; - /* Skip over the first help entry for all but the - * actual 'xcsv' format - so we don't expose the - * 'full path to xcsv style file' argument to any - * GUIs for an internal format. - */ - svp[i]->vec->args++; - } - memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); - switch(xcsv_file.datatype) { - case 0: - case wptdata: - svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap) (ff_cap_read | ff_cap_write); break; - case trkdata: - svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap) (ff_cap_read | ff_cap_write); break; - case rtedata: - svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); break; - default: ; - } - svp[i]->desc = xcsv_file.description; - svp[i]->parent = "xcsv"; - } + /* Walk the style list, parse the entries, dummy up a "normal" vec */ + for (svec = style_list; svec->name; svec++, i++) { + xcsv_read_internal_style(svec->style_buf); + svp[i] = (vecs_t*) xcalloc(1, sizeof **svp); + svp[i]->name = svec->name; + svp[i]->vec = (ff_vecs_t*) xmalloc(sizeof(*svp[i]->vec)); + svp[i]->extension = xcsv_file.extension; + *svp[i]->vec = *vec_list[0].vec; /* Interits xcsv opts */ + /* Reset file type to inherit ff_type from xcsv for everything + * except the xcsv format itself, which we leave as "internal" + */ + if (case_ignore_strcmp(svec->name, "xcsv")) { + svp[i]->vec->type = xcsv_file.type; + /* Skip over the first help entry for all but the + * actual 'xcsv' format - so we don't expose the + * 'full path to xcsv style file' argument to any + * GUIs for an internal format. + */ + svp[i]->vec->args++; + } + memset(&svp[i]->vec->cap, 0, sizeof(svp[i]->vec->cap)); + switch (xcsv_file.datatype) { + case 0: + case wptdata: + svp[i]->vec->cap[ff_cap_rw_wpt] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + case trkdata: + svp[i]->vec->cap[ff_cap_rw_trk] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + case rtedata: + svp[i]->vec->cap[ff_cap_rw_rte] = (ff_cap)(ff_cap_read | ff_cap_write); + break; + default: + ; + } + svp[i]->desc = xcsv_file.description; + svp[i]->parent = "xcsv"; + } #endif // CSVFMTS_ENABLED - /* Now that we have everything in an array, alphabetize them */ - qsort(svp, vc, sizeof(*svp), alpha); + /* Now that we have everything in an array, alphabetize them */ + qsort(svp, vc, sizeof(*svp), alpha); - *ctp = i; - return svp; + *ctp = i; + return svp; } #define VEC_FMT " %-20.20s %-.50s\n" @@ -1448,57 +1481,57 @@ sort_and_unify_vecs(int *ctp) void disp_vecs(void) { - vecs_t **svp; - arglist_t *ap; - int vc; - int i = 0; - - svp = sort_and_unify_vecs(&vc); - for (i=0;ivec->type == ff_type_internal ) { - continue; - } - printf(VEC_FMT, svp[i]->name, svp[i]->desc); - for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) - printf(" %-18.18s %s%-.50s %s\n", - ap->argstring, - (ap->argtype & ARGTYPE_TYPEMASK) == - ARGTYPE_BOOL ? "(0/1) " : "", - ap->helpstring, - (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); - } - } - xfree (svp); - return; + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0; ivec->type == ff_type_internal) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree(svp); + return; } void -disp_vec( const char *vecname ) +disp_vec(const char *vecname) { - vecs_t **svp; - arglist_t *ap; - int vc; - int i = 0; - - svp = sort_and_unify_vecs(&vc); - for (i=0;iname, vecname )) { - continue; - } - printf(VEC_FMT, svp[i]->name, svp[i]->desc); - for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) - printf(" %-18.18s %s%-.50s %s\n", - ap->argstring, - (ap->argtype & ARGTYPE_TYPEMASK) == - ARGTYPE_BOOL ? "(0/1) " : "", - ap->helpstring, - (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); - } - } - xfree (svp); - return; + vecs_t **svp; + arglist_t *ap; + int vc; + int i = 0; + + svp = sort_and_unify_vecs(&vc); + for (i=0; iname, vecname)) { + continue; + } + printf(VEC_FMT, svp[i]->name, svp[i]->desc); + for (ap = svp[i]->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) + printf(" %-18.18s %s%-.50s %s\n", + ap->argstring, + (ap->argtype & ARGTYPE_TYPEMASK) == + ARGTYPE_BOOL ? "(0/1) " : "", + ap->helpstring, + (ap->argtype & ARGTYPE_REQUIRED)?"(required)":""); + } + } + xfree(svp); + return; } /* @@ -1508,78 +1541,86 @@ disp_vec( const char *vecname ) static void disp_v1(ff_type t) { - char *tstring; - - switch (t) { - case ff_type_file: tstring = "file"; break; - case ff_type_serial: tstring = "serial"; break; - case ff_type_internal: tstring = "internal"; break; - default: tstring = "unknown"; break; - } - printf("%s\t", tstring); + char *tstring; + + switch (t) { + case ff_type_file: + tstring = "file"; + break; + case ff_type_serial: + tstring = "serial"; + break; + case ff_type_internal: + tstring = "internal"; + break; + default: + tstring = "unknown"; + break; + } + printf("%s\t", tstring); } static void disp_v2(ff_vecs_t *v) { - int i; - for (i = 0; i < 3; i++) { - putchar(v->cap[i] & ff_cap_read ? 'r' : '-'); - putchar(v->cap[i] & ff_cap_write ? 'w' : '-'); - } - putchar('\t'); + int i; + for (i = 0; i < 3; i++) { + putchar(v->cap[i] & ff_cap_read ? 'r' : '-'); + putchar(v->cap[i] & ff_cap_write ? 'w' : '-'); + } + putchar('\t'); } const char * name_option(long type) { - const char *at[] = { - "unknown", - "integer", - "float", - "string", - "boolean", - "file", - "outfile" - }; - - if ((type & ARGTYPE_TYPEMASK) <= 6) { - return at[type & ARGTYPE_TYPEMASK]; - } - return at[0]; + const char *at[] = { + "unknown", + "integer", + "float", + "string", + "boolean", + "file", + "outfile" + }; + + if ((type & ARGTYPE_TYPEMASK) <= 6) { + return at[type & ARGTYPE_TYPEMASK]; + } + return at[0]; } -static +static void disp_help_url(const vecs_t *vec, arglist_t *arg) { - printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); - if (arg) { - printf("#fmt_%s_o_%s",vec->name, arg->argstring); - } - printf("\n"); + printf("\t" WEB_DOC_DIR "/fmt_%s.html", vec->name); + if (arg) { + printf("#fmt_%s_o_%s",vec->name, arg->argstring); + } + printf("\n"); } -static void +static void disp_v3(const vecs_t *vec) { - arglist_t *ap; - - disp_help_url(vec, NULL); - for (ap = vec->vec->args; ap && ap->argstring; ap++) { - if ( !(ap->argtype & ARGTYPE_HIDDEN)) { - printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", - vec->name, - ap->argstring, - ap->helpstring, - name_option(ap->argtype), - ap->defaultvalue? ap->defaultvalue : "", - ap->minvalue? ap->minvalue : "", - ap->maxvalue? ap->maxvalue : ""); - } - disp_help_url(vec, ap); - printf("\n"); - } + arglist_t *ap; + + disp_help_url(vec, NULL); + for (ap = vec->vec->args; ap && ap->argstring; ap++) { + if (!(ap->argtype & ARGTYPE_HIDDEN)) { + printf("option\t%s\t%s\t%s\t%s\t%s\t%s\t%s", + vec->name, + ap->argstring, + ap->helpstring, + name_option(ap->argtype), + ap->defaultvalue? ap->defaultvalue : "", + ap->minvalue? ap->minvalue : "", + ap->maxvalue? ap->maxvalue : ""); + } + disp_help_url(vec, ap); + printf("\n"); + } } /* @@ -1590,43 +1631,44 @@ disp_v3(const vecs_t *vec) void disp_formats(int version) { - vecs_t **svp; - vecs_t *vec; - int i, vc = 0; - - switch(version) { - case 0: - case 1: - case 2: - case 3: - svp = sort_and_unify_vecs(&vc); - for (i=0;i 0) { - disp_v1(vec->vec->type); - } else { - if (vec->vec->type == ff_type_internal) - continue; - } - if (version >= 2) { - disp_v2(vec->vec); - } - printf("%s\t%s\t%s%s%s\n", vec->name, - vec->extension? vec->extension : "", - vec->desc, - version >= 3 ? "\t" : "", - version >= 3 ? vec->parent : ""); - if (version >= 3) { - disp_v3(vec); - } - } - xfree (svp); - break; - default: - ; - } + vecs_t **svp; + vecs_t *vec; + int i, vc = 0; + + switch (version) { + case 0: + case 1: + case 2: + case 3: + svp = sort_and_unify_vecs(&vc); + for (i=0; i 0) { + disp_v1(vec->vec->type); + } else { + if (vec->vec->type == ff_type_internal) { + continue; + } + } + if (version >= 2) { + disp_v2(vec->vec); + } + printf("%s\t%s\t%s%s%s\n", vec->name, + vec->extension? vec->extension : "", + vec->desc, + version >= 3 ? "\t" : "", + version >= 3 ? vec->parent : ""); + if (version >= 3) { + disp_v3(vec); + } + } + xfree(svp); + break; + default: + ; + } } diff --git a/gpsbabel/vidaone.c b/gpsbabel/vidaone.c index 630e2128b..472cd1938 100644 --- a/gpsbabel/vidaone.c +++ b/gpsbabel/vidaone.c @@ -20,17 +20,17 @@ */ - /* - Simple layout: - - struct - { - double dLatitude - double dLongitude - float fReserved - }; - */ - +/* + Simple layout: + +struct +{ + double dLatitude + double dLongitude + float fReserved +}; +*/ + #include "defs.h" #include #include @@ -44,10 +44,12 @@ static int vidaone_ver; static arglist_t vidaone_args[] = { - {VIDAONE_VER, &vidaone_opt_ver, - "Version of VidaOne file to read or write (1 or 2)", - "1", ARGTYPE_INT, "1", "2"}, - ARG_TERMINATOR + { + VIDAONE_VER, &vidaone_opt_ver, + "Version of VidaOne file to read or write (1 or 2)", + "1", ARGTYPE_INT, "1", "2" + }, + ARG_TERMINATOR }; static gbfile *fin, *fout; @@ -59,90 +61,93 @@ static gbfile *fin, *fout; static void vidaone_rd_init(const char *fname) { - vidaone_ver = atoi(vidaone_opt_ver); - fin = gbfopen(fname, "rb", MYNAME); + vidaone_ver = atoi(vidaone_opt_ver); + fin = gbfopen(fname, "rb", MYNAME); } -static void +static void vidaone_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static void vidaone_read(void) { - route_head *trk = NULL; - - while (! gbfeof(fin)) { - waypoint *wpt = waypt_new(); - - wpt->latitude = gbfgetdbl(fin); - wpt->longitude = gbfgetdbl(fin); - if (vidaone_ver >= 2) - wpt->altitude = gbfgetflt(fin); - (void) gbfgetflt(fin); - - /* Only one basic check of data integrity */ - if ((fabs(wpt->latitude) > 90) || (fabs(wpt->longitude) > 180)) - fatal(MYNAME ": Latitude and/or longitude out of range.\n"); - - if (!trk) { - trk = route_head_alloc(); - track_add_head(trk); - } - - track_add_wpt(trk, wpt); - } + route_head *trk = NULL; + + while (! gbfeof(fin)) { + waypoint *wpt = waypt_new(); + + wpt->latitude = gbfgetdbl(fin); + wpt->longitude = gbfgetdbl(fin); + if (vidaone_ver >= 2) { + wpt->altitude = gbfgetflt(fin); + } + (void) gbfgetflt(fin); + + /* Only one basic check of data integrity */ + if ((fabs(wpt->latitude) > 90) || (fabs(wpt->longitude) > 180)) { + fatal(MYNAME ": Latitude and/or longitude out of range.\n"); + } + + if (!trk) { + trk = route_head_alloc(); + track_add_head(trk); + } + + track_add_wpt(trk, wpt); + } } static void vidaone_wr_init(const char *fname) { - vidaone_ver = atoi(vidaone_opt_ver); - fout = gbfopen(fname, "wb", MYNAME); + vidaone_ver = atoi(vidaone_opt_ver); + fout = gbfopen(fname, "wb", MYNAME); } static void vidaone_wr_deinit(void) { - gbfclose(fout); + gbfclose(fout); } static void vidaone_trkpt(const waypoint *wpt) { - gbfputdbl(wpt->latitude, fout); - gbfputdbl(wpt->longitude, fout); - if (vidaone_ver >= 2) - gbfputflt(wpt->altitude, fout); - gbfputflt(0, fout); + gbfputdbl(wpt->latitude, fout); + gbfputdbl(wpt->longitude, fout); + if (vidaone_ver >= 2) { + gbfputflt(wpt->altitude, fout); + } + gbfputflt(0, fout); } static void vidaone_write(void) { - track_disp_all(NULL, NULL, vidaone_trkpt); + track_disp_all(NULL, NULL, vidaone_trkpt); } /**************************************************************************/ ff_vecs_t vidaone_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read | ff_cap_write /* tracks */, - ff_cap_none /* routes */ - }, - vidaone_rd_init, - vidaone_wr_init, - vidaone_rd_deinit, - vidaone_wr_deinit, - vidaone_read, - vidaone_write, - NULL, - vidaone_args, - CET_CHARSET_UTF8, 1 + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read | ff_cap_write /* tracks */, + ff_cap_none /* routes */ + }, + vidaone_rd_init, + vidaone_wr_init, + vidaone_rd_deinit, + vidaone_wr_deinit, + vidaone_read, + vidaone_write, + NULL, + vidaone_args, + CET_CHARSET_UTF8, 1 }; /**************************************************************************/ diff --git a/gpsbabel/vitosmt.c b/gpsbabel/vitosmt.c index 1297eb7b4..d2d3bcdd3 100644 --- a/gpsbabel/vitosmt.c +++ b/gpsbabel/vitosmt.c @@ -1,6 +1,6 @@ /* Read Vito Navigator .SMT tracks - + Copyright (C) 2005 Etienne TASSE This program is free software; you can redistribute it and/or modify @@ -40,10 +40,10 @@ const size_t vitosmt_datasize =64; static unsigned char * ReadRecord(gbfile *f, gbsize_t size) { - unsigned char *result = (unsigned char *) xmalloc(size); + unsigned char *result = (unsigned char *) xmalloc(size); - gbfread(result, size, 1, f); - return result; + gbfread(result, size, 1, f); + return result; } static void @@ -58,326 +58,321 @@ WriteDouble(void* ptr, double d) static void rd_init(const char *fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void vitosmt_read(void) { - long version =0; - long subversion =0; - long check1 =-1; - long check2 =-2; - long check3 =-3; - route_head *route_head =0; - waypoint *wpt_tmp =0; - double latrad =0; - double lonrad =0; - double elev =0; - unsigned char* timestamp =0; - struct tm tmStruct; - double seconds =0.0; - double speed =0.0; - double course =0.0; - double pdop =0.0; - unsigned char gpsfix =0; - unsigned char gpsvalid =0; - unsigned char gpssats =0; - int serial =0; - - - memset(&tmStruct, 0, sizeof(tmStruct)); - /* - * 24 bytes header - */ - version = gbfgetint32(infile); /* 2 */ - subversion = gbfgetint32(infile); /* 1000 */ - count = gbfgetint32(infile); /* n */ - check1 = gbfgetint32(infile); /* 0 */ - check2 = gbfgetint32(infile); /* not sure */ - check3 = gbfgetint32(infile); /* n */ - - if (version!=vitosmt_version) { - - fatal("%s (%d) reading file. Unsupported version %ld.%ld\n", - MYNAME, __LINE__, version, subversion ); - } - - if (subversion!=vitosmt_subversion) { - warning("%s (%d) reading file. Unsafe version %ld.%ld\n", - MYNAME, __LINE__, version, subversion ); - } - - if ((count!=check3) || - (check1!=count-1) || - (check3!=count) ) { - - fatal("%s (%d) reading file. Invalid file header\n", - MYNAME, __LINE__ ); - - } - - while (count) { - /* - * 64 bytes of data - */ - if (gbfeof(infile)||gbferror(infile)) - { - warning("%s (%d) reading file. Unexpected end of file %s\n", - MYNAME, __LINE__, strerror(errno) ); - break; - } + long version =0; + long subversion =0; + long check1 =-1; + long check2 =-2; + long check3 =-3; + route_head *route_head =0; + waypoint *wpt_tmp =0; + double latrad =0; + double lonrad =0; + double elev =0; + unsigned char* timestamp =0; + struct tm tmStruct; + double seconds =0.0; + double speed =0.0; + double course =0.0; + double pdop =0.0; + unsigned char gpsfix =0; + unsigned char gpsvalid =0; + unsigned char gpssats =0; + int serial =0; + + + memset(&tmStruct, 0, sizeof(tmStruct)); + /* + * 24 bytes header + */ + version = gbfgetint32(infile); /* 2 */ + subversion = gbfgetint32(infile); /* 1000 */ + count = gbfgetint32(infile); /* n */ + check1 = gbfgetint32(infile); /* 0 */ + check2 = gbfgetint32(infile); /* not sure */ + check3 = gbfgetint32(infile); /* n */ + + if (version!=vitosmt_version) { + + fatal("%s (%d) reading file. Unsupported version %ld.%ld\n", + MYNAME, __LINE__, version, subversion); + } + + if (subversion!=vitosmt_subversion) { + warning("%s (%d) reading file. Unsafe version %ld.%ld\n", + MYNAME, __LINE__, version, subversion); + } + + if ((count!=check3) || + (check1!=count-1) || + (check3!=count)) { + + fatal("%s (%d) reading file. Invalid file header\n", + MYNAME, __LINE__); + + } + + while (count) { + /* + * 64 bytes of data + */ + if (gbfeof(infile)||gbferror(infile)) { + warning("%s (%d) reading file. Unexpected end of file %s\n", + MYNAME, __LINE__, strerror(errno)); + break; + } #if 0 - fprintf(stderr, "Looptop %d\n", gbftell(infile)); + fprintf(stderr, "Looptop %d\n", gbftell(infile)); #endif - latrad =gbfgetdbl(infile); /* WGS84 latitude in radians */ - lonrad =gbfgetdbl(infile); /* WGS84 longitude in radians */ - elev =gbfgetdbl(infile); /* elevation in meters */ + latrad =gbfgetdbl(infile); /* WGS84 latitude in radians */ + lonrad =gbfgetdbl(infile); /* WGS84 longitude in radians */ + elev =gbfgetdbl(infile); /* elevation in meters */ #if 0 - fprintf(stderr, "before %d\n", gbftell(infile)); + fprintf(stderr, "before %d\n", gbftell(infile)); #endif - timestamp =ReadRecord(infile,5); /* UTC time yr/mo/dy/hr/mi */ + timestamp =ReadRecord(infile,5); /* UTC time yr/mo/dy/hr/mi */ #if 0 - fprintf(stderr, "%d latrad %f/%f ele %f\n", gbftell(infile),latrad, DEG(latrad), elev); + fprintf(stderr, "%d latrad %f/%f ele %f\n", gbftell(infile),latrad, DEG(latrad), elev); #endif - seconds =gbfgetdbl(infile); /* seconds */ - speed =gbfgetdbl(infile); /* speed in knots */ - course =gbfgetdbl(infile); /* course in degrees */ - pdop =gbfgetdbl(infile); /* dilution of precision */ - gpsfix =gbfgetc(infile); /* fix type x08,x10, x20 */ - gpsvalid =gbfgetc(infile); /* fix is valid */ - gpssats =gbfgetc(infile); /* number of sats */ - - wpt_tmp = waypt_new(); - - wpt_tmp->latitude =DEG(latrad); - wpt_tmp->longitude =DEG(lonrad); - wpt_tmp->altitude =elev; - - tmStruct.tm_year =timestamp[0]+100; - tmStruct.tm_mon =timestamp[1]-1; - tmStruct.tm_mday =timestamp[2]; - tmStruct.tm_hour =timestamp[3]; - tmStruct.tm_min =timestamp[4]; - tmStruct.tm_sec =(int)floor(seconds); - tmStruct.tm_isdst =-1; - - wpt_tmp->creation_time = mkgmtime(&tmStruct); - wpt_tmp->microseconds = fmod(1000000*seconds+0.5,1000000); - wpt_tmp->shortname =xcalloc(16,1); - snprintf(wpt_tmp->shortname, 15 , "WP%04d", ++serial); - - WAYPT_SET(wpt_tmp, speed, KNOTS_TO_MPS(speed)); /* meters per second */ - WAYPT_SET(wpt_tmp, course, course); - wpt_tmp->pdop = pdop; - - /* - GPS Fix data - */ - if (gpsvalid&0x7) { - if (gpsfix==0) - wpt_tmp->fix =fix_none; - if (gpsfix&0x8) - wpt_tmp->fix =fix_2d; - else if (gpsfix&0x10) - wpt_tmp->fix =fix_3d; - else if (gpsfix&0x20) - wpt_tmp->fix =fix_dgps; - else - wpt_tmp->fix =fix_unknown; - - /* */ - wpt_tmp->sat = gpssats; - } - else - wpt_tmp->fix =fix_unknown; - - if (doing_wpts) /* process as waypoints */ - { - waypt_add(wpt_tmp); - } - else if (doing_rtes) /* process as route */ - { - if (route_head == NULL) { - route_head = route_head_alloc(); - route_add_head(route_head); - } - route_add_wpt(route_head, wpt_tmp); - } - else /* default track mode */ - { - if (route_head == NULL) { - route_head = route_head_alloc(); - track_add_head(route_head); - } - track_add_wpt(route_head, wpt_tmp); - } - - xfree(timestamp); - - count--; - } + seconds =gbfgetdbl(infile); /* seconds */ + speed =gbfgetdbl(infile); /* speed in knots */ + course =gbfgetdbl(infile); /* course in degrees */ + pdop =gbfgetdbl(infile); /* dilution of precision */ + gpsfix =gbfgetc(infile); /* fix type x08,x10, x20 */ + gpsvalid =gbfgetc(infile); /* fix is valid */ + gpssats =gbfgetc(infile); /* number of sats */ + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude =DEG(latrad); + wpt_tmp->longitude =DEG(lonrad); + wpt_tmp->altitude =elev; + + tmStruct.tm_year =timestamp[0]+100; + tmStruct.tm_mon =timestamp[1]-1; + tmStruct.tm_mday =timestamp[2]; + tmStruct.tm_hour =timestamp[3]; + tmStruct.tm_min =timestamp[4]; + tmStruct.tm_sec =(int)floor(seconds); + tmStruct.tm_isdst =-1; + + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = fmod(1000000*seconds+0.5,1000000); + wpt_tmp->shortname =xcalloc(16,1); + snprintf(wpt_tmp->shortname, 15 , "WP%04d", ++serial); + + WAYPT_SET(wpt_tmp, speed, KNOTS_TO_MPS(speed)); /* meters per second */ + WAYPT_SET(wpt_tmp, course, course); + wpt_tmp->pdop = pdop; + + /* + GPS Fix data + */ + if (gpsvalid&0x7) { + if (gpsfix==0) { + wpt_tmp->fix =fix_none; + } + if (gpsfix&0x8) { + wpt_tmp->fix =fix_2d; + } else if (gpsfix&0x10) { + wpt_tmp->fix =fix_3d; + } else if (gpsfix&0x20) { + wpt_tmp->fix =fix_dgps; + } else { + wpt_tmp->fix =fix_unknown; + } + + /* */ + wpt_tmp->sat = gpssats; + } else { + wpt_tmp->fix =fix_unknown; + } + + if (doing_wpts) { /* process as waypoints */ + waypt_add(wpt_tmp); + } else if (doing_rtes) { /* process as route */ + if (route_head == NULL) { + route_head = route_head_alloc(); + route_add_head(route_head); + } + route_add_wpt(route_head, wpt_tmp); + } else { /* default track mode */ + if (route_head == NULL) { + route_head = route_head_alloc(); + track_add_head(route_head); + } + track_add_wpt(route_head, wpt_tmp); + } + + xfree(timestamp); + + count--; + } } static void wr_init(const char *fname) { - warning(MYNAME " write: format is experimental and may crash Vito Navigator II.\n"); - ofs = gbfopen_le(fname, "wb", MYNAME); + warning(MYNAME " write: format is experimental and may crash Vito Navigator II.\n"); + ofs = gbfopen_le(fname, "wb", MYNAME); } static void wr_deinit(void) { - gbfclose(ofs); + gbfclose(ofs); } static void vitosmt_waypt_pr(const waypoint *waypointp) { - unsigned char * workbuffer =0; - size_t position =0; - struct tm* tmstructp =0; - double seconds =0; - - ++count; - workbuffer = xcalloc(vitosmt_datasize,1); - - WriteDouble(&workbuffer[position], RAD(waypointp->latitude) ); - position += sizeof(double); - WriteDouble(&workbuffer[position], RAD(waypointp->longitude) ); - position += sizeof(double); - if ( waypointp->altitude-1 > unknown_alt) - WriteDouble(&workbuffer[position], waypointp->altitude ); - position += sizeof(double); - - tmstructp = gmtime(&waypointp->creation_time); - seconds = (double) tmstructp->tm_sec + 0.0000001*waypointp->microseconds; - - workbuffer[position++] =tmstructp->tm_year-100; - workbuffer[position++] =tmstructp->tm_mon+1; - workbuffer[position++] =tmstructp->tm_mday; - workbuffer[position++] =tmstructp->tm_hour; - workbuffer[position++] =tmstructp->tm_min; - - WriteDouble(&workbuffer[position], seconds ); - position += sizeof(double); - - /* speed */ - if (waypointp->speed>0) - WriteDouble(&workbuffer[position], MPS_TO_MPH(waypointp->speed)); - position += sizeof(double); - - /* course */ - if ((waypointp->course>=-360.0)&&(waypointp->course<=360.0)) - WriteDouble(&workbuffer[position], waypointp->course ); - position += sizeof(double); - - /* pdop */ - if (waypointp->pdop>0) - WriteDouble(&workbuffer[position], waypointp->pdop ); - position += sizeof(double); - - - /* fix type */ - switch (waypointp->fix) - { - case fix_2d: - workbuffer[position++] = 0x08; - break; - case fix_3d: - workbuffer[position++] = 0x10; - break; - case fix_dgps: - workbuffer[position++] = 0x20; - break; - default: - workbuffer[position++] = 0; - break; - } - - /* Assume position is valid */ - workbuffer[position++] = 0x07; - - if ((waypointp->sat>0)&&(waypointp->sat<128)) - workbuffer[position++] = waypointp->sat; - else - workbuffer[position++] = 0; - - (void)gbfwrite(workbuffer,vitosmt_datasize,1,ofs); - - xfree(workbuffer); + unsigned char * workbuffer =0; + size_t position =0; + struct tm* tmstructp =0; + double seconds =0; + + ++count; + workbuffer = xcalloc(vitosmt_datasize,1); + + WriteDouble(&workbuffer[position], RAD(waypointp->latitude)); + position += sizeof(double); + WriteDouble(&workbuffer[position], RAD(waypointp->longitude)); + position += sizeof(double); + if (waypointp->altitude-1 > unknown_alt) { + WriteDouble(&workbuffer[position], waypointp->altitude); + } + position += sizeof(double); + + tmstructp = gmtime(&waypointp->creation_time); + seconds = (double) tmstructp->tm_sec + 0.0000001*waypointp->microseconds; + + workbuffer[position++] =tmstructp->tm_year-100; + workbuffer[position++] =tmstructp->tm_mon+1; + workbuffer[position++] =tmstructp->tm_mday; + workbuffer[position++] =tmstructp->tm_hour; + workbuffer[position++] =tmstructp->tm_min; + + WriteDouble(&workbuffer[position], seconds); + position += sizeof(double); + + /* speed */ + if (waypointp->speed>0) { + WriteDouble(&workbuffer[position], MPS_TO_MPH(waypointp->speed)); + } + position += sizeof(double); + + /* course */ + if ((waypointp->course>=-360.0)&&(waypointp->course<=360.0)) { + WriteDouble(&workbuffer[position], waypointp->course); + } + position += sizeof(double); + + /* pdop */ + if (waypointp->pdop>0) { + WriteDouble(&workbuffer[position], waypointp->pdop); + } + position += sizeof(double); + + + /* fix type */ + switch (waypointp->fix) { + case fix_2d: + workbuffer[position++] = 0x08; + break; + case fix_3d: + workbuffer[position++] = 0x10; + break; + case fix_dgps: + workbuffer[position++] = 0x20; + break; + default: + workbuffer[position++] = 0; + break; + } + + /* Assume position is valid */ + workbuffer[position++] = 0x07; + + if ((waypointp->sat>0)&&(waypointp->sat<128)) { + workbuffer[position++] = waypointp->sat; + } else { + workbuffer[position++] = 0; + } + + (void)gbfwrite(workbuffer,vitosmt_datasize,1,ofs); + + xfree(workbuffer); } static void vitosmt_write(void) { - time_t now = 0; - unsigned char * workbuffer =0; - size_t position =0; - - workbuffer = xcalloc(vitosmt_headersize,1); - - now = current_time(); - count = 0; - position = 0; - - /* leave a spacer for the header */ - memset(workbuffer,0,vitosmt_headersize); - (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); - - if (doing_wpts) /* process as waypoints */ - { - waypt_disp_all(vitosmt_waypt_pr); - } - else if (doing_rtes) /* process as route */ - { - route_disp_all(NULL, NULL, vitosmt_waypt_pr); - } - else /* default track mode */ - { - track_disp_all(NULL, NULL, vitosmt_waypt_pr); - } - - - /* write the complete the header */ - le_write32(&workbuffer[position],vitosmt_version); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],vitosmt_subversion); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],0); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count-1); - position += sizeof(gbuint32); - le_write32(&workbuffer[position],count); - position += sizeof(gbuint32); - - gbfrewind(ofs); - (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); - - xfree(workbuffer); + time_t now = 0; + unsigned char * workbuffer =0; + size_t position =0; + + workbuffer = xcalloc(vitosmt_headersize,1); + + now = current_time(); + count = 0; + position = 0; + + /* leave a spacer for the header */ + memset(workbuffer,0,vitosmt_headersize); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + if (doing_wpts) { /* process as waypoints */ + waypt_disp_all(vitosmt_waypt_pr); + } else if (doing_rtes) { /* process as route */ + route_disp_all(NULL, NULL, vitosmt_waypt_pr); + } else { /* default track mode */ + track_disp_all(NULL, NULL, vitosmt_waypt_pr); + } + + + /* write the complete the header */ + le_write32(&workbuffer[position],vitosmt_version); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],vitosmt_subversion); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],0); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count-1); + position += sizeof(gbuint32); + le_write32(&workbuffer[position],count); + position += sizeof(gbuint32); + + gbfrewind(ofs); + (void)gbfwrite(workbuffer,vitosmt_headersize,1,ofs); + + xfree(workbuffer); } ff_vecs_t vitosmt_vecs = { - ff_type_file, - FF_CAP_RW_ALL, - rd_init, - wr_init, - rd_deinit, - wr_deinit, - vitosmt_read, - vitosmt_write, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ + ff_type_file, + FF_CAP_RW_ALL, + rd_init, + wr_init, + rd_deinit, + wr_deinit, + vitosmt_read, + vitosmt_write, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/gpsbabel/vitovtt.c b/gpsbabel/vitovtt.c index 99f6538e5..c4cc2f606 100644 --- a/gpsbabel/vitovtt.c +++ b/gpsbabel/vitovtt.c @@ -1,8 +1,8 @@ /* Read Vito SmartMap .vtt tracks - + Copyright (C) 2007 Jeremy Ehrhardt, jeremye@caltech.edu - + based on vitostc.c, which is Copyright (C) 2005 Etienne TASSE @@ -48,92 +48,92 @@ static const int vitovtt_microsecondscale = 30; static void rd_init(const char *fname) { - infile = gbfopen_le(fname, "rb", MYNAME); + infile = gbfopen_le(fname, "rb", MYNAME); } static void rd_deinit(void) { - gbfclose(infile); + gbfclose(infile); } static void vitovtt_read(void) { - int version = 0; - route_head *route_head = 0; - waypoint *wpt_tmp = 0; - int scaled_lat = 0; - int scaled_lon = 0; - double altitude = 0; - struct tm tmStruct; - int scaled_sec = 0; - int microseconds = 0; - double speed = 0; - int course = 0; - int status = 0; - - memset(&tmStruct, 0, sizeof(tmStruct)); - - route_head = route_head_alloc(); - track_add_head(route_head); - - /* Read the header. */ - version = gbfgetint32(infile); - count = gbfgetint32(infile); - - if (version!=vitovtt_version) { - - fatal("%s (%d) reading file. Unsupported version %d\n", - MYNAME, __LINE__, version ); - } - - while (count) { - /* Read an entry. */ - scaled_lat = gbfgetint32(infile); - scaled_lon = gbfgetint32(infile); - altitude = gbfgetflt(infile); - tmStruct.tm_year = gbfgetint16(infile) - TM_YEAR_ZERO; - tmStruct.tm_mon = gbfgetc(infile) - TM_MONTH_ZERO; - tmStruct.tm_mday = gbfgetc(infile); - tmStruct.tm_hour = gbfgetc(infile); - tmStruct.tm_min = gbfgetc(infile); - scaled_sec = gbfgetint32(infile); - speed = gbfgetflt(infile); - course = gbfgetint16(infile); - status = gbfgetint32(infile); - - wpt_tmp = waypt_new(); - - wpt_tmp->latitude = scaled_lat / vitovtt_latitudescale; - wpt_tmp->longitude = scaled_lon / vitovtt_longitudescale; - wpt_tmp->altitude = altitude; - - tmStruct.tm_sec = scaled_sec / vitovtt_secondscale; - microseconds = (scaled_sec % vitovtt_secondscale) / vitovtt_microsecondscale; - wpt_tmp->creation_time = mkgmtime(&tmStruct); - wpt_tmp->microseconds = microseconds; - - /* - * TODO: interpret speed, course, status - */ - - track_add_wpt(route_head, wpt_tmp); - - count--; - } + int version = 0; + route_head *route_head = 0; + waypoint *wpt_tmp = 0; + int scaled_lat = 0; + int scaled_lon = 0; + double altitude = 0; + struct tm tmStruct; + int scaled_sec = 0; + int microseconds = 0; + double speed = 0; + int course = 0; + int status = 0; + + memset(&tmStruct, 0, sizeof(tmStruct)); + + route_head = route_head_alloc(); + track_add_head(route_head); + + /* Read the header. */ + version = gbfgetint32(infile); + count = gbfgetint32(infile); + + if (version!=vitovtt_version) { + + fatal("%s (%d) reading file. Unsupported version %d\n", + MYNAME, __LINE__, version); + } + + while (count) { + /* Read an entry. */ + scaled_lat = gbfgetint32(infile); + scaled_lon = gbfgetint32(infile); + altitude = gbfgetflt(infile); + tmStruct.tm_year = gbfgetint16(infile) - TM_YEAR_ZERO; + tmStruct.tm_mon = gbfgetc(infile) - TM_MONTH_ZERO; + tmStruct.tm_mday = gbfgetc(infile); + tmStruct.tm_hour = gbfgetc(infile); + tmStruct.tm_min = gbfgetc(infile); + scaled_sec = gbfgetint32(infile); + speed = gbfgetflt(infile); + course = gbfgetint16(infile); + status = gbfgetint32(infile); + + wpt_tmp = waypt_new(); + + wpt_tmp->latitude = scaled_lat / vitovtt_latitudescale; + wpt_tmp->longitude = scaled_lon / vitovtt_longitudescale; + wpt_tmp->altitude = altitude; + + tmStruct.tm_sec = scaled_sec / vitovtt_secondscale; + microseconds = (scaled_sec % vitovtt_secondscale) / vitovtt_microsecondscale; + wpt_tmp->creation_time = mkgmtime(&tmStruct); + wpt_tmp->microseconds = microseconds; + + /* + * TODO: interpret speed, course, status + */ + + track_add_wpt(route_head, wpt_tmp); + + count--; + } } ff_vecs_t vitovtt_vecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - vitovtt_read, - NULL, - NULL, - NULL, - CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + vitovtt_read, + NULL, + NULL, + NULL, + CET_CHARSET_UTF8, 1 /* do nothing | CET-REVIEW */ }; diff --git a/gpsbabel/vmem.c b/gpsbabel/vmem.c index c35a02fa2..437b9cd4b 100644 --- a/gpsbabel/vmem.c +++ b/gpsbabel/vmem.c @@ -1,5 +1,5 @@ /* - vmem utilities. Manipulate allocated object optimized for + vmem utilities. Manipulate allocated object optimized for long-term persistence over raw speed. Copyright (C) 2003 Robert Lipe, robertlipe@usa.net @@ -23,28 +23,31 @@ #include "defs.h" #include -vmem_t +vmem_t vmem_alloc(size_t size, int flags) { - vmem_t vm; - /* - * By default, zero the allocated thingy. - */ - if (flags & VMFL_NOZERO) - vm.mem = xmalloc(size); - else - vm.mem = (char *) xcalloc(size, 1); - vm.size = size; - return vm; + vmem_t vm; + /* + * By default, zero the allocated thingy. + */ + if (flags & VMFL_NOZERO) { + vm.mem = xmalloc(size); + } else { + vm.mem = (char *) xcalloc(size, 1); + } + vm.size = size; + return vm; } void vmem_free(vmem_t *vm) { - if (vm->mem) xfree(vm->mem); - vm->mem = NULL; - vm->size = 0; - return; + if (vm->mem) { + xfree(vm->mem); + } + vm->mem = NULL; + vm->size = 0; + return; } /* @@ -54,12 +57,12 @@ vmem_free(vmem_t *vm) void vmem_realloc(vmem_t *vm, size_t size) { - /* - * Reallocate only if we must. - */ - if (size > vm->size) { - vm->mem = xrealloc(vm->mem, size); - vm->size = size; - } - return; + /* + * Reallocate only if we must. + */ + if (size > vm->size) { + vm->mem = xrealloc(vm->mem, size); + vm->size = size; + } + return; } diff --git a/gpsbabel/vpl.c b/gpsbabel/vpl.c index 16f32d348..6eb21c77f 100644 --- a/gpsbabel/vpl.c +++ b/gpsbabel/vpl.c @@ -101,7 +101,7 @@ C - Checksum */ -/* +/* TODO: - Implement checksum verification */ @@ -116,7 +116,7 @@ void vpl_parse_75_sentence(const char*); static arglist_t vpl_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; static gbfile *vpl_file_in; @@ -129,37 +129,37 @@ static route_head *track_head; static void vpl_rd_init(const char *fname) { - vpl_file_in = gbfopen(fname, "r", MYNAME); + vpl_file_in = gbfopen(fname, "r", MYNAME); } -static void +static void vpl_rd_deinit(void) { - gbfclose(vpl_file_in); + gbfclose(vpl_file_in); } static void vpl_read(void) { - char *ibuf; - - // Set up a track - if(track_head == NULL) { - track_head = route_head_alloc(); - track_add_head(track_head); - } - - while((ibuf = gbfgetstr(vpl_file_in))) { - if(strncmp(ibuf, "75", 2) == 0) { - vpl_parse_75_sentence(ibuf); - } - } + char *ibuf; + + // Set up a track + if (track_head == NULL) { + track_head = route_head_alloc(); + track_add_head(track_head); + } + + while ((ibuf = gbfgetstr(vpl_file_in))) { + if (strncmp(ibuf, "75", 2) == 0) { + vpl_parse_75_sentence(ibuf); + } + } } static void vpl_wr_init(const char *fname) { - fatal("Writing file of type %s is not support\n", MYNAME); + fatal("Writing file of type %s is not support\n", MYNAME); } /******************************************************************************* @@ -169,69 +169,69 @@ vpl_wr_init(const char *fname) void vpl_parse_75_sentence(const char *ibuf) { - gbuint32 ymd, hms; - gbint32 lat_raw, lon_raw; - gbint16 alt, speed_raw; - gbuint16 hdg_raw; - gbuint8 sats, hdop_raw, vdop_raw; - waypoint *waypt; - struct tm tm; - - // The files have DOS line endings (CR/LF) but we don't care, because we - // don't read to the end. - sscanf(ibuf, "75%*2c%8X%8X%4hX%4hX%4hX%*2c%2hhX%2hhX%2hhX%6u%6u", - &lat_raw, &lon_raw, &alt, &speed_raw, &hdg_raw, &sats, &hdop_raw, &vdop_raw, - &ymd, &hms); - - tm.tm_sec = hms % 100; - hms /= 100; - tm.tm_min = hms % 100; - hms /= 100; - tm.tm_hour = hms % 100; - - tm.tm_mday = ymd % 100; - ymd /= 100; - tm.tm_mon = ymd % 100; - ymd /= 100; - tm.tm_year = ymd % 100 + 100; - - waypt = waypt_new(); - - // Lat/Lon are both stored *0xE1000 which we have to divide out - // for decimal degrees - waypt->latitude = lat_raw / (double) 0xE1000; - waypt->longitude = lon_raw / (double) 0xE1000; - waypt->altitude = alt; - waypt->sat = sats; - // Speed comes in (MPH x 0x10) which we have to convert to m/s - WAYPT_SET(waypt, speed, (speed_raw / (double) 0x10) * 0.44704); - waypt->course = hdg_raw * (double) (360/65535); - waypt->hdop = hdop_raw / (double) 8; - waypt->vdop = vdop_raw / (double) 8; - - waypt->creation_time = mkgmtime(&tm); - - track_add_wpt(track_head, waypt); + gbuint32 ymd, hms; + gbint32 lat_raw, lon_raw; + gbint16 alt, speed_raw; + gbuint16 hdg_raw; + gbuint8 sats, hdop_raw, vdop_raw; + waypoint *waypt; + struct tm tm; + + // The files have DOS line endings (CR/LF) but we don't care, because we + // don't read to the end. + sscanf(ibuf, "75%*2c%8X%8X%4hX%4hX%4hX%*2c%2hhX%2hhX%2hhX%6u%6u", + &lat_raw, &lon_raw, &alt, &speed_raw, &hdg_raw, &sats, &hdop_raw, &vdop_raw, + &ymd, &hms); + + tm.tm_sec = hms % 100; + hms /= 100; + tm.tm_min = hms % 100; + hms /= 100; + tm.tm_hour = hms % 100; + + tm.tm_mday = ymd % 100; + ymd /= 100; + tm.tm_mon = ymd % 100; + ymd /= 100; + tm.tm_year = ymd % 100 + 100; + + waypt = waypt_new(); + + // Lat/Lon are both stored *0xE1000 which we have to divide out + // for decimal degrees + waypt->latitude = lat_raw / (double) 0xE1000; + waypt->longitude = lon_raw / (double) 0xE1000; + waypt->altitude = alt; + waypt->sat = sats; + // Speed comes in (MPH x 0x10) which we have to convert to m/s + WAYPT_SET(waypt, speed, (speed_raw / (double) 0x10) * 0.44704); + waypt->course = hdg_raw * (double)(360/65535); + waypt->hdop = hdop_raw / (double) 8; + waypt->vdop = vdop_raw / (double) 8; + + waypt->creation_time = mkgmtime(&tm); + + track_add_wpt(track_head, waypt); } /**************************************************************************/ ff_vecs_t vpl_vecs = { - ff_type_file, - { - ff_cap_none /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - vpl_rd_init, - vpl_wr_init, - vpl_rd_deinit, - NULL, - vpl_read, - NULL, - NULL, - vpl_args, - CET_CHARSET_ASCII, /* ascii is the expected character set */ - 1 /* fixed, can't be changed through command line parameter */ + ff_type_file, + { + ff_cap_none /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + vpl_rd_init, + vpl_wr_init, + vpl_rd_deinit, + NULL, + vpl_read, + NULL, + NULL, + vpl_args, + CET_CHARSET_ASCII, /* ascii is the expected character set */ + 1 /* fixed, can't be changed through command line parameter */ }; /**************************************************************************/ diff --git a/gpsbabel/waypt.c b/gpsbabel/waypt.c index 912a463ee..4d55a7bab 100644 --- a/gpsbabel/waypt.c +++ b/gpsbabel/waypt.c @@ -34,161 +34,174 @@ static global_trait traits; const global_trait* get_traits(void) { - return &traits; + return &traits; } void waypt_init(void) { - mkshort_handle = mkshort_new_handle(); - QUEUE_INIT(&waypt_head); + mkshort_handle = mkshort_new_handle(); + QUEUE_INIT(&waypt_head); } waypoint * -waypt_dupe(const waypoint *wpt) -{ - /* - * This and waypt_free should be closely synced. - */ - waypoint * tmp; - url_link *url_next; - - tmp = waypt_new(); - memcpy(tmp, wpt, sizeof(waypoint)); - tmp->url_next = NULL; - - if (wpt->shortname) - tmp->shortname = xstrdup(wpt->shortname); - if (wpt->description) - tmp->description = xstrdup(wpt->description); - if (wpt->notes) - tmp->notes = xstrdup(wpt->notes); - if (wpt->url) - tmp->url = xstrdup(wpt->url); - if (wpt->url_link_text) - tmp->url_link_text = xstrdup(wpt->url_link_text); - for (url_next = wpt->url_next; url_next; url_next = url_next->url_next) { - waypt_add_url(tmp, - (url_next->url) ? xstrdup(url_next->url) : NULL, - (url_next->url_link_text) ? xstrdup(url_next->url_link_text) : NULL); - } - if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) - tmp->icon_descr = xstrdup(wpt->icon_descr); - - if (wpt->gc_data != &empty_gc_data) { - geocache_data *gc_data = xmalloc(sizeof(*gc_data)); - tmp->gc_data = (const geocache_data *)gc_data; - - memcpy(gc_data, wpt->gc_data, sizeof(*gc_data)); - if (wpt->gc_data->desc_short.utfstring) { - gc_data->desc_short.utfstring = - xstrdup(wpt->gc_data->desc_short.utfstring); - } - if (wpt->gc_data->desc_long.utfstring) { - gc_data->desc_long.utfstring = - xstrdup(wpt->gc_data->desc_long.utfstring); - } - if (wpt->gc_data->placer) { - gc_data->placer = xstrdup(wpt->gc_data->placer); - } - if (wpt->gc_data->hint) { - gc_data->hint = xstrdup(wpt->gc_data->hint); - } - } - - /* - * It's important that this duplicated waypoint not appear - * on the master Q. - */ - QUEUE_INIT(&tmp->Q); - tmp->fs = fs_chain_copy( wpt->fs ); - - return tmp; +waypt_dupe(const waypoint *wpt) +{ + /* + * This and waypt_free should be closely synced. + */ + waypoint * tmp; + url_link *url_next; + + tmp = waypt_new(); + memcpy(tmp, wpt, sizeof(waypoint)); + tmp->url_next = NULL; + + if (wpt->shortname) { + tmp->shortname = xstrdup(wpt->shortname); + } + if (wpt->description) { + tmp->description = xstrdup(wpt->description); + } + if (wpt->notes) { + tmp->notes = xstrdup(wpt->notes); + } + if (wpt->url) { + tmp->url = xstrdup(wpt->url); + } + if (wpt->url_link_text) { + tmp->url_link_text = xstrdup(wpt->url_link_text); + } + for (url_next = wpt->url_next; url_next; url_next = url_next->url_next) { + waypt_add_url(tmp, + (url_next->url) ? xstrdup(url_next->url) : NULL, + (url_next->url_link_text) ? xstrdup(url_next->url_link_text) : NULL); + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { + tmp->icon_descr = xstrdup(wpt->icon_descr); + } + + if (wpt->gc_data != &empty_gc_data) { + geocache_data *gc_data = xmalloc(sizeof(*gc_data)); + tmp->gc_data = (const geocache_data *)gc_data; + + memcpy(gc_data, wpt->gc_data, sizeof(*gc_data)); + if (wpt->gc_data->desc_short.utfstring) { + gc_data->desc_short.utfstring = + xstrdup(wpt->gc_data->desc_short.utfstring); + } + if (wpt->gc_data->desc_long.utfstring) { + gc_data->desc_long.utfstring = + xstrdup(wpt->gc_data->desc_long.utfstring); + } + if (wpt->gc_data->placer) { + gc_data->placer = xstrdup(wpt->gc_data->placer); + } + if (wpt->gc_data->hint) { + gc_data->hint = xstrdup(wpt->gc_data->hint); + } + } + + /* + * It's important that this duplicated waypoint not appear + * on the master Q. + */ + QUEUE_INIT(&tmp->Q); + tmp->fs = fs_chain_copy(wpt->fs); + + return tmp; } void update_common_traits(const waypoint* wpt) { - /* This is a bit tacky, but it allows a hint whether we've seen - * this data or not in the life cycle of this run. Of course, - * the caches could have been filtered out of existance and not - * all waypoints may have this and a few other pitfalls, but it's - * an easy and fast test here. - */ - traits.trait_geocaches |= (wpt->gc_data->diff && wpt->gc_data->terr); - traits.trait_heartrate |= wpt->heartrate > 0; - traits.trait_cadence |= wpt->cadence > 0; - traits.trait_power |= wpt->power > 0; - traits.trait_depth |= WAYPT_HAS(wpt, depth); - traits.trait_temperature |= WAYPT_HAS(wpt, temperature); + /* This is a bit tacky, but it allows a hint whether we've seen + * this data or not in the life cycle of this run. Of course, + * the caches could have been filtered out of existance and not + * all waypoints may have this and a few other pitfalls, but it's + * an easy and fast test here. + */ + traits.trait_geocaches |= (wpt->gc_data->diff && wpt->gc_data->terr); + traits.trait_heartrate |= wpt->heartrate > 0; + traits.trait_cadence |= wpt->cadence > 0; + traits.trait_power |= wpt->power > 0; + traits.trait_depth |= WAYPT_HAS(wpt, depth); + traits.trait_temperature |= WAYPT_HAS(wpt, temperature); } void waypt_add(waypoint *wpt) { - double lat_orig = wpt->latitude; - double lon_orig = wpt->longitude; - - ENQUEUE_TAIL(&waypt_head, &wpt->Q); - - waypt_ct++; - - if (wpt->latitude < -90) wpt->latitude += 180; - else if (wpt->latitude > +90) wpt->latitude -= 180; - if (wpt->longitude < -180) wpt->longitude += 360; - else if (wpt->longitude > +180) wpt->longitude -= 360; - - if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) - fatal("%s: Invalid latitude %f in waypoint %s.\n", - wpt->session->name, - lat_orig, wpt->shortname ? wpt->shortname : ""); - if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) - fatal ("Invalid longitude %f in waypoint %s.\n", - lon_orig, wpt->shortname ? wpt->shortname : ""); - if (wpt->creation_time < 0) { - warning("%s: Invalid timestamp in waypoint %s.\n", - wpt->session->name, - wpt->shortname ? wpt->shortname : ""); - wpt->creation_time = 0; - } - /* - * Some input may not have one or more of these types so we - * try to be sure that we have these fields even if just by - * copying them from elsewhere. - */ - if (wpt->shortname == NULL) { - if (wpt->description) { - wpt->shortname = xstrdup(wpt->description); - } else if (wpt->notes) { - wpt->shortname = xstrdup(wpt->notes); - } else { - /* Last ditch: make up a name */ - char cbuf[10]; - snprintf(cbuf, sizeof(cbuf), "WPT%03d", waypt_ct); - wpt->shortname = xstrdup(cbuf); - } - } - - if (wpt->description == NULL || strlen(wpt->description) == 0) { - if (wpt->description) - xfree(wpt->description); - if (wpt->notes != NULL) { - wpt->description = xstrdup(wpt->notes); - } else { - if (wpt->shortname != NULL) { - wpt->description = xstrdup(wpt->shortname); - } - } - } - - update_common_traits(wpt); + double lat_orig = wpt->latitude; + double lon_orig = wpt->longitude; + + ENQUEUE_TAIL(&waypt_head, &wpt->Q); + + waypt_ct++; + + if (wpt->latitude < -90) { + wpt->latitude += 180; + } else if (wpt->latitude > +90) { + wpt->latitude -= 180; + } + if (wpt->longitude < -180) { + wpt->longitude += 360; + } else if (wpt->longitude > +180) { + wpt->longitude -= 360; + } + + if ((wpt->latitude < -90) || (wpt->latitude > 90.0)) + fatal("%s: Invalid latitude %f in waypoint %s.\n", + wpt->session->name, + lat_orig, wpt->shortname ? wpt->shortname : ""); + if ((wpt->longitude < -180) || (wpt->longitude > 180.0)) + fatal("Invalid longitude %f in waypoint %s.\n", + lon_orig, wpt->shortname ? wpt->shortname : ""); + if (wpt->creation_time < 0) { + warning("%s: Invalid timestamp in waypoint %s.\n", + wpt->session->name, + wpt->shortname ? wpt->shortname : ""); + wpt->creation_time = 0; + } + /* + * Some input may not have one or more of these types so we + * try to be sure that we have these fields even if just by + * copying them from elsewhere. + */ + if (wpt->shortname == NULL) { + if (wpt->description) { + wpt->shortname = xstrdup(wpt->description); + } else if (wpt->notes) { + wpt->shortname = xstrdup(wpt->notes); + } else { + /* Last ditch: make up a name */ + char cbuf[10]; + snprintf(cbuf, sizeof(cbuf), "WPT%03d", waypt_ct); + wpt->shortname = xstrdup(cbuf); + } + } + + if (wpt->description == NULL || strlen(wpt->description) == 0) { + if (wpt->description) { + xfree(wpt->description); + } + if (wpt->notes != NULL) { + wpt->description = xstrdup(wpt->notes); + } else { + if (wpt->shortname != NULL) { + wpt->description = xstrdup(wpt->shortname); + } + } + } + + update_common_traits(wpt); } void waypt_del(waypoint *wpt) { - dequeue(&wpt->Q); - waypt_ct--; + dequeue(&wpt->Q); + waypt_ct--; } /* @@ -197,135 +210,143 @@ waypt_del(waypoint *wpt) waypoint * waypt_new(void) { - waypoint *wpt; + waypoint *wpt; - wpt = (waypoint *) xcalloc(sizeof (*wpt), 1); + wpt = (waypoint *) xcalloc(sizeof(*wpt), 1); #ifdef DEBUG_MEM - wpt->altitude = unknown_alt; - wpt->longitude = unknown_alt; + wpt->altitude = unknown_alt; + wpt->longitude = unknown_alt; #endif - wpt->altitude = unknown_alt; - wpt->fix = fix_unknown; - wpt->sat = -1; - wpt->session = curr_session(); - wpt->gc_data = &empty_gc_data; + wpt->altitude = unknown_alt; + wpt->fix = fix_unknown; + wpt->sat = -1; + wpt->session = curr_session(); + wpt->gc_data = &empty_gc_data; - QUEUE_INIT(&wpt->Q); - return wpt; + QUEUE_INIT(&wpt->Q); + return wpt; } unsigned int waypt_count(void) { - return waypt_ct; + return waypt_ct; } void set_waypt_count(unsigned int nc) { - waypt_ct = nc; + waypt_ct = nc; } void waypt_disp(const waypoint *wpt) { - char *tmpdesc = NULL; - if (wpt->creation_time) { - printf("%s ", ctime(&wpt->creation_time)); - } - printposn(wpt->latitude,1); - printposn(wpt->longitude,0); - - if ( wpt->description ) { - tmpdesc = xstrdup( wpt->description); - printf("%s/%s", - global_opts.synthesize_shortnames ? - mkshort(mkshort_handle, tmpdesc) : - wpt->shortname, - tmpdesc); - if ( tmpdesc ) - xfree(tmpdesc); - } - - if (wpt->altitude != unknown_alt) - printf(" %f", wpt->altitude); - printf("\n"); + char *tmpdesc = NULL; + if (wpt->creation_time) { + printf("%s ", ctime(&wpt->creation_time)); + } + printposn(wpt->latitude,1); + printposn(wpt->longitude,0); + + if (wpt->description) { + tmpdesc = xstrdup(wpt->description); + printf("%s/%s", + global_opts.synthesize_shortnames ? + mkshort(mkshort_handle, tmpdesc) : + wpt->shortname, + tmpdesc); + if (tmpdesc) { + xfree(tmpdesc); + } + } + + if (wpt->altitude != unknown_alt) { + printf(" %f", wpt->altitude); + } + printf("\n"); } void waypt_status_disp(int total_ct, int myct) { - fprintf(stdout, "%d/%d/%d\r", myct*100/total_ct, myct, total_ct); - fflush(stdout); + fprintf(stdout, "%d/%d/%d\r", myct*100/total_ct, myct, total_ct); + fflush(stdout); } void waypt_disp_all(waypt_cb cb) { - waypt_disp_session(NULL, cb); + waypt_disp_session(NULL, cb); } void waypt_disp_session(const session_t *se, waypt_cb cb) { - queue *elem, *tmp; - waypoint *waypointp; - int i = 0; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - if ((se == NULL) || (waypointp->session == se)) { - if (global_opts.verbose_status) { - i++; - waypt_status_disp(waypt_ct, i); - } - (*cb) (waypointp); - } - } - if (global_opts.verbose_status) { - fprintf(stdout, "\r\n"); - } + queue *elem, *tmp; + waypoint *waypointp; + int i = 0; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if ((se == NULL) || (waypointp->session == se)) { + if (global_opts.verbose_status) { + i++; + waypt_status_disp(waypt_ct, i); + } + (*cb)(waypointp); + } + } + if (global_opts.verbose_status) { + fprintf(stdout, "\r\n"); + } } void waypt_init_bounds(bounds *bounds) { - /* Set data out of bounds so that even one waypoint will reset */ - bounds->max_lat = -9999; - bounds->max_lon = -9999; - bounds->min_lat = 9999; - bounds->min_lon = 9999; - bounds->max_alt = unknown_alt; - bounds->min_alt = -unknown_alt; + /* Set data out of bounds so that even one waypoint will reset */ + bounds->max_lat = -9999; + bounds->max_lon = -9999; + bounds->min_lat = 9999; + bounds->min_lon = 9999; + bounds->max_alt = unknown_alt; + bounds->min_alt = -unknown_alt; } int waypt_bounds_valid(bounds *bounds) { - /* Returns true if bb has any 'real' data in it */ - return bounds->max_lat > -9999; + /* Returns true if bb has any 'real' data in it */ + return bounds->max_lat > -9999; } /* * Recompund bounding box based on new position point. */ -void +void waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) { - if (waypointp->latitude > bounds->max_lat) - bounds->max_lat = waypointp->latitude; - if (waypointp->longitude > bounds->max_lon) - bounds->max_lon = waypointp->longitude; - if (waypointp->latitude < bounds->min_lat) - bounds->min_lat = waypointp->latitude; - if (waypointp->longitude < bounds->min_lon) - bounds->min_lon = waypointp->longitude; - if (waypointp->altitude != unknown_alt) { - if (waypointp->altitude < bounds->min_alt) - bounds->min_alt = waypointp->altitude; - if (waypointp->altitude > bounds->max_alt) - bounds->max_alt = waypointp->altitude; - } + if (waypointp->latitude > bounds->max_lat) { + bounds->max_lat = waypointp->latitude; + } + if (waypointp->longitude > bounds->max_lon) { + bounds->max_lon = waypointp->longitude; + } + if (waypointp->latitude < bounds->min_lat) { + bounds->min_lat = waypointp->latitude; + } + if (waypointp->longitude < bounds->min_lon) { + bounds->min_lon = waypointp->longitude; + } + if (waypointp->altitude != unknown_alt) { + if (waypointp->altitude < bounds->min_alt) { + bounds->min_alt = waypointp->altitude; + } + if (waypointp->altitude > bounds->max_alt) { + bounds->max_alt = waypointp->altitude; + } + } } @@ -337,289 +358,304 @@ waypt_add_to_bounds(bounds *bounds, const waypoint *waypointp) void waypt_compute_bounds(bounds *bounds) { - queue *elem, *tmp; - waypoint *waypointp; + queue *elem, *tmp; + waypoint *waypointp; - waypt_init_bounds(bounds); + waypt_init_bounds(bounds); - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - waypt_add_to_bounds(bounds, waypointp); - } + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + waypt_add_to_bounds(bounds, waypointp); + } } waypoint * find_waypt_by_name(const char *name) { - queue *elem, *tmp; - waypoint *waypointp; - - QUEUE_FOR_EACH(&waypt_head, elem, tmp) { - waypointp = (waypoint *) elem; - if (0 == strcmp(waypointp->shortname, name)) { - return waypointp; - } - } - - return NULL; -} - -void -waypt_free( waypoint *wpt ) -{ - /* - * This and waypt_dupe should be closely synced. - */ - if (wpt->shortname) { - xfree(wpt->shortname); - } - if (wpt->description) { - xfree(wpt->description); - } - if (wpt->notes) { - xfree(wpt->notes); - } - if (wpt->url) { - xfree(wpt->url); - } - if (wpt->url_link_text) { - xfree(wpt->url_link_text); - } - if (wpt->url_next) { - url_link *url_next; - - for (url_next = wpt->url_next; url_next; ) { - - url_link *tonuke = url_next; - if (tonuke->url) { - xfree(tonuke->url); - } - if (tonuke->url_link_text) { - xfree(tonuke->url_link_text); - } - url_next = tonuke->url_next; - xfree(tonuke); - } - } - if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { - xfree((char *)(void *)wpt->icon_descr); - } - - if (wpt->gc_data != &empty_gc_data) { - geocache_data *gc_data = (geocache_data *)wpt->gc_data; - - if (gc_data->desc_short.utfstring) { - xfree(gc_data->desc_short.utfstring); - } - if (gc_data->desc_long.utfstring) { - xfree(gc_data->desc_long.utfstring); - } - if (gc_data->placer) { - xfree(gc_data->placer); - } - if (gc_data->hint) { - xfree (gc_data->hint); - } - xfree(gc_data); - } - fs_chain_destroy( wpt->fs ); - xfree(wpt); -} - -void -waypt_flush( queue *head ) -{ - queue *elem, *tmp; - - QUEUE_FOR_EACH(head, elem, tmp) { - waypoint *q = (waypoint *) dequeue(elem); - waypt_free(q); - if (head == &waypt_head) { - waypt_ct--; - } - } + queue *elem, *tmp; + waypoint *waypointp; + + QUEUE_FOR_EACH(&waypt_head, elem, tmp) { + waypointp = (waypoint *) elem; + if (0 == strcmp(waypointp->shortname, name)) { + return waypointp; + } + } + + return NULL; +} + +void +waypt_free(waypoint *wpt) +{ + /* + * This and waypt_dupe should be closely synced. + */ + if (wpt->shortname) { + xfree(wpt->shortname); + } + if (wpt->description) { + xfree(wpt->description); + } + if (wpt->notes) { + xfree(wpt->notes); + } + if (wpt->url) { + xfree(wpt->url); + } + if (wpt->url_link_text) { + xfree(wpt->url_link_text); + } + if (wpt->url_next) { + url_link *url_next; + + for (url_next = wpt->url_next; url_next;) { + + url_link *tonuke = url_next; + if (tonuke->url) { + xfree(tonuke->url); + } + if (tonuke->url_link_text) { + xfree(tonuke->url_link_text); + } + url_next = tonuke->url_next; + xfree(tonuke); + } + } + if (wpt->icon_descr && wpt->wpt_flags.icon_descr_is_dynamic) { + xfree((char *)(void *)wpt->icon_descr); + } + + if (wpt->gc_data != &empty_gc_data) { + geocache_data *gc_data = (geocache_data *)wpt->gc_data; + + if (gc_data->desc_short.utfstring) { + xfree(gc_data->desc_short.utfstring); + } + if (gc_data->desc_long.utfstring) { + xfree(gc_data->desc_long.utfstring); + } + if (gc_data->placer) { + xfree(gc_data->placer); + } + if (gc_data->hint) { + xfree(gc_data->hint); + } + xfree(gc_data); + } + fs_chain_destroy(wpt->fs); + xfree(wpt); +} + +void +waypt_flush(queue *head) +{ + queue *elem, *tmp; + + QUEUE_FOR_EACH(head, elem, tmp) { + waypoint *q = (waypoint *) dequeue(elem); + waypt_free(q); + if (head == &waypt_head) { + waypt_ct--; + } + } } void waypt_flush_all() { - if ( mkshort_handle ) { - mkshort_del_handle( &mkshort_handle ); - } - waypt_flush(&waypt_head); + if (mkshort_handle) { + mkshort_del_handle(&mkshort_handle); + } + waypt_flush(&waypt_head); } void waypt_backup(signed int *count, queue **head_bak) { - queue *elem, *tmp, *qbackup; - waypoint *wpt; - int no = 0; + queue *elem, *tmp, *qbackup; + waypoint *wpt; + int no = 0; - qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); - QUEUE_INIT(qbackup); - - QUEUE_MOVE(qbackup, &waypt_head); - QUEUE_INIT(&waypt_head); + qbackup = (queue *) xcalloc(1, sizeof(*qbackup)); + QUEUE_INIT(qbackup); - waypt_ct = 0; + QUEUE_MOVE(qbackup, &waypt_head); + QUEUE_INIT(&waypt_head); - QUEUE_FOR_EACH(qbackup, elem, tmp) - { - wpt = (waypoint *)elem; - waypt_add(waypt_dupe(wpt)); - no++; - } + waypt_ct = 0; - *head_bak = qbackup; - *count = no; + QUEUE_FOR_EACH(qbackup, elem, tmp) { + wpt = (waypoint *)elem; + waypt_add(waypt_dupe(wpt)); + no++; + } + + *head_bak = qbackup; + *count = no; } void waypt_restore(signed int count, queue *head_bak) { - if (head_bak == NULL) return; - - waypt_flush(&waypt_head); - QUEUE_INIT(&waypt_head); - QUEUE_MOVE(&waypt_head, head_bak); - waypt_ct = count; - xfree(head_bak); + if (head_bak == NULL) { + return; + } + + waypt_flush(&waypt_head); + QUEUE_INIT(&waypt_head); + QUEUE_MOVE(&waypt_head, head_bak); + waypt_ct = count; + xfree(head_bak); } void waypt_add_url(waypoint *wpt, char *link, char *url_link_text) { - if ((link == NULL) && (url_link_text == NULL)) return; - - /* Special case first one; it goes right into the waypoint. */ - if ((wpt->url == NULL) && (wpt->url_link_text == NULL)) { - wpt->url = link; - wpt->url_link_text = url_link_text; - } else { - url_link *tail; - url_link *new_link = xcalloc(sizeof(url_link), 1); - new_link->url = link; - new_link->url_link_text = url_link_text; - - /* Find current end of chain and tack this onto the end.. */ - for (tail = wpt->url_next;;tail = tail->url_next) { - if (tail == NULL) { - wpt->url_next = new_link; - break; - } - if (tail->url_next == NULL) { - tail->url_next = new_link; - break; - } - } - } + if ((link == NULL) && (url_link_text == NULL)) { + return; + } + + /* Special case first one; it goes right into the waypoint. */ + if ((wpt->url == NULL) && (wpt->url_link_text == NULL)) { + wpt->url = link; + wpt->url_link_text = url_link_text; + } else { + url_link *tail; + url_link *new_link = xcalloc(sizeof(url_link), 1); + new_link->url = link; + new_link->url_link_text = url_link_text; + + /* Find current end of chain and tack this onto the end.. */ + for (tail = wpt->url_next;; tail = tail->url_next) { + if (tail == NULL) { + wpt->url_next = new_link; + break; + } + if (tail->url_next == NULL) { + tail->url_next = new_link; + break; + } + } + } } double gcgeodist(const double lat1, const double lon1, - const double lat2, const double lon2) + const double lat2, const double lon2) { - double res; + double res; + + res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); + if (res < 0.1) { + res = 0; /* calc. diffs on 32- and 64-bit hosts */ + } - res = radtometers(gcdist(RAD(lat1), RAD(lon1), RAD(lat2), RAD(lon2))); - if (res < 0.1) res = 0; /* calc. diffs on 32- and 64-bit hosts */ - - return res; + return res; } /* * returns full creation_time with parts of seconds in fractional portion */ - + double waypt_time(const waypoint *wpt) { - if (wpt->creation_time <= 0) - return (double) 0; - else - return ((double)wpt->creation_time + ((double)wpt->microseconds / 1000000)); + if (wpt->creation_time <= 0) { + return (double) 0; + } else { + return ((double)wpt->creation_time + ((double)wpt->microseconds / 1000000)); + } } /* * Calculates the distance between points "A" and "B" including * special data (Garmin interstep links) * The result comes in meters. - */ + */ double waypt_distance_ex(const waypoint *A, const waypoint *B) { - double res = 0; - garmin_fs_p gmsd; - - if ((A == NULL) || (B == NULL)) return 0; - - if ((gmsd = GMSD_FIND(A)) && (gmsd->ilinks != NULL)) - { - garmin_ilink_t *link = gmsd->ilinks; - - res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon); - while (link->next != NULL) - { - garmin_ilink_t *prev = link; - link = link->next; - res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon); - } - res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude); - } - else - res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); - - return res; + double res = 0; + garmin_fs_p gmsd; + + if ((A == NULL) || (B == NULL)) { + return 0; + } + + if ((gmsd = GMSD_FIND(A)) && (gmsd->ilinks != NULL)) { + garmin_ilink_t *link = gmsd->ilinks; + + res = gcgeodist(A->latitude, A->longitude, link->lat, link->lon); + while (link->next != NULL) { + garmin_ilink_t *prev = link; + link = link->next; + res += gcgeodist(prev->lat, prev->lon, link->lat, link->lon); + } + res += gcgeodist(link->lat, link->lon, B->latitude, B->longitude); + } else { + res = gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + } + + return res; } double waypt_distance(const waypoint *A, const waypoint *B) { - if ((A == NULL) || (B == NULL)) return 0; - else return gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + if ((A == NULL) || (B == NULL)) { + return 0; + } else { + return gcgeodist(A->latitude, A->longitude, B->latitude, B->longitude); + } } /* * Calculates the speed between points "A" and "B" including * special data (Garmin interstep links) * The result comes in meters per second and is always positive. - */ + */ double waypt_speed_ex(const waypoint *A, const waypoint *B) { - double dist, time; - - dist = waypt_distance_ex(A, B); - if (dist == 0) return 0; - - time = fabs(waypt_time(A) - waypt_time(B)); - if (time > 0) - return (dist / time); - else - return 0; + double dist, time; + + dist = waypt_distance_ex(A, B); + if (dist == 0) { + return 0; + } + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) { + return (dist / time); + } else { + return 0; + } } /* * Calculates the speed between points "A" and "B" * the result comes in meters per second and is always positive - */ + */ double waypt_speed(const waypoint *A, const waypoint *B) { - double dist, time; - - dist = waypt_distance(A, B); - if (dist == 0) return 0; - - time = fabs(waypt_time(A) - waypt_time(B)); - if (time > 0) - return (dist / time); - else - return 0; + double dist, time; + + dist = waypt_distance(A, B); + if (dist == 0) { + return 0; + } + + time = fabs(waypt_time(A) - waypt_time(B)); + if (time > 0) { + return (dist / time); + } else { + return 0; + } } /* @@ -628,26 +664,27 @@ waypt_speed(const waypoint *A, const waypoint *B) double waypt_course(const waypoint *A, const waypoint *B) { - if (A && B) - return heading_true_degrees(RAD(A->latitude), RAD(A->longitude), RAD(B->latitude), RAD(B->longitude)); - else - return 0; + if (A && B) { + return heading_true_degrees(RAD(A->latitude), RAD(A->longitude), RAD(B->latitude), RAD(B->longitude)); + } else { + return 0; + } } geocache_data * waypt_alloc_gc_data(waypoint *wpt) { - geocache_data *res = (geocache_data *)wpt->gc_data; - if (res == &empty_gc_data) { - res = xcalloc(1, sizeof(*res)); - wpt->gc_data = (const geocache_data *)res; - - } - return res; + geocache_data *res = (geocache_data *)wpt->gc_data; + if (res == &empty_gc_data) { + res = xcalloc(1, sizeof(*res)); + wpt->gc_data = (const geocache_data *)res; + + } + return res; } int waypt_empty_gc_data(const waypoint *wpt) { - return (wpt->gc_data == &empty_gc_data); + return (wpt->gc_data == &empty_gc_data); } diff --git a/gpsbabel/wbt-200.c b/gpsbabel/wbt-200.c index ab1e0d94b..7fdd4c86e 100644 --- a/gpsbabel/wbt-200.c +++ b/gpsbabel/wbt-200.c @@ -56,9 +56,9 @@ /* Flags for WBT201 */ enum { - WBT201_TRACK_START = 0x01, - WBT201_WAYPOINT = 0x02, - WBT201_OVER_SPEED = 0x04 + WBT201_TRACK_START = 0x01, + WBT201_WAYPOINT = 0x02, + WBT201_OVER_SPEED = 0x04 }; #define BUFSPEC(b) b, sizeof(b) @@ -69,11 +69,11 @@ enum { * heuristics the format matching code will have to be rejigged. */ static struct { - size_t reclen; + size_t reclen; } fmt_version[] = { - { RECLEN_V1 }, - { RECLEN_V2 }, - { 0 } + { RECLEN_V1 }, + { RECLEN_V2 }, + { 0 } }; /* Number of lines to skip while waiting for an ACK from a command. I've seen @@ -92,15 +92,15 @@ static FILE *fl; static char *port; static char *erase; -static enum { - UNKNOWN, WBT200, WBT201, WSG1000 +static enum { + UNKNOWN, WBT200, WBT201, WSG1000 } dev_type = UNKNOWN; struct buf_chunk { - struct buf_chunk *next; - size_t size; - size_t used; - /* data follows in memory */ + struct buf_chunk *next; + size_t size; + size_t used; + /* data follows in memory */ }; #define buf_CHUNK_DATA(c) \ @@ -110,364 +110,396 @@ struct buf_chunk { ((void *) ((char *) buf_CHUNK_DATA(c) + (offset))) struct buf_head { - struct buf_chunk *head; - struct buf_chunk *tail; - size_t alloc; - size_t used; - /* read position */ - struct buf_chunk *current; - unsigned long offset; - /* shoehorned in here primarily out of laziness */ - unsigned checksum; + struct buf_chunk *head; + struct buf_chunk *tail; + size_t alloc; + size_t used; + /* read position */ + struct buf_chunk *current; + unsigned long offset; + /* shoehorned in here primarily out of laziness */ + unsigned checksum; }; struct read_state { - route_head *route_head; - unsigned wpn, tpn; + route_head *route_head; + unsigned wpn, tpn; - struct buf_head data; + struct buf_head data; }; -static void db(int l, const char *msg, ...) { - va_list ap; - va_start(ap, msg); - if (global_opts.debug_level >= l) { - vprintf(msg, ap); - } - va_end(ap); +static void db(int l, const char *msg, ...) +{ + va_list ap; + va_start(ap, msg); + if (global_opts.debug_level >= l) { + vprintf(msg, ap); + } + va_end(ap); } /* Growable buffer support. TODO: Put this in a separate file and * tidy up its interface. */ -static void buf_init(struct buf_head *h, size_t alloc) { - h->head = NULL; - h->tail = NULL; - h->alloc = alloc; - h->used = 0; - h->checksum = 0; - h->offset = 0; +static void buf_init(struct buf_head *h, size_t alloc) +{ + h->head = NULL; + h->tail = NULL; + h->alloc = alloc; + h->used = 0; + h->checksum = 0; + h->offset = 0; } -static void buf_empty(struct buf_head *h) { - struct buf_chunk *chunk, *next; - for (chunk = h->head; chunk; chunk = next) { - next = chunk->next; - xfree(chunk); - } - h->head = NULL; - h->tail = NULL; - h->used = 0; - h->checksum = 0; +static void buf_empty(struct buf_head *h) +{ + struct buf_chunk *chunk, *next; + for (chunk = h->head; chunk; chunk = next) { + next = chunk->next; + xfree(chunk); + } + h->head = NULL; + h->tail = NULL; + h->used = 0; + h->checksum = 0; } -static void buf_rewind(struct buf_head *h) { - h->current = h->head; - h->offset = 0; +static void buf_rewind(struct buf_head *h) +{ + h->current = h->head; + h->offset = 0; } -static size_t buf_read(struct buf_head *h, void *data, size_t len) { - char *bp = data; - size_t got = 0; +static size_t buf_read(struct buf_head *h, void *data, size_t len) +{ + char *bp = data; + size_t got = 0; - while (len != 0 && h->current != NULL) { - size_t avail = h->current->used - h->offset; - if (avail > len) { avail = len; } + while (len != 0 && h->current != NULL) { + size_t avail = h->current->used - h->offset; + if (avail > len) { + avail = len; + } - /* Allow NULL buffer pointer to skip bytes */ - if (NULL != bp) { - memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); - bp += avail; - } + /* Allow NULL buffer pointer to skip bytes */ + if (NULL != bp) { + memcpy(bp, buf_CHUNK_PTR(h->current, h->offset), avail); + bp += avail; + } - h->offset += avail; - len -= avail; - got += avail; + h->offset += avail; + len -= avail; + got += avail; - if (h->offset == h->current->used) { - h->current = h->current->next; - h->offset = 0; - } + if (h->offset == h->current->used) { + h->current = h->current->next; + h->offset = 0; } + } - return got; + return got; } -static void buf_extend(struct buf_head *h, size_t amt) { - struct buf_chunk *c; - size_t sz = amt + sizeof(struct buf_chunk); +static void buf_extend(struct buf_head *h, size_t amt) +{ + struct buf_chunk *c; + size_t sz = amt + sizeof(struct buf_chunk); - c = xmalloc(sz); - c->next = NULL; - c->size = amt; - c->used = 0; + c = xmalloc(sz); + c->next = NULL; + c->size = amt; + c->used = 0; - if (NULL == h->head) { - h->head = c; - } else { - h->tail->next = c; - } + if (NULL == h->head) { + h->head = c; + } else { + h->tail->next = c; + } - h->tail = c; + h->tail = c; } -static void buf_update_checksum(struct buf_head *h, const void *data, size_t len) { - unsigned char *cp = (unsigned char *) data; - unsigned i; - - db(4, "Updating checksum with %p, %lu, before: %02x ", - data, (unsigned long) len, h->checksum); - for (i = 0; i < len; i++) { - h->checksum ^= cp[i]; - } - db(4, "after: %02x\n", h->checksum); +static void buf_update_checksum(struct buf_head *h, const void *data, size_t len) +{ + unsigned char *cp = (unsigned char *) data; + unsigned i; + + db(4, "Updating checksum with %p, %lu, before: %02x ", + data, (unsigned long) len, h->checksum); + for (i = 0; i < len; i++) { + h->checksum ^= cp[i]; + } + db(4, "after: %02x\n", h->checksum); } -static void buf_write(struct buf_head *h, const void *data, size_t len) { - size_t avail; - const char *bp = data; - - buf_update_checksum(h, data, len); +static void buf_write(struct buf_head *h, const void *data, size_t len) +{ + size_t avail; + const char *bp = data; - h->used += len; + buf_update_checksum(h, data, len); - if (NULL == h->tail) { - buf_extend(h, h->alloc); - } + h->used += len; - for (;;) { - avail = h->tail->size - h->tail->used; - if (avail > len) { avail = len; } + if (NULL == h->tail) { + buf_extend(h, h->alloc); + } - memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); - h->tail->used += avail; - bp += avail; - len -= avail; - if (len == 0) { - break; - } - buf_extend(h, h->alloc); + for (;;) { + avail = h->tail->size - h->tail->used; + if (avail > len) { + avail = len; } -} -static void rd_drain() { - if (gbser_flush(fd)) { - fatal(MYNAME ": Comm error\n"); + memcpy((char *) buf_CHUNK_PTR(h->tail, h->tail->used), bp, avail); + h->tail->used += avail; + bp += avail; + len -= avail; + if (len == 0) { + break; } + buf_extend(h, h->alloc); + } } -static void rd_line(char *buf, int len) { - int rc; - if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { - fatal(MYNAME ": Read error (%d)\n", rc); - } - db(3, "Got response: \"%s\"\n", buf); +static void rd_drain() +{ + if (gbser_flush(fd)) { + fatal(MYNAME ": Comm error\n"); + } } -static void wr_cmd(const char *cmd) { - int rc; - db(3, "Sending: %s\n", cmd); - if (rc = gbser_print(fd, cmd), gbser_OK != rc) { - fatal(MYNAME ": Write error (%d)\n", rc); - } +static void rd_line(char *buf, int len) +{ + int rc; + if (rc = gbser_read_line(fd, buf, len, TIMEOUT, 0x0A, 0x0D), rc != gbser_OK) { + fatal(MYNAME ": Read error (%d)\n", rc); + } + db(3, "Got response: \"%s\"\n", buf); } -static void wr_cmdl(const char *cmd) { - wr_cmd(cmd); - wr_cmd(NL); +static void wr_cmd(const char *cmd) +{ + int rc; + db(3, "Sending: %s\n", cmd); + if (rc = gbser_print(fd, cmd), gbser_OK != rc) { + fatal(MYNAME ": Write error (%d)\n", rc); + } } -static int expect(const char *str) { - int state = 0; - int c, i; - int errors = 5; /* allow this many errors */ - - for (i = 0; i < 5000; i++) { - /* reached end of string */ - if (str[state] == '\0') { - return 1; - } - - c = gbser_readc_wait(fd, 500); - if (c < 0) { - db(3, "Got error: %d\n", c); - if (--errors <= 0) { - return 0; - } - } else { - db(3, "Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); - if (c == str[state]) { - state++; /* carry on */ - } else { - state = 0; /* go back to start */ - } - } - } - - return 0; +static void wr_cmdl(const char *cmd) +{ + wr_cmd(cmd); + wr_cmd(NL); } -static int wbt200_try() { - int rc; +static int expect(const char *str) +{ + int state = 0; + int c, i; + int errors = 5; /* allow this many errors */ - db(1, "Trying WBT100/200\n"); + for (i = 0; i < 5000; i++) { + /* reached end of string */ + if (str[state] == '\0') { + return 1; + } - if ((rc = gbser_set_port(fd, WBT200BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT200BAUD, rc); + c = gbser_readc_wait(fd, 500); + if (c < 0) { + db(3, "Got error: %d\n", c); + if (--errors <= 0) { return 0; + } + } else { + db(3, "Got char: %02x '%c'\n", c, isprint(c) ? c : '.'); + if (c == str[state]) { + state++; /* carry on */ + } else { + state = 0; /* go back to start */ + } } + } - wr_cmdl("$PFST,NORMAL"); - return expect("$PFST"); + return 0; } -static int wbt201_try() { - int rc; - - db(1, "Trying WBT201/G-Rays 2\n"); +static int wbt200_try() +{ + int rc; - if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); - return 0; - } - - wr_cmdl("@AL"); - return expect("@AL"); + db(1, "Trying WBT100/200\n"); + + if ((rc = gbser_set_port(fd, WBT200BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT200BAUD, rc); + return 0; + } + + wr_cmdl("$PFST,NORMAL"); + return expect("$PFST"); } -static int wsg1000_try() { - int rc; +static int wbt201_try() +{ + int rc; - db(1, "Trying WSG 1000/G-Rays 2\n"); + db(1, "Trying WBT201/G-Rays 2\n"); - if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { - db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); - return 0; - } - - wr_cmdl("@AL,2,3"); - return expect("@AL,2,3,OK"); -} + if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); + return 0; + } -static int guess_device() { - int i; - db(1, "Guessing device...\n"); - for (i = 0; i < 5; i++) { - if (wbt200_try()) { - return WBT200; - } - if (wbt201_try()) { - return WBT201; - } - if (wsg1000_try()) { - return WSG1000; - } - } - return UNKNOWN; - + wr_cmdl("@AL"); + return expect("@AL"); } -static void rd_init(const char *fname) { - port = xstrdup(fname); +static int wsg1000_try() +{ + int rc; - db(1, "Opening port...\n"); - if ((fd = gbser_init(port)) == NULL) { - fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + db(1, "Trying WSG 1000/G-Rays 2\n"); + + if ((rc = gbser_set_port(fd, WBT201BAUD, 8, 0, 1))) { + db(1, "Set baud rate to %d failed (%d)\n", WBT201BAUD, rc); + return 0; + } + + wr_cmdl("@AL,2,3"); + return expect("@AL,2,3,OK"); +} + +static int guess_device() +{ + int i; + db(1, "Guessing device...\n"); + for (i = 0; i < 5; i++) { + if (wbt200_try()) { + return WBT200; + } + if (wbt201_try()) { + return WBT201; } - - dev_type = guess_device(); - if (UNKNOWN == dev_type) { - fatal(MYNAME ": Can't determine device type\n"); + if (wsg1000_try()) { + return WSG1000; } + } + return UNKNOWN; + } -static void rd_deinit(void) { - db(1, "Closing port...\n"); - gbser_deinit(fd); - fd = NULL; - xfree(port); +static void rd_init(const char *fname) +{ + port = xstrdup(fname); + + db(1, "Opening port...\n"); + if ((fd = gbser_init(port)) == NULL) { + fatal(MYNAME ": Can't initialise port \"%s\"\n", port); + } + + dev_type = guess_device(); + if (UNKNOWN == dev_type) { + fatal(MYNAME ": Can't determine device type\n"); + } } -static int rd_buf(void *buf, int len) { - int rc; - if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { - fatal(MYNAME ": Read error (%d)\n", rc); - } else if (rc < len) { - db(2, MYNAME ": Read timout, got %i of %i bytes\n", rc, len); - return 0; - } - return 1; +static void rd_deinit(void) +{ + db(1, "Closing port...\n"); + gbser_deinit(fd); + fd = NULL; + xfree(port); } -static void file_init(const char *fname) { - db(1, "Opening file...\n"); - if ((fl = fopen(fname, "rb")) == NULL) { - fatal(MYNAME ": Can't open file '%s'\n", fname); - } +static int rd_buf(void *buf, int len) +{ + int rc; + if (rc = gbser_read_wait(fd, buf, len, TIMEOUT), rc < 0) { + fatal(MYNAME ": Read error (%d)\n", rc); + } else if (rc < len) { + db(2, MYNAME ": Read timout, got %i of %i bytes\n", rc, len); + return 0; + } + return 1; +} + +static void file_init(const char *fname) +{ + db(1, "Opening file...\n"); + if ((fl = fopen(fname, "rb")) == NULL) { + fatal(MYNAME ": Can't open file '%s'\n", fname); + } } -static void file_deinit(void) { - db(1, "Closing file...\n"); - fclose(fl); +static void file_deinit(void) +{ + db(1, "Closing file...\n"); + fclose(fl); } -static int starts_with(const char *buf, const char *pat) { - size_t pat_len = strlen(pat); - return (pat_len <= strlen(buf)) - ? (memcmp(buf, pat, pat_len) == 0) - : 0; +static int starts_with(const char *buf, const char *pat) +{ + size_t pat_len = strlen(pat); + return (pat_len <= strlen(buf)) + ? (memcmp(buf, pat, pat_len) == 0) + : 0; } /* Send a command then wait for a line starting with the command string * to be returned. */ -static int do_cmd(const char *cmd, const char *expect, char *buf, int len) { - int try; - - rd_drain(); - wr_cmdl(cmd); - - db(2, "Cmd: %s\n", cmd); - - /* We may need to skip a load of data to start with - the unit streams - * NMEA data all the time so it's highly likely that it'll be in the - * middle of an NMEA sentence when we start listening. - */ - for (try = 0; try < RETRIES; try++) { - rd_line(buf, len); - db(3, "Got: %s\n", buf); - if (starts_with(buf, expect)) { +static int do_cmd(const char *cmd, const char *expect, char *buf, int len) +{ + int try; + + rd_drain(); + wr_cmdl(cmd); + + db(2, "Cmd: %s\n", cmd); + + /* We may need to skip a load of data to start with - the unit streams + * NMEA data all the time so it's highly likely that it'll be in the + * middle of an NMEA sentence when we start listening. + */ + for (try = 0; try < RETRIES; try++) { + rd_line(buf, len); + db(3, "Got: %s\n", buf); + if (starts_with(buf, expect)) { db(2, "Matched: %s\n", buf); return strlen(expect); + } + db(2, "Skip %d: %s\n", try, buf); } - db(2, "Skip %d: %s\n", try, buf); - } - fatal(MYNAME ": Bad response from unit\n"); - return 0; /* keep compiler quiet */ + fatal(MYNAME ": Bad response from unit\n"); + return 0; /* keep compiler quiet */ } /* Issue a command that expects the same string to be echoed * back as an ACK */ -static int do_simple(const char *cmd, char *buf, int len) { - return do_cmd(cmd, cmd, buf, len); +static int do_simple(const char *cmd, char *buf, int len) +{ + return do_cmd(cmd, cmd, buf, len); } -static char *get_param(const char *cmd, char *buf, int len) { - int cl = do_simple(cmd, buf, len); - return buf + cl + 1; +static char *get_param(const char *cmd, char *buf, int len) +{ + int cl = do_simple(cmd, buf, len); + return buf + cl + 1; } -static int get_param_int(const char *cmd) { - char buf[80]; - return atoi(get_param(cmd, buf, sizeof(buf))); +static int get_param_int(const char *cmd) +{ + char buf[80]; + return atoi(get_param(cmd, buf, sizeof(buf))); } -static double get_param_float(const char *cmd) { - char buf[80]; - return atof(get_param(cmd, buf, sizeof(buf))); +static double get_param_float(const char *cmd) +{ + char buf[80]; + return atof(get_param(cmd, buf, sizeof(buf))); } /* Decompose binary date into discreet fields */ @@ -479,597 +511,620 @@ static double get_param_float(const char *cmd) { int mon = (((tim) >> 22) & 0x0F); \ int year = (((tim) >> 26) & 0x3F); -static time_t decode_date(gbuint32 tim) { - _SPLIT_DATE(tim) - struct tm t; +static time_t decode_date(gbuint32 tim) +{ + _SPLIT_DATE(tim) + struct tm t; - t.tm_sec = sec; - t.tm_min = min; - t.tm_hour = hour; - t.tm_mday = mday; - t.tm_mon = mon - 1; - t.tm_year = year + 100; + t.tm_sec = sec; + t.tm_min = min; + t.tm_hour = hour; + t.tm_mday = mday; + t.tm_mon = mon - 1; + t.tm_year = year + 100; - return mkgmtime(&t); + return mkgmtime(&t); } -static int check_date(gbuint32 tim) { - _SPLIT_DATE(tim) +static int check_date(gbuint32 tim) +{ + _SPLIT_DATE(tim) - /* Sanity check the date. We don't allow years prior to 2004 because zero in - * those bits will usually indicate that we have an altitude instead of a - * date (i.e. that the data is the new format that uses 16 byte records). - */ - return sec < 60 && min < 60 && hour < 24 && - mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; + /* Sanity check the date. We don't allow years prior to 2004 because zero in + * those bits will usually indicate that we have an altitude instead of a + * date (i.e. that the data is the new format that uses 16 byte records). + */ + return sec < 60 && min < 60 && hour < 24 && + mday > 0 && mday <= 31 && mon > 0 && mon <= 12 && year >= 4; } -static waypoint *make_point(double lat, double lon, double alt, time_t tim, const char *fmt, int index) { - char wp_name[20]; - waypoint *wpt = waypt_new(); +static waypoint *make_point(double lat, double lon, double alt, time_t tim, const char *fmt, int index) +{ + char wp_name[20]; + waypoint *wpt = waypt_new(); - sprintf(wp_name, fmt, index); + sprintf(wp_name, fmt, index); - wpt->latitude = lat;; - wpt->longitude = lon; - wpt->altitude = alt; - wpt->creation_time = tim; - wpt->shortname = xstrdup(wp_name); - - return wpt; -} + wpt->latitude = lat;; + wpt->longitude = lon; + wpt->altitude = alt; + wpt->creation_time = tim; + wpt->shortname = xstrdup(wp_name); -static waypoint *make_waypoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { - return make_point(lat, lon, alt, tim, "WP%04d", ++st->wpn); + return wpt; } -static waypoint *make_trackpoint(struct read_state *st, double lat, double lon, double alt, time_t tim) { - return make_point(lat, lon, alt, tim, "TP%04d", ++st->tpn); +static waypoint *make_waypoint(struct read_state *st, double lat, double lon, double alt, time_t tim) +{ + return make_point(lat, lon, alt, tim, "WP%04d", ++st->wpn); } -static int wbt200_data_chunk(struct read_state *st, const void *buf, int fmt) { - gbuint32 tim; - double lat, lon, alt; - time_t rtim; - waypoint *tpt = NULL; - const char *bp = buf; - size_t buf_used = fmt_version[fmt].reclen; - - tim = le_read32(bp + 0); - - lat = (double) ((gbint32) le_read32(bp + 4)) / 10000000; - lon = (double) ((gbint32) le_read32(bp + 8)) / 10000000; - - /* Handle extra fields in longer records here. */ - if (buf_used >= 16) { - alt = (double) le_read32(bp + 12) / 10; - } else { - alt = unknown_alt; - } - - rtim = decode_date(tim); - - if (lat >= 100) { - /* Start new track in the northern hemisphere */ - lat -= 100; - st->route_head = NULL; - } else if (lat <= -100) { - /* Start new track in the southern hemisphere */ - /* This fix courtesy of Anton Frolich */ - lat += 100; - st->route_head = NULL; - } - - tpt = make_trackpoint(st, lat, lon, alt, rtim); - - if (NULL == st->route_head) { - db(1, "New Track\n"); - st->route_head = route_head_alloc(); - track_add_head(st->route_head); - } - - track_add_wpt(st->route_head, tpt); +static waypoint *make_trackpoint(struct read_state *st, double lat, double lon, double alt, time_t tim) +{ + return make_point(lat, lon, alt, tim, "TP%04d", ++st->tpn); +} - return 1; +static int wbt200_data_chunk(struct read_state *st, const void *buf, int fmt) +{ + gbuint32 tim; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = buf; + size_t buf_used = fmt_version[fmt].reclen; + + tim = le_read32(bp + 0); + + lat = (double)((gbint32) le_read32(bp + 4)) / 10000000; + lon = (double)((gbint32) le_read32(bp + 8)) / 10000000; + + /* Handle extra fields in longer records here. */ + if (buf_used >= 16) { + alt = (double) le_read32(bp + 12) / 10; + } else { + alt = unknown_alt; + } + + rtim = decode_date(tim); + + if (lat >= 100) { + /* Start new track in the northern hemisphere */ + lat -= 100; + st->route_head = NULL; + } else if (lat <= -100) { + /* Start new track in the southern hemisphere */ + /* This fix courtesy of Anton Frolich */ + lat += 100; + st->route_head = NULL; + } + + tpt = make_trackpoint(st, lat, lon, alt, rtim); + + if (NULL == st->route_head) { + db(1, "New Track\n"); + st->route_head = route_head_alloc(); + track_add_head(st->route_head); + } + + track_add_wpt(st->route_head, tpt); + + return 1; } /* Return true iff the data appears valid with the specified record length */ -static int is_valid(struct buf_head *h, int fmt) { - char buf[RECLEN_MAX]; - size_t reclen = fmt_version[fmt].reclen; +static int is_valid(struct buf_head *h, int fmt) +{ + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; - buf_rewind(h); + buf_rewind(h); - db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); + db(2, "Checking %lu bytes of data against format %d\n", h->used, fmt); - for (;;) { - size_t got = buf_read(h, buf, reclen); - gbuint32 tim; - /* Don't mind odd bytes at the end - we may - * be examining an incomplete dataset. - */ - if (got != reclen) { - break; - } + for (;;) { + size_t got = buf_read(h, buf, reclen); + gbuint32 tim; + /* Don't mind odd bytes at the end - we may + * be examining an incomplete dataset. + */ + if (got != reclen) { + break; + } - tim = le_read32(buf + 0); - if (!check_date(tim)) { - return 0; - } + tim = le_read32(buf + 0); + if (!check_date(tim)) { + return 0; + } - if (reclen > 12) { + if (reclen > 12) { #ifdef MAXALT - gbuint32 alt = le_read32(buf + 12); - if (alt > MAXALT * 10) { - return 0; - } + gbuint32 alt = le_read32(buf + 12); + if (alt > MAXALT * 10) { + return 0; + } #endif - } } + } - return 1; + return 1; } -static void wbt200_process_data(struct read_state *pst, int fmt) { - char buf[RECLEN_MAX]; - size_t reclen = fmt_version[fmt].reclen; +static void wbt200_process_data(struct read_state *pst, int fmt) +{ + char buf[RECLEN_MAX]; + size_t reclen = fmt_version[fmt].reclen; - buf_rewind(&pst->data); + buf_rewind(&pst->data); - db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); + db(2, "Processing %lu bytes of data using format %d\n", pst->data.used, fmt); - for (;;) { - size_t got = buf_read(&pst->data, buf, reclen); - if (got != reclen) { - break; - } - wbt200_data_chunk(pst, buf, fmt); + for (;;) { + size_t got = buf_read(&pst->data, buf, reclen); + if (got != reclen) { + break; } + wbt200_data_chunk(pst, buf, fmt); + } } -static void state_init(struct read_state *pst) { - pst->route_head = NULL; - pst->wpn = 0; - pst->tpn = 0; +static void state_init(struct read_state *pst) +{ + pst->route_head = NULL; + pst->wpn = 0; + pst->tpn = 0; - buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); + buf_init(&pst->data, RECLEN_V1 * RECLEN_V2); } -static void state_empty(struct read_state *pst) { - buf_empty(&pst->data); - state_init(pst); +static void state_empty(struct read_state *pst) +{ + buf_empty(&pst->data); + state_init(pst); } -static int want_bytes(struct buf_head *h, size_t len) { - char buf[512]; +static int want_bytes(struct buf_head *h, size_t len) +{ + char buf[512]; - db(3, "Reading %lu bytes from device\n", (unsigned long) len); + db(3, "Reading %lu bytes from device\n", (unsigned long) len); - while (len > 0) { - size_t want = sizeof(buf); - if (want > len) { want = len; } - if (!rd_buf(buf, want)) - return 0; - buf_write(h, buf, want); - len -= want; + while (len > 0) { + size_t want = sizeof(buf); + if (want > len) { + want = len; } - return 1; + if (!rd_buf(buf, want)) { + return 0; + } + buf_write(h, buf, want); + len -= want; + } + return 1; } -static void wbt200_data_read(void) { - /* Awooga! Awooga! Statically allocated buffer danger! - * Actually, it's OK because rd_line can read arbitrarily - * long lines returning only the first N characters - */ - char line_buf[100]; - int fmt; - unsigned long count; - struct read_state st; - - state_init(&st); - - /* We could potentially parse the version string to find out which - * data format to use - but it's not clear how the version string - * will increment in the future - so just now it's more future- - * proof to rely on analysing the data. We need to be able to do - * that with files anyway - because they're not versioned. - */ - do_simple("$PFST,FIRMWAREVERSION", BUFSPEC(line_buf)); - - do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); - do_simple("$PFST,READLOGGER", BUFSPEC(line_buf)); +static void wbt200_data_read(void) +{ + /* Awooga! Awooga! Statically allocated buffer danger! + * Actually, it's OK because rd_line can read arbitrarily + * long lines returning only the first N characters + */ + char line_buf[100]; + int fmt; + unsigned long count; + struct read_state st; + + state_init(&st); + + /* We could potentially parse the version string to find out which + * data format to use - but it's not clear how the version string + * will increment in the future - so just now it's more future- + * proof to rely on analysing the data. We need to be able to do + * that with files anyway - because they're not versioned. + */ + do_simple("$PFST,FIRMWAREVERSION", BUFSPEC(line_buf)); + + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + do_simple("$PFST,READLOGGER", BUFSPEC(line_buf)); + + /* Now we're into binary mode */ + rd_buf(line_buf, 6); /* six byte header */ + count = le_read16(line_buf + 2) + 1; + if (count == 0x10000) { + count = 0; + } + + db(3, "%lu points available\n", count); + + /* Loop through the known formats requesting more data from the + * device each time. When the device contains only a single + * point the first format will get a false positive - so we'll + * lose the altitude data. + */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + size_t want = reclen * count; - /* Now we're into binary mode */ - rd_buf(line_buf, 6); /* six byte header */ - count = le_read16(line_buf + 2) + 1; - if (count == 0x10000) { - count = 0; + if (want < st.data.used) { + fatal(MYNAME ": Internal error: formats not ordered in ascending size order\n"); } - db(3, "%lu points available\n", count); + db(3, "Want %lu bytes of data\n", (unsigned long) want); - /* Loop through the known formats requesting more data from the - * device each time. When the device contains only a single - * point the first format will get a false positive - so we'll - * lose the altitude data. - */ - for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { - size_t reclen = fmt_version[fmt].reclen; - size_t want = reclen * count; - - if (want < st.data.used) { - fatal(MYNAME ": Internal error: formats not ordered in ascending size order\n"); - } - - db(3, "Want %lu bytes of data\n", (unsigned long) want); + /* Top up the buffer */ + want_bytes(&st.data, want - st.data.used); - /* Top up the buffer */ - want_bytes(&st.data, want - st.data.used); - - /* And see if it's valid */ - if (is_valid(&st.data, fmt)) { - break; - } + /* And see if it's valid */ + if (is_valid(&st.data, fmt)) { + break; } + } - if (fmt_version[fmt].reclen == 0) { - fatal(MYNAME ": Can't autodetect data format\n"); - } + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); + } - wbt200_process_data(&st, fmt); + wbt200_process_data(&st, fmt); - /* Erase data? */ + /* Erase data? */ - if (*erase != '0') { - int f; - db(1, "Erasing data\n"); - for (f = 27; f <= 31; f++) { - sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); - do_cmd(line_buf, "$PFST,REMOVEFILE", BUFSPEC(line_buf)); - } - db(1, "Reclaiming free space\n"); - for (f = 0; f <= 3; f++) { - sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); - do_cmd(line_buf, "$PFST,FFSRECLAIM", BUFSPEC(line_buf)); - } + if (*erase != '0') { + int f; + db(1, "Erasing data\n"); + for (f = 27; f <= 31; f++) { + sprintf(line_buf, "$PFST,REMOVEFILE,%d", f); + do_cmd(line_buf, "$PFST,REMOVEFILE", BUFSPEC(line_buf)); } + db(1, "Reclaiming free space\n"); + for (f = 0; f <= 3; f++) { + sprintf(line_buf, "$PFST,FFSRECLAIM,%d", f); + do_cmd(line_buf, "$PFST,FFSRECLAIM", BUFSPEC(line_buf)); + } + } - do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); + do_simple("$PFST,NORMAL", BUFSPEC(line_buf)); - state_empty(&st); + state_empty(&st); } -static int all_null(const void *buf, const int len) { - const char *bp = buf; - int i; +static int all_null(const void *buf, const int len) +{ + const char *bp = buf; + int i; - for (i = 0; i < len; i++) { - if (bp[i]) { - return 0; - } + for (i = 0; i < len; i++) { + if (bp[i]) { + return 0; } + } - return 1; + return 1; } -static int wbt201_data_chunk(struct read_state *st, const void *buf) { - gbuint32 tim; - gbuint16 flags; - double lat, lon, alt; - time_t rtim; - waypoint *tpt = NULL; - const char *bp = buf; - - /* Zero records are skipped */ - if (all_null(buf, RECLEN_WBT201)) { - return 1; - } - - flags = le_read16(bp + 0); - tim = le_read32(bp + 2); +static int wbt201_data_chunk(struct read_state *st, const void *buf) +{ + gbuint32 tim; + gbuint16 flags; + double lat, lon, alt; + time_t rtim; + waypoint *tpt = NULL; + const char *bp = buf; + + /* Zero records are skipped */ + if (all_null(buf, RECLEN_WBT201)) { + return 1; + } - if (TK1_END_FLAG == tim) { - /* EOF? (TK1 files only as far as I know) */ - return 0; - } + flags = le_read16(bp + 0); + tim = le_read32(bp + 2); - lat = (double) ((gbint32) le_read32(bp + 6)) / 10000000; - lon = (double) ((gbint32) le_read32(bp + 10)) / 10000000; - alt = (double) ((gbint16) le_read16(bp + 14)); + if (TK1_END_FLAG == tim) { + /* EOF? (TK1 files only as far as I know) */ + return 0; + } - rtim = decode_date(tim); + lat = (double)((gbint32) le_read32(bp + 6)) / 10000000; + lon = (double)((gbint32) le_read32(bp + 10)) / 10000000; + alt = (double)((gbint16) le_read16(bp + 14)); - if ((flags & WBT201_WAYPOINT) && (global_opts.masked_objective & WPTDATAMASK)) { - waypoint *wpt = make_waypoint(st, lat, lon, alt, rtim); - waypt_add(wpt); - } + rtim = decode_date(tim); - if (global_opts.masked_objective & TRKDATAMASK) { - if (flags & WBT201_TRACK_START) { - st->route_head = NULL; - } + if ((flags & WBT201_WAYPOINT) && (global_opts.masked_objective & WPTDATAMASK)) { + waypoint *wpt = make_waypoint(st, lat, lon, alt, rtim); + waypt_add(wpt); + } - tpt = make_trackpoint(st, lat, lon, alt, rtim); + if (global_opts.masked_objective & TRKDATAMASK) { + if (flags & WBT201_TRACK_START) { + st->route_head = NULL; + } - if (NULL == st->route_head) { - db(1, "New Track\n"); - st->route_head = route_head_alloc(); - track_add_head(st->route_head); - } + tpt = make_trackpoint(st, lat, lon, alt, rtim); - track_add_wpt(st->route_head, tpt); + if (NULL == st->route_head) { + db(1, "New Track\n"); + st->route_head = route_head_alloc(); + track_add_head(st->route_head); } - return 1; + track_add_wpt(st->route_head, tpt); + } + + return 1; } -static void wbt201_process_chunk(struct read_state *st) { - char buf[RECLEN_WBT201]; +static void wbt201_process_chunk(struct read_state *st) +{ + char buf[RECLEN_WBT201]; - db(2, "Processing %lu bytes of data\n", st->data.used); + db(2, "Processing %lu bytes of data\n", st->data.used); - while (buf_read(&st->data, buf, sizeof(buf)) == sizeof(buf) - && wbt201_data_chunk(st, buf)) { - /* do nothing */ - } + while (buf_read(&st->data, buf, sizeof(buf)) == sizeof(buf) + && wbt201_data_chunk(st, buf)) { + /* do nothing */ + } } -static int wbt201_read_chunk(struct read_state *st, unsigned pos, unsigned limit) { - char cmd_buf[30]; - char line_buf[100]; - unsigned long cs; - char *lp, *op; - static char *cs_prefix = "@AL,CS,"; +static int wbt201_read_chunk(struct read_state *st, unsigned pos, unsigned limit) +{ + char cmd_buf[30]; + char line_buf[100]; + unsigned long cs; + char *lp, *op; + static char *cs_prefix = "@AL,CS,"; - unsigned want = limit - pos; - if (want > WBT201CHUNK) { - want = WBT201CHUNK; - } + unsigned want = limit - pos; + if (want > WBT201CHUNK) { + want = WBT201CHUNK; + } - db(3, "Reading bytes at %u (0x%x), limit = %u (0x%x), want = %u (0x%x)\n", - pos, pos, limit, limit, want, want); + db(3, "Reading bytes at %u (0x%x), limit = %u (0x%x), want = %u (0x%x)\n", + pos, pos, limit, limit, want, want); - buf_empty(&st->data); + buf_empty(&st->data); - rd_drain(); - sprintf(cmd_buf, "@AL,5,3,%d", pos); - wr_cmdl(cmd_buf); + rd_drain(); + sprintf(cmd_buf, "@AL,5,3,%d", pos); + wr_cmdl(cmd_buf); - - if (!want_bytes(&st->data, want)) - return 0; - /* checksum */ - rd_line(BUFSPEC(line_buf)); + if (!want_bytes(&st->data, want)) { + return 0; + } - if (!starts_with(line_buf, cs_prefix)) { - db(2, "Bad checksum response\n"); - return 0; - } + /* checksum */ + rd_line(BUFSPEC(line_buf)); - lp = line_buf + strlen(cs_prefix); - cs = strtoul(lp, &op, 16); - if (*lp == ',' || *op != ',') { - db(2, "Badly formed checksum\n"); - return 0; - } + if (!starts_with(line_buf, cs_prefix)) { + db(2, "Bad checksum response\n"); + return 0; + } - if (cs != st->data.checksum) { - db(2, "Checksums don't match. Got %02x, expected %02\n", cs, st->data.checksum); - return 0; - } - - /* ack */ -/* rd_line(BUFSPEC(line_buf)); + lp = line_buf + strlen(cs_prefix); + cs = strtoul(lp, &op, 16); + if (*lp == ',' || *op != ',') { + db(2, "Badly formed checksum\n"); + return 0; + } + + if (cs != st->data.checksum) { + db(2, "Checksums don't match. Got %02x, expected %02\n", cs, st->data.checksum); + return 0; + } + + /* ack */ + /* rd_line(BUFSPEC(line_buf)); + return starts_with(line_buf, cmd_buf); + */ + if (dev_type == WBT201) { + rd_line(BUFSPEC(line_buf)); return starts_with(line_buf, cmd_buf); -*/ - if (dev_type == WBT201){ - rd_line(BUFSPEC(line_buf)); - return starts_with(line_buf, cmd_buf); - } - return 1; - + } + return 1; + } -static void wbt201_data_read(void) { - char line_buf[100]; - struct read_state st; - unsigned tries; - - const char *tmp; - - double ver_hw; - double ver_sw; - double ver_fmt; - - unsigned log_addr_start; - unsigned log_addr_end; - unsigned log_area_start; - unsigned log_area_end; - - unsigned wantbytes; - unsigned read_pointer; - unsigned read_limit; - - /* Read various device information. We don't use much of this yet - - * just log_addr_start and log_addr_end - but it's useful to have it - * here for debug and documentation purposes. - */ - tmp = get_param("@AL,7,1", BUFSPEC(line_buf)); - db(1, "Reading device \"%s\"\n", tmp); - - ver_hw = get_param_float("@AL,8,1"); - ver_sw = get_param_float("@AL,8,2"); - ver_fmt = get_param_float("@AL,8,3"); - - db(2, "versions: hw=%f, sw=%f, fmt=%f\n", - ver_hw, ver_sw, ver_fmt); - - log_addr_start = get_param_int("@AL,5,1"); /* we read from here... */ - log_addr_end = get_param_int("@AL,5,2"); /* ...to here, but ... */ - log_area_start = get_param_int("@AL,5,9"); /* ...we need these when ... */ - log_area_end = get_param_int("@AL,5,10"); /* ...the gps wrote more then it fits in memory */ - - db(2, "Log addr=(%d..%d), area=(%d..%d)\n", - log_addr_start, log_addr_end, - log_area_start, log_area_end); - - state_init(&st); - - tries = 10; - - /* If the WBT-201 device logs more then the memory can handle it continues to write at the beginning of the memory, - * thus overwriting the oldest tracks. In this case log_addr_end is smaller then log_addr_start and we need to read - * from log_addr_start to log_area_end and then from log_area_start to log_addr_end. - */ - - wantbytes = (log_addr_start < log_addr_end) ? log_addr_end - log_addr_start : log_area_end - (log_addr_start - log_addr_end); - read_pointer = log_addr_start; - read_limit = (log_addr_start < log_addr_end) ? log_addr_end : log_area_end; - - db(2, "Want %d bytes from device\n", wantbytes); - while (wantbytes > 0) { - db(2, "Read params: Want %d bytes, read_pointer = %d, read_limit = %d\n", wantbytes, read_pointer, read_limit); - if (wbt201_read_chunk(&st, read_pointer, read_limit)) { - buf_rewind(&st.data); - wbt201_process_chunk(&st); - wantbytes -= st.data.used; - read_pointer += st.data.used; - if (read_pointer >= log_area_end) - { - read_pointer = log_area_start; - read_limit = log_addr_end; - } - } else { - if (--tries <= 0) { - fatal(MYNAME ": Too many data errors during read\n"); - } - } +static void wbt201_data_read(void) +{ + char line_buf[100]; + struct read_state st; + unsigned tries; + + const char *tmp; + + double ver_hw; + double ver_sw; + double ver_fmt; + + unsigned log_addr_start; + unsigned log_addr_end; + unsigned log_area_start; + unsigned log_area_end; + + unsigned wantbytes; + unsigned read_pointer; + unsigned read_limit; + + /* Read various device information. We don't use much of this yet - + * just log_addr_start and log_addr_end - but it's useful to have it + * here for debug and documentation purposes. + */ + tmp = get_param("@AL,7,1", BUFSPEC(line_buf)); + db(1, "Reading device \"%s\"\n", tmp); + + ver_hw = get_param_float("@AL,8,1"); + ver_sw = get_param_float("@AL,8,2"); + ver_fmt = get_param_float("@AL,8,3"); + + db(2, "versions: hw=%f, sw=%f, fmt=%f\n", + ver_hw, ver_sw, ver_fmt); + + log_addr_start = get_param_int("@AL,5,1"); /* we read from here... */ + log_addr_end = get_param_int("@AL,5,2"); /* ...to here, but ... */ + log_area_start = get_param_int("@AL,5,9"); /* ...we need these when ... */ + log_area_end = get_param_int("@AL,5,10"); /* ...the gps wrote more then it fits in memory */ + + db(2, "Log addr=(%d..%d), area=(%d..%d)\n", + log_addr_start, log_addr_end, + log_area_start, log_area_end); + + state_init(&st); + + tries = 10; + + /* If the WBT-201 device logs more then the memory can handle it continues to write at the beginning of the memory, + * thus overwriting the oldest tracks. In this case log_addr_end is smaller then log_addr_start and we need to read + * from log_addr_start to log_area_end and then from log_area_start to log_addr_end. + */ + + wantbytes = (log_addr_start < log_addr_end) ? log_addr_end - log_addr_start : log_area_end - (log_addr_start - log_addr_end); + read_pointer = log_addr_start; + read_limit = (log_addr_start < log_addr_end) ? log_addr_end : log_area_end; + + db(2, "Want %d bytes from device\n", wantbytes); + while (wantbytes > 0) { + db(2, "Read params: Want %d bytes, read_pointer = %d, read_limit = %d\n", wantbytes, read_pointer, read_limit); + if (wbt201_read_chunk(&st, read_pointer, read_limit)) { + buf_rewind(&st.data); + wbt201_process_chunk(&st); + wantbytes -= st.data.used; + read_pointer += st.data.used; + if (read_pointer >= log_area_end) { + read_pointer = log_area_start; + read_limit = log_addr_end; + } + } else { + if (--tries <= 0) { + fatal(MYNAME ": Too many data errors during read\n"); + } } + } - if (*erase != '0') { - /* erase device */ - do_simple("@AL,5,6", BUFSPEC(line_buf)); - } + if (*erase != '0') { + /* erase device */ + do_simple("@AL,5,6", BUFSPEC(line_buf)); + } - state_empty(&st); - do_simple("@AL,2,1", BUFSPEC(line_buf)); + state_empty(&st); + do_simple("@AL,2,1", BUFSPEC(line_buf)); } -static void file_read(void) { - char buf[512]; - size_t rc; - struct read_state st; - int fmt; +static void file_read(void) +{ + char buf[512]; + size_t rc; + struct read_state st; + int fmt; - const char * tk1_magic = TK1_MAGIC; - size_t tk1_magic_len = strlen(tk1_magic) + 1; + const char * tk1_magic = TK1_MAGIC; + size_t tk1_magic_len = strlen(tk1_magic) + 1; - state_init(&st); + state_init(&st); - /* Read the whole file into the buffer */ + /* Read the whole file into the buffer */ + rc = fread(buf, 1, sizeof(buf), fl); + while (rc != 0) { + buf_write(&st.data, buf, rc); rc = fread(buf, 1, sizeof(buf), fl); - while (rc != 0) { - buf_write(&st.data, buf, rc); - rc = fread(buf, 1, sizeof(buf), fl); - } + } - if (!feof(fl)) { - fatal(MYNAME ": Read error\n"); - } + if (!feof(fl)) { + fatal(MYNAME ": Read error\n"); + } - /* Although wbt-tk1 and wbt-bin are enumerated as distinct formats - * we handle them both here and autodetect which type we have. - */ + /* Although wbt-tk1 and wbt-bin are enumerated as distinct formats + * we handle them both here and autodetect which type we have. + */ - /* WBT201 TK1 format? */ + /* WBT201 TK1 format? */ + buf_rewind(&st.data); + buf_read(&st.data, buf, tk1_magic_len); + if (memcmp(buf, tk1_magic, tk1_magic_len) == 0) { + db(1, "Got TK1 file\n"); buf_rewind(&st.data); - buf_read(&st.data, buf, tk1_magic_len); - if (memcmp(buf, tk1_magic, tk1_magic_len) == 0) { - db(1, "Got TK1 file\n"); - buf_rewind(&st.data); - /* Seek */ - buf_read(&st.data, NULL, TK1_DATA_OFFSET); - wbt201_process_chunk(&st); - } - else { - db(1, "Got bin file\n"); - - /* Try to guess the data format */ - for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { - size_t reclen = fmt_version[fmt].reclen; - if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { - break; - } - } + /* Seek */ + buf_read(&st.data, NULL, TK1_DATA_OFFSET); + wbt201_process_chunk(&st); + } else { + db(1, "Got bin file\n"); - if (fmt_version[fmt].reclen == 0) { - fatal(MYNAME ": Can't autodetect data format\n"); - } + /* Try to guess the data format */ + for (fmt = 0; fmt_version[fmt].reclen != 0; fmt++) { + size_t reclen = fmt_version[fmt].reclen; + if ((st.data.used % reclen) == 0 && is_valid(&st.data, fmt)) { + break; + } + } - wbt200_process_data(&st, fmt); + if (fmt_version[fmt].reclen == 0) { + fatal(MYNAME ": Can't autodetect data format\n"); } - state_empty(&st); + wbt200_process_data(&st, fmt); + } + + state_empty(&st); } -static void data_read(void) { - switch (dev_type) { - case WBT200: - wbt200_data_read(); - break; - case WBT201: - wbt201_data_read(); - break; - case WSG1000: - wbt201_data_read(); - break; - - default: - fatal(MYNAME ": Unknown device type (internal)\n"); - break; - } +static void data_read(void) +{ + switch (dev_type) { + case WBT200: + wbt200_data_read(); + break; + case WBT201: + wbt201_data_read(); + break; + case WSG1000: + wbt201_data_read(); + break; + + default: + fatal(MYNAME ": Unknown device type (internal)\n"); + break; + } } /* wbt */ static arglist_t wbt_sargs[] = { - { "erase", &erase, "Erase device data after download", - "0", ARGTYPE_BOOL, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "erase", &erase, "Erase device data after download", + "0", ARGTYPE_BOOL, ARG_NOMINMAX + }, + ARG_TERMINATOR }; ff_vecs_t wbt_svecs = { - ff_type_serial, - { ff_cap_read, ff_cap_read, ff_cap_none }, - rd_init, - NULL, - rd_deinit, - NULL, - data_read, - NULL, - NULL, - wbt_sargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_serial, + { ff_cap_read, ff_cap_read, ff_cap_none }, + rd_init, + NULL, + rd_deinit, + NULL, + data_read, + NULL, + NULL, + wbt_sargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; /* used for wbt-bin /and/ wbt-tk1 */ static arglist_t wbt_fargs[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t wbt_fvecs = { - ff_type_file, - { ff_cap_none, ff_cap_read, ff_cap_none }, - file_init, - NULL, - file_deinit, - NULL, - file_read, - NULL, - NULL, - wbt_fargs, - CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ + ff_type_file, + { ff_cap_none, ff_cap_read, ff_cap_none }, + file_init, + NULL, + file_deinit, + NULL, + file_read, + NULL, + NULL, + wbt_fargs, + CET_CHARSET_UTF8, 1 /* master process: don't convert anything | CET-REVIEW */ }; diff --git a/gpsbabel/wfff_xml.c b/gpsbabel/wfff_xml.c index ffa4bb6ac..8105f3828 100644 --- a/gpsbabel/wfff_xml.c +++ b/gpsbabel/wfff_xml.c @@ -1,4 +1,4 @@ -/* +/* Copyright (C) 2006 Etienne Tasse etasse@yahoo.com This program is free software; you can redistribute it and/or modify @@ -28,16 +28,24 @@ static char * snmac =0; static arglist_t wfff_xml_args[] = { - {"aicicon", &aicicon, "Infrastructure closed icon name", - "Red Square", ARGTYPE_STRING }, - {"aioicon", &aioicon, "Infrastructure open icon name", - "Green Square", ARGTYPE_STRING }, - {"ahcicon", &ahcicon, "Ad-hoc closed icon name", - "Red Diamond", ARGTYPE_STRING }, - {"ahoicon", &ahoicon, "Ad-hoc open icon name", - "Green Diamond", ARGTYPE_STRING }, - {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, - {0, 0, 0, 0, 0} + { + "aicicon", &aicicon, "Infrastructure closed icon name", + "Red Square", ARGTYPE_STRING + }, + { + "aioicon", &aioicon, "Infrastructure open icon name", + "Green Square", ARGTYPE_STRING + }, + { + "ahcicon", &ahcicon, "Ad-hoc closed icon name", + "Red Diamond", ARGTYPE_STRING + }, + { + "ahoicon", &ahoicon, "Ad-hoc open icon name", + "Green Diamond", ARGTYPE_STRING + }, + {"snmac", &snmac, "Shortname is MAC address", NULL, ARGTYPE_BOOL }, + {0, 0, 0, 0, 0} }; #define xfreez(p) { if (p) xfree(p); p=0; } @@ -49,7 +57,7 @@ arglist_t wfff_xml_args[] = { void wfff_xml_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded WFFF_XML support because expat was not installed.\n"); } void wfff_xml_read(void) @@ -69,23 +77,23 @@ static xg_callback wfff_mnrssi, wfff_mxrssi; static xg_callback wfff_first, wfff_last; static xg_callback wfff_hdop, wfff_lat, wfff_lon; -static +static xg_tag_mapping loc_map[] = { - { wfff_s, cb_start, "/DocumentElement/AP" }, - { wfff_e, cb_end, "/DocumentElement/AP" }, - { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, - { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, - { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, - { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, - { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, - { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, - { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, - { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, - { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, - { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, - { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, - { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, - { 0,0,0 } + { wfff_s, cb_start, "/DocumentElement/AP" }, + { wfff_e, cb_end, "/DocumentElement/AP" }, + { wfff_wep, cb_cdata, "/DocumentElement/AP/WEP" }, + { wfff_mac, cb_cdata, "/DocumentElement/AP/MAC" }, + { wfff_ssid, cb_cdata, "/DocumentElement/AP/SSID" }, + { wfff_type, cb_cdata, "/DocumentElement/AP/Type" }, + { wfff_mnrssi, cb_cdata, "/DocumentElement/AP/MinRSSI" }, + { wfff_mxrssi, cb_cdata, "/DocumentElement/AP/MaxRSSI" }, + { wfff_chan, cb_cdata, "/DocumentElement/AP/Channel" }, + { wfff_first, cb_cdata, "/DocumentElement/AP/FirstSeen" }, + { wfff_last, cb_cdata, "/DocumentElement/AP/LastSeen" }, + { wfff_hdop, cb_cdata, "/DocumentElement/AP/HDOP" }, + { wfff_lat, cb_cdata, "/DocumentElement/AP/Lat" }, + { wfff_lon, cb_cdata, "/DocumentElement/AP/Lon" }, + { 0,0,0 } }; /* work variables for wfff_xxx */ @@ -103,83 +111,105 @@ static double ap_lat =0.0; static double ap_lon =0.0; /* Start of AP block */ -void wfff_s(const char *args, const char **unused) -{ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); - ap_mnrssi=0.0; - ap_mxrssi=0.0; - ap_chan=0; - ap_hdop=0.0; - ap_first=0; - ap_last=0; - ap_lat=0.0; - ap_lon=0.0; +void wfff_s(const char *args, const char **unused) +{ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + ap_mnrssi=0.0; + ap_mxrssi=0.0; + ap_chan=0; + ap_hdop=0.0; + ap_first=0; + ap_last=0; + ap_lat=0.0; + ap_lon=0.0; } void wfff_mac(const char *args, const char **unused) { - if (args) ap_mac = xstrdup(args); + if (args) { + ap_mac = xstrdup(args); + } } void wfff_ssid(const char *args, const char **unused) { - if (args) ap_ssid = xstrdup(args); + if (args) { + ap_ssid = xstrdup(args); + } } void wfff_type(const char *args, const char **unused) { - if (args) ap_type = xstrdup(args); + if (args) { + ap_type = xstrdup(args); + } } void wfff_mnrssi(const char *args, const char **unused) { - if (args) ap_mnrssi = atof(args); + if (args) { + ap_mnrssi = atof(args); + } } void wfff_mxrssi(const char *args, const char **unused) { - if (args) ap_mxrssi = atof(args); + if (args) { + ap_mxrssi = atof(args); + } } void wfff_chan(const char *args, const char **unused) { - if (args) ap_chan = atoi(args); + if (args) { + ap_chan = atoi(args); + } } void wfff_first(const char *args, const char **unused) { - if (args) { - ap_first = xml_parse_time(args, NULL); - } + if (args) { + ap_first = xml_parse_time(args, NULL); + } } void wfff_last(const char *args, const char **unused) { - if (args) ap_last = xstrdup(args); + if (args) { + ap_last = xstrdup(args); + } } void wfff_wep(const char *args, const char **unused) { - if (args) ap_wep = xstrdup(args); + if (args) { + ap_wep = xstrdup(args); + } } void wfff_hdop(const char *args, const char **unused) { - if (args) ap_hdop = atof(args); + if (args) { + ap_hdop = atof(args); + } } void wfff_lat(const char *args, const char **unused) { - if (args) ap_lat = atof(args); + if (args) { + ap_lat = atof(args); + } } void wfff_lon(const char *args, const char **unused) { - if (args) ap_lon = atof(args); + if (args) { + ap_lon = atof(args); + } } /* End of AP Block, set waypoint and add */ @@ -187,60 +217,59 @@ static long tosscount=0; void wfff_e(const char *args, const char **unused) { - waypoint* wpt_tmp =0; - char desc[255] ="\0"; - - if ((ap_hdop>=1)&&(ap_hdop<50)) // Discard invalid GPS fix - { - wpt_tmp = waypt_new(); - - if ( snmac ) { - wpt_tmp->shortname = xstrdup(ap_mac); - } else { - wpt_tmp->shortname = xstrdup(ap_ssid); - } - - snprintf(desc, sizeof desc, - "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", - (snmac?ap_ssid:ap_mac), ap_type, ap_wep, - ap_chan, ap_mnrssi, ap_mxrssi, ap_last); - wpt_tmp->description = xstrdup(desc); - - wpt_tmp->latitude = ap_lat; - wpt_tmp->longitude = ap_lon; - wpt_tmp->hdop = ap_hdop; - wpt_tmp->altitude = unknown_alt; - wpt_tmp->fix = fix_unknown; - - wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; - if (case_ignore_strncmp(ap_wep,"On",2)==0) { - if (case_ignore_strncmp(ap_type,"AP",2)==0) { - wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ - } else { - wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ - } - } else { - if (case_ignore_strncmp(ap_type,"AP",2)==0) { - wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ - } else { - wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ - } - } - - wpt_tmp->creation_time = ap_first; - - waypt_add(wpt_tmp); - - } else { - tosscount++; - } - - /* cleanup */ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); + waypoint* wpt_tmp =0; + char desc[255] ="\0"; + + if ((ap_hdop>=1)&&(ap_hdop<50)) { // Discard invalid GPS fix + wpt_tmp = waypt_new(); + + if (snmac) { + wpt_tmp->shortname = xstrdup(ap_mac); + } else { + wpt_tmp->shortname = xstrdup(ap_ssid); + } + + snprintf(desc, sizeof desc, + "%s/%s/WEP %s/Ch %d/%2.0fdB/%2.0fdB/%s", + (snmac?ap_ssid:ap_mac), ap_type, ap_wep, + ap_chan, ap_mnrssi, ap_mxrssi, ap_last); + wpt_tmp->description = xstrdup(desc); + + wpt_tmp->latitude = ap_lat; + wpt_tmp->longitude = ap_lon; + wpt_tmp->hdop = ap_hdop; + wpt_tmp->altitude = unknown_alt; + wpt_tmp->fix = fix_unknown; + + wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; + if (case_ignore_strncmp(ap_wep,"On",2)==0) { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aicicon); /* Infra Closed */ + } else { + wpt_tmp->icon_descr = xstrdup(ahcicon); /* AdHoc Closed */ + } + } else { + if (case_ignore_strncmp(ap_type,"AP",2)==0) { + wpt_tmp->icon_descr = xstrdup(aioicon); /* Infra Open */ + } else { + wpt_tmp->icon_descr = xstrdup(ahoicon); /* AdHoc Open */ + } + } + + wpt_tmp->creation_time = ap_first; + + waypt_add(wpt_tmp); + + } else { + tosscount++; + } + + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); } @@ -248,48 +277,48 @@ void wfff_e(const char *args, const char **unused) void wfff_xml_rd_init(const char *fname) { - tosscount = 0; + tosscount = 0; - xml_init(fname, loc_map, NULL); + xml_init(fname, loc_map, NULL); } void wfff_xml_read(void) { - xml_read(); + xml_read(); } void wfff_xml_rd_deinit(void) { - /* cleanup */ - xfreez(ap_mac); - xfreez(ap_ssid); - xfreez(ap_type); - xfreez(ap_wep); - xfreez(ap_last); - - xml_deinit(); + /* cleanup */ + xfreez(ap_mac); + xfreez(ap_ssid); + xfreez(ap_type); + xfreez(ap_wep); + xfreez(ap_last); + + xml_deinit(); - if (tosscount) { - warning("Warning: %s reading file. Threw away %ld invalid entries.\n", - MYNAME, tosscount ); - } + if (tosscount) { + warning("Warning: %s reading file. Threw away %ld invalid entries.\n", + MYNAME, tosscount); + } } #endif ff_vecs_t wfff_xml_vecs = { - ff_type_file, - {ff_cap_read, ff_cap_none, ff_cap_none}, - wfff_xml_rd_init, - 0, - wfff_xml_rd_deinit, - 0, - wfff_xml_read, - 0, - 0, - wfff_xml_args + ff_type_file, + {ff_cap_read, ff_cap_none, ff_cap_none}, + wfff_xml_rd_init, + 0, + wfff_xml_rd_deinit, + 0, + wfff_xml_read, + 0, + 0, + wfff_xml_args }; diff --git a/gpsbabel/wintec_tes.c b/gpsbabel/wintec_tes.c index f5d76f06c..5c1561dcd 100644 --- a/gpsbabel/wintec_tes.c +++ b/gpsbabel/wintec_tes.c @@ -29,90 +29,90 @@ static gbfile* fin; static void wintec_tes_rd_init(const char *fname) { - fin = gbfopen(fname, "r", MYNAME); + fin = gbfopen(fname, "r", MYNAME); } -static void +static void wintec_tes_rd_deinit(void) { - gbfclose(fin); + gbfclose(fin); } static time_t wintec_date_to_time(gbuint32 w) { - struct tm tm; - memset(&tm, 0, sizeof(tm)); - tm.tm_sec = ((w & 0x0000003f)); - tm.tm_min = ((w & 0x00000fc0) >> 6); - tm.tm_hour = ((w & 0x0001f000) >> 12); - tm.tm_mday = ((w & 0x003f0000) >> 17); - tm.tm_mon = ((w & 0x03c00000) >> 22) - 1; - tm.tm_year = ((w & 0xfc000000) >> 26) + 100; - - return mkgmtime(&tm);; + struct tm tm; + memset(&tm, 0, sizeof(tm)); + tm.tm_sec = ((w & 0x0000003f)); + tm.tm_min = ((w & 0x00000fc0) >> 6); + tm.tm_hour = ((w & 0x0001f000) >> 12); + tm.tm_mday = ((w & 0x003f0000) >> 17); + tm.tm_mon = ((w & 0x03c00000) >> 22) - 1; + tm.tm_year = ((w & 0xfc000000) >> 26) + 100; + + return mkgmtime(&tm);; } static void wintec_tes_read(void) { - route_head *trk = route_head_alloc(); - track_add_head(trk); - - while (!gbfeof(fin)) { - waypoint *wpt; - gbuint16 flags = gbfgetuint16(fin); - gbuint32 date = gbfgetuint32(fin); - gbint32 latitude = gbfgetint32(fin); - gbint32 longitude = gbfgetint32(fin); - gbint16 alt = gbfgetint16(fin); // Signed. Meters. - - (void) flags; // Silence 'unused' warning until we use flags. - wpt = waypt_new(); - wpt->latitude = latitude / 1.0e7; - wpt->longitude = longitude / 1.0e7; - wpt->creation_time = wintec_date_to_time(date); - // The unit of altitude isn't clear and we have a lot of - // samples with wildly negative values, so ignore those for now. - wpt->altitude = alt; - - // The description given to us says this is a bitmask with - // 0x01 "split mark" (not at all clear what that is) - // 0x02 interest point - // 0x04 track point - // But of the files we've seen, none have had > 1 bit set - // and none have had 0x04 set. - // Wintec's software puts a waypoint in the track, so we - // mock that. - if (flags & 0x02) { - waypoint *temp = waypt_dupe(wpt); - waypt_add(temp); - } - - track_add_wpt(trk, wpt); - } + route_head *trk = route_head_alloc(); + track_add_head(trk); + + while (!gbfeof(fin)) { + waypoint *wpt; + gbuint16 flags = gbfgetuint16(fin); + gbuint32 date = gbfgetuint32(fin); + gbint32 latitude = gbfgetint32(fin); + gbint32 longitude = gbfgetint32(fin); + gbint16 alt = gbfgetint16(fin); // Signed. Meters. + + (void) flags; // Silence 'unused' warning until we use flags. + wpt = waypt_new(); + wpt->latitude = latitude / 1.0e7; + wpt->longitude = longitude / 1.0e7; + wpt->creation_time = wintec_date_to_time(date); + // The unit of altitude isn't clear and we have a lot of + // samples with wildly negative values, so ignore those for now. + wpt->altitude = alt; + + // The description given to us says this is a bitmask with + // 0x01 "split mark" (not at all clear what that is) + // 0x02 interest point + // 0x04 track point + // But of the files we've seen, none have had > 1 bit set + // and none have had 0x04 set. + // Wintec's software puts a waypoint in the track, so we + // mock that. + if (flags & 0x02) { + waypoint *temp = waypt_dupe(wpt); + waypt_add(temp); + } + + track_add_wpt(trk, wpt); + } } static arglist_t wintec_tes_args[] = { - ARG_TERMINATOR + ARG_TERMINATOR }; ff_vecs_t wintec_tes_vecs = { - ff_type_file, - { - ff_cap_read /* waypoints */, - ff_cap_read /* tracks */, - ff_cap_none /* routes */ - }, - wintec_tes_rd_init, - NULL, - wintec_tes_rd_deinit, - NULL, - wintec_tes_read, - NULL, - NULL, - wintec_tes_args, - CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ - /* not fixed, can be changed through command line parameter */ + ff_type_file, + { + ff_cap_read /* waypoints */, + ff_cap_read /* tracks */, + ff_cap_none /* routes */ + }, + wintec_tes_rd_init, + NULL, + wintec_tes_rd_deinit, + NULL, + wintec_tes_read, + NULL, + NULL, + wintec_tes_args, + CET_CHARSET_ASCII, 0 /* ascii is the expected character set */ + /* not fixed, can be changed through command line parameter */ }; diff --git a/gpsbabel/xcsv.c b/gpsbabel/xcsv.c index b72a26761..5fc11b073 100644 --- a/gpsbabel/xcsv.c +++ b/gpsbabel/xcsv.c @@ -45,397 +45,433 @@ static const char *intstylebuf = NULL; static arglist_t xcsv_args[] = { - {"style", &styleopt, "Full path to XCSV style file", NULL, - ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX }, - {"snlen", &snlenopt, "Max synthesized shortname length", NULL, - ARGTYPE_INT, "1", NULL}, - {"snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snupper", &snupperopt, "UPPERCASE synth. shortnames", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"snunique", &snuniqueopt, "Make synth. shortnames unique", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX}, - {"urlbase", &xcsv_urlbase, "Basename prepended to URL on output", - NULL, ARGTYPE_STRING, ARG_NOMINMAX}, - {"prefer_shortnames", &prefer_shortnames, - "Use shortname instead of description", - NULL, ARGTYPE_BOOL, ARG_NOMINMAX }, - {"datum", &opt_datum, "GPS datum (def. WGS 84)", - "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX}, - ARG_TERMINATOR + { + "style", &styleopt, "Full path to XCSV style file", NULL, + ARGTYPE_FILE | ARGTYPE_REQUIRED, ARG_NOMINMAX + }, + { + "snlen", &snlenopt, "Max synthesized shortname length", NULL, + ARGTYPE_INT, "1", NULL + }, + { + "snwhite", &snwhiteopt, "Allow whitespace synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snupper", &snupperopt, "UPPERCASE synth. shortnames", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "snunique", &snuniqueopt, "Make synth. shortnames unique", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "urlbase", &xcsv_urlbase, "Basename prepended to URL on output", + NULL, ARGTYPE_STRING, ARG_NOMINMAX + }, + { + "prefer_shortnames", &prefer_shortnames, + "Use shortname instead of description", + NULL, ARGTYPE_BOOL, ARG_NOMINMAX + }, + { + "datum", &opt_datum, "GPS datum (def. WGS 84)", + "WGS 84", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; /* a table of config file constants mapped to chars */ -static +static char_map_t xcsv_char_table[] = { - { "COMMA", "," }, - { "COMMASPACE", ", " }, - { "SINGLEQUOTE", "'" }, - { "DOUBLEQUOTE", "\"" }, - { "COLON", ":" }, - { "SEMICOLON", ";" }, - { "NEWLINE", "\n" }, - { "CR", "\n" }, - { "CRNEWLINE", "\r\n" }, - { "TAB", "\t" }, - { "SPACE", " " }, - { "HASH", "#" }, - { "WHITESPACE", "\\w" }, - { "PIPE", "|" }, - { NULL, NULL } -}; + { "COMMA", "," }, + { "COMMASPACE", ", " }, + { "SINGLEQUOTE", "'" }, + { "DOUBLEQUOTE", "\"" }, + { "COLON", ":" }, + { "SEMICOLON", ";" }, + { "NEWLINE", "\n" }, + { "CR", "\n" }, + { "CRNEWLINE", "\r\n" }, + { "TAB", "\t" }, + { "SPACE", " " }, + { "HASH", "#" }, + { "WHITESPACE", "\\w" }, + { "PIPE", "|" }, + { NULL, NULL } +}; void xcsv_destroy_style(void) { - queue *elem, *tmp; - field_map_t *fmp; - ogue_t *ogp; - int internal = 0; - - /* - * If this xcsv_file struct came from a file we can free it all. - * If not, we can at least free the queue elements. - */ - - /* destroy the prologue */ - QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { - ogp = (ogue_t *)elem; - if (ogp->val) - xfree(ogp->val); - if (elem) - xfree(elem); + queue *elem, *tmp; + field_map_t *fmp; + ogue_t *ogp; + int internal = 0; + + /* + * If this xcsv_file struct came from a file we can free it all. + * If not, we can at least free the queue elements. + */ + + /* destroy the prologue */ + QUEUE_FOR_EACH(&xcsv_file.prologue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) { + xfree(ogp->val); } - - /* destroy the epilogue */ - QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { - ogp = (ogue_t *)elem; - if (ogp->val) - xfree(ogp->val); - if (elem) - xfree(elem); + if (elem) { + xfree(elem); } + } - /* destroy the ifields */ - QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) { - fmp = (field_map_t *) elem; - if (fmp->key) - xfree(fmp->key); - if (fmp->val) - xfree(fmp->val); - if (fmp->printfc) - xfree(fmp->printfc); - if (elem) - xfree(elem); + /* destroy the epilogue */ + QUEUE_FOR_EACH(&xcsv_file.epilogue, elem, tmp) { + ogp = (ogue_t *)elem; + if (ogp->val) { + xfree(ogp->val); } + if (elem) { + xfree(elem); + } + } - /* destroy the ofields, if they are not re-mapped to ifields. */ - if (xcsv_file.ofield != &xcsv_file.ifield) { - QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { - fmp = (field_map_t *) elem; - if (fmp->key) - xfree(fmp->key); - if (fmp->val) - xfree(fmp->val); - if (fmp->printfc) - xfree(fmp->printfc); - if (elem) - xfree(elem); - } + /* destroy the ifields */ + QUEUE_FOR_EACH(&xcsv_file.ifield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) { + xfree(fmp->key); + } + if (fmp->val) { + xfree(fmp->val); + } + if (fmp->printfc) { + xfree(fmp->printfc); + } + if (elem) { + xfree(elem); + } + } + + /* destroy the ofields, if they are not re-mapped to ifields. */ + if (xcsv_file.ofield != &xcsv_file.ifield) { + QUEUE_FOR_EACH(xcsv_file.ofield, elem, tmp) { + fmp = (field_map_t *) elem; + if (fmp->key) { + xfree(fmp->key); + } + if (fmp->val) { + xfree(fmp->val); + } + if (fmp->printfc) { + xfree(fmp->printfc); + } + if (elem) { + xfree(elem); + } + } - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); } + } - /* other alloc'd glory */ - if (xcsv_file.field_delimiter) - xfree(xcsv_file.field_delimiter); + /* other alloc'd glory */ + if (xcsv_file.field_delimiter) { + xfree(xcsv_file.field_delimiter); + } - if (xcsv_file.record_delimiter) - xfree(xcsv_file.record_delimiter); + if (xcsv_file.record_delimiter) { + xfree(xcsv_file.record_delimiter); + } - if (xcsv_file.badchars) - xfree(xcsv_file.badchars); + if (xcsv_file.badchars) { + xfree(xcsv_file.badchars); + } - if (xcsv_file.description) - xfree(xcsv_file.description); + if (xcsv_file.description) { + xfree(xcsv_file.description); + } - if (xcsv_file.extension) - xfree(xcsv_file.extension); + if (xcsv_file.extension) { + xfree(xcsv_file.extension); + } - if (xcsv_file.mkshort_handle) - mkshort_del_handle(&xcsv_file.mkshort_handle); + if (xcsv_file.mkshort_handle) { + mkshort_del_handle(&xcsv_file.mkshort_handle); + } - /* return everything to zeros */ - internal = xcsv_file.is_internal; - memset(&xcsv_file, '\0', sizeof(xcsv_file)); - xcsv_file.is_internal = internal; + /* return everything to zeros */ + internal = xcsv_file.is_internal; + memset(&xcsv_file, '\0', sizeof(xcsv_file)); + xcsv_file.is_internal = internal; } const char * xcsv_get_char_from_constant_table(char *key) { - char_map_t *cm = xcsv_char_table; + char_map_t *cm = xcsv_char_table; - while ((cm->key) && (strcmp(key, cm->key) != 0)) { - cm++; - } + while ((cm->key) && (strcmp(key, cm->key) != 0)) { + cm++; + } - return (cm->chars); + return (cm->chars); } static void xcsv_parse_style_line(const char *sbuff) { - int i, linecount = 0; - char *s, *p, *sp; - const char *cp; - char *key, *val, *pfc; - - /* - * tokens should be parsed longest to shortest, unless something - * requires a previously set value. This way something like - * SHORT and SHORTNAME don't collide. - */ - - /* whack off any comments */ - if ((p = strchr(sbuff, '#')) != NULL) { - if ((p > sbuff) && p[-1] == '\\') { - memmove(p-1, p, strlen(p)); - p[strlen(p)-1] = '\0'; - } else { - *p = '\0'; - } + int i, linecount = 0; + char *s, *p, *sp; + const char *cp; + char *key, *val, *pfc; + + /* + * tokens should be parsed longest to shortest, unless something + * requires a previously set value. This way something like + * SHORT and SHORTNAME don't collide. + */ + + /* whack off any comments */ + if ((p = strchr(sbuff, '#')) != NULL) { + if ((p > sbuff) && p[-1] == '\\') { + memmove(p-1, p, strlen(p)); + p[strlen(p)-1] = '\0'; + } else { + *p = '\0'; } + } + + if (strlen(sbuff)) { + if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[16], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.field_delimiter = xstrdup(cp); + xfree(sp); + } else { + xcsv_file.field_delimiter = sp; + } + + p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); + + /* field delimiters are always bad characters */ + if (0 == strcmp(p, "\\w")) { + char *s = xstrappend(xcsv_file.badchars, " \n\r"); + if (xcsv_file.badchars) { + xfree(xcsv_file.badchars); + } + xcsv_file.badchars = s; + } else { + xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); + } + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) { + sp = csv_stringtrim(&sbuff[17], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + if (cp) { + xcsv_file.record_delimiter = xstrdup(cp); + xfree(sp); + } else { + xcsv_file.record_delimiter = sp; + } - if (strlen(sbuff)) { - if (ISSTOKEN(sbuff, "FIELD_DELIMITER")) { - sp = csv_stringtrim(&sbuff[16], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - if (cp) { - xcsv_file.field_delimiter = xstrdup(cp); - xfree(sp); - } - else - xcsv_file.field_delimiter = sp; - - p = csv_stringtrim(xcsv_file.field_delimiter, " ", 0); - - /* field delimiters are always bad characters */ - if (0 == strcmp(p, "\\w")) { - char *s = xstrappend(xcsv_file.badchars, " \n\r"); - if (xcsv_file.badchars) xfree(xcsv_file.badchars); - xcsv_file.badchars = s; - } else { - xcsv_file.badchars = xstrappend(xcsv_file.badchars, p); - } - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "RECORD_DELIMITER")) { - sp = csv_stringtrim(&sbuff[17], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - if (cp) { - xcsv_file.record_delimiter = xstrdup(cp); - xfree(sp); - } - else - xcsv_file.record_delimiter = sp; - - p = csv_stringtrim(xcsv_file.record_delimiter, " ", 0); - - /* record delimiters are always bad characters */ - if (xcsv_file.badchars) { - xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, - strlen(xcsv_file.badchars) + - strlen(p) + 1); - } else { - xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); - } - - strcat(xcsv_file.badchars, p); - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "FORMAT_TYPE")) { - const char *p; - for (p = &sbuff[11]; *p && isspace(*p); p++) { - ; - } - if (ISSTOKEN(p, "INTERNAL")) { - xcsv_file.type = ff_type_internal; - } - /* this is almost inconcievable... */ - if (ISSTOKEN(p, "SERIAL")) { - xcsv_file.type = ff_type_serial; - } - } else - - if (ISSTOKEN(sbuff, "DESCRIPTION")) { - xcsv_file.description = csv_stringtrim(&sbuff[11],"", 0); - } else - - if (ISSTOKEN(sbuff, "EXTENSION")) { - xcsv_file.extension = csv_stringtrim(&sbuff[10],"", 0); - } else - - if (ISSTOKEN(sbuff, "SHORTLEN")) { - if (xcsv_file.mkshort_handle) - setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "SHORTWHITE")) { - if (xcsv_file.mkshort_handle) - setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12])); - } else - - if (ISSTOKEN(sbuff, "BADCHARS")) { - sp = csv_stringtrim(&sbuff[9], "\"", 1); - cp = xcsv_get_char_from_constant_table(sp); - - if (cp) { - p = xstrdup(cp); - xfree(sp); - } - else - p = sp; - - if (xcsv_file.badchars) { - xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, - strlen(xcsv_file.badchars) + - strlen(p) + 1); - } else { - xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); - } - - strcat(xcsv_file.badchars, p); - - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "PROLOGUE")) { - xcsv_prologue_add(xstrdup(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "EPILOGUE")) { - xcsv_epilogue_add(xstrdup(&sbuff[9])); - } else - - if (ISSTOKEN(sbuff, "ENCODING")) { - p = csv_stringtrim(&sbuff[8], "\"", 1); - cet_convert_init(p, 1); - xfree(p); - } else - - if (ISSTOKEN(sbuff, "DATUM")) { - p = csv_stringtrim(&sbuff[5], "\"", 1); - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(p); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", p); - xfree(p); - } else - - if (ISSTOKEN(sbuff, "DATATYPE")) { - p = csv_stringtrim(&sbuff[8], "\"", 1); - if (case_ignore_strcmp(p, "TRACK") == 0) { - xcsv_file.datatype = trkdata; - } - else if (case_ignore_strcmp(p, "ROUTE") == 0) { - xcsv_file.datatype = rtedata; - } - else if (case_ignore_strcmp(p, "WAYPOINT") == 0) { - xcsv_file.datatype = wptdata; - } - else { - fatal(MYNAME ": Unknown data type \"%s\"!\n", p); - } - xfree(p); - - } else - - if (ISSTOKEN(sbuff, "IFIELD")) { - key = val = pfc = NULL; - - s = csv_lineparse(&sbuff[6], ",", "", linecount); - - i = 0; - while (s) { - switch(i) { - case 0: - /* key */ - key = csv_stringtrim(s, "\"", 1); - break; - case 1: - /* default value */ - val = csv_stringtrim(s, "\"", 1); - break; - case 2: - /* printf conversion */ - pfc = csv_stringtrim(s, "\"", 1); - break; - default: - break; - } - i++; - - s = csv_lineparse(NULL, ",", "", linecount); - } - - xcsv_ifield_add(key, val, pfc); - - } else - - /* - * as OFIELDs are implemented as an after-thought, I'll - * leave this as it's own parsing for now. We could - * change the world on ifield vs ofield format later.. - */ - if (ISSTOKEN(sbuff, "OFIELD")) { - int options = 0; - key = val = pfc = NULL; - - s = csv_lineparse(&sbuff[6], ",", "", linecount); - - i = 0; - while (s) { - switch(i) { - case 0: - /* key */ - key = csv_stringtrim(s, "\"", 1); - break; - case 1: - /* default value */ - val = csv_stringtrim(s, "\"", 1); - break; - case 2: - /* printf conversion */ - pfc = csv_stringtrim(s, "\"", 1); - break; - case 3: - /* Any additional options. */ - if (strstr(s, "no_delim_before")) { - options |= OPTIONS_NODELIM; - } - if (strstr(s, "absolute")) { - options |= OPTIONS_ABSOLUTE; - } - if (strstr(s, "optional")) { - options |= OPTIONS_OPTIONAL; - } - default: - break; - } - i++; - s = csv_lineparse(NULL, ",", "", linecount); - } - - xcsv_ofield_add(key, val, pfc, options); - } - } + p = csv_stringtrim(xcsv_file.record_delimiter, " ", 0); + + /* record delimiters are always bad characters */ + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "FORMAT_TYPE")) { + const char *p; + for (p = &sbuff[11]; *p && isspace(*p); p++) { + ; + } + if (ISSTOKEN(p, "INTERNAL")) { + xcsv_file.type = ff_type_internal; + } + /* this is almost inconcievable... */ + if (ISSTOKEN(p, "SERIAL")) { + xcsv_file.type = ff_type_serial; + } + } else + + if (ISSTOKEN(sbuff, "DESCRIPTION")) { + xcsv_file.description = csv_stringtrim(&sbuff[11],"", 0); + } else + + if (ISSTOKEN(sbuff, "EXTENSION")) { + xcsv_file.extension = csv_stringtrim(&sbuff[10],"", 0); + } else + + if (ISSTOKEN(sbuff, "SHORTLEN")) { + if (xcsv_file.mkshort_handle) { + setshort_length(xcsv_file.mkshort_handle, atoi(&sbuff[9])); + } + } else + + if (ISSTOKEN(sbuff, "SHORTWHITE")) { + if (xcsv_file.mkshort_handle) { + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(&sbuff[12])); + } + } else + + if (ISSTOKEN(sbuff, "BADCHARS")) { + sp = csv_stringtrim(&sbuff[9], "\"", 1); + cp = xcsv_get_char_from_constant_table(sp); + + if (cp) { + p = xstrdup(cp); + xfree(sp); + } else { + p = sp; + } + + if (xcsv_file.badchars) { + xcsv_file.badchars = (char *) xrealloc(xcsv_file.badchars, + strlen(xcsv_file.badchars) + + strlen(p) + 1); + } else { + xcsv_file.badchars = (char *) xcalloc(strlen(p) + 1, 1); + } + + strcat(xcsv_file.badchars, p); + + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "PROLOGUE")) { + xcsv_prologue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "EPILOGUE")) { + xcsv_epilogue_add(xstrdup(&sbuff[9])); + } else + + if (ISSTOKEN(sbuff, "ENCODING")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + cet_convert_init(p, 1); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATUM")) { + p = csv_stringtrim(&sbuff[5], "\"", 1); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(p); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", p); + xfree(p); + } else + + if (ISSTOKEN(sbuff, "DATATYPE")) { + p = csv_stringtrim(&sbuff[8], "\"", 1); + if (case_ignore_strcmp(p, "TRACK") == 0) { + xcsv_file.datatype = trkdata; + } else if (case_ignore_strcmp(p, "ROUTE") == 0) { + xcsv_file.datatype = rtedata; + } else if (case_ignore_strcmp(p, "WAYPOINT") == 0) { + xcsv_file.datatype = wptdata; + } else { + fatal(MYNAME ": Unknown data type \"%s\"!\n", p); + } + xfree(p); + + } else + + if (ISSTOKEN(sbuff, "IFIELD")) { + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch (i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + default: + break; + } + i++; + + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ifield_add(key, val, pfc); + + } else + + /* + * as OFIELDs are implemented as an after-thought, I'll + * leave this as it's own parsing for now. We could + * change the world on ifield vs ofield format later.. + */ + if (ISSTOKEN(sbuff, "OFIELD")) { + int options = 0; + key = val = pfc = NULL; + + s = csv_lineparse(&sbuff[6], ",", "", linecount); + + i = 0; + while (s) { + switch (i) { + case 0: + /* key */ + key = csv_stringtrim(s, "\"", 1); + break; + case 1: + /* default value */ + val = csv_stringtrim(s, "\"", 1); + break; + case 2: + /* printf conversion */ + pfc = csv_stringtrim(s, "\"", 1); + break; + case 3: + /* Any additional options. */ + if (strstr(s, "no_delim_before")) { + options |= OPTIONS_NODELIM; + } + if (strstr(s, "absolute")) { + options |= OPTIONS_ABSOLUTE; + } + if (strstr(s, "optional")) { + options |= OPTIONS_OPTIONAL; + } + default: + break; + } + i++; + s = csv_lineparse(NULL, ",", "", linecount); + } + + xcsv_ofield_add(key, val, pfc, options); + } + } } @@ -447,45 +483,48 @@ xcsv_parse_style_line(const char *sbuff) static void xcsv_parse_style_buff(const char *sbuff) { - char ibuf[256]; - char *ibufp; - size_t i; - - while (*sbuff) { - ibuf[0] = 0; - i = 0; - for (ibufp = ibuf; *sbuff != '\n' && i++ < sizeof(ibuf); ) { - *ibufp++ = *sbuff++; - } - while (*sbuff == '\n' || *sbuff == '\r') - sbuff++; - *ibufp = 0; - xcsv_parse_style_line(ibuf); - } + char ibuf[256]; + char *ibufp; + size_t i; + + while (*sbuff) { + ibuf[0] = 0; + i = 0; + for (ibufp = ibuf; *sbuff != '\n' && i++ < sizeof(ibuf);) { + *ibufp++ = *sbuff++; + } + while (*sbuff == '\n' || *sbuff == '\r') { + sbuff++; + } + *ibufp = 0; + xcsv_parse_style_line(ibuf); + } } static void xcsv_read_style(const char *fname) { - char *sbuff; - gbfile *fp; - - xcsv_file_init(); - - fp = gbfopen(fname, "rb", MYNAME); - while ((sbuff = gbfgetstr(fp))) { - sbuff = lrtrim(sbuff); - xcsv_parse_style_line(sbuff); - } while (!gbfeof(fp)); - - /* if we have no output fields, use input fields as output fields */ - if (xcsv_file.ofield_ct == 0) { - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); - xcsv_file.ofield = &xcsv_file.ifield; - xcsv_file.ofield_ct = xcsv_file.ifield_ct; + char *sbuff; + gbfile *fp; + + xcsv_file_init(); + + fp = gbfopen(fname, "rb", MYNAME); + while ((sbuff = gbfgetstr(fp))) { + sbuff = lrtrim(sbuff); + xcsv_parse_style_line(sbuff); + } + while (!gbfeof(fp)); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); } - gbfclose(fp); + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } + gbfclose(fp); } /* @@ -496,27 +535,28 @@ xcsv_read_style(const char *fname) void xcsv_read_internal_style(const char *style_buf) { - xcsv_file_init(); - xcsv_file.is_internal = 1; - - xcsv_parse_style_buff(style_buf); - - /* if we have no output fields, use input fields as output fields */ - if (xcsv_file.ofield_ct == 0) { - if (xcsv_file.ofield) - xfree(xcsv_file.ofield); - xcsv_file.ofield = &xcsv_file.ifield; - xcsv_file.ofield_ct = xcsv_file.ifield_ct; - } + xcsv_file_init(); + xcsv_file.is_internal = 1; + + xcsv_parse_style_buff(style_buf); + + /* if we have no output fields, use input fields as output fields */ + if (xcsv_file.ofield_ct == 0) { + if (xcsv_file.ofield) { + xfree(xcsv_file.ofield); + } + xcsv_file.ofield = &xcsv_file.ifield; + xcsv_file.ofield_ct = xcsv_file.ifield_ct; + } } void xcsv_setup_internal_style(const char *style_buf) { - xcsv_file_init(); - xcsv_destroy_style(); - xcsv_file.is_internal = !!style_buf; - intstylebuf = style_buf; + xcsv_file_init(); + xcsv_destroy_style(); + xcsv_file.is_internal = !!style_buf; + intstylebuf = style_buf; } @@ -524,137 +564,141 @@ static void xcsv_rd_init(const char *fname) { - /* - * if we don't have an internal style defined, we need to - * read it from a user-supplied style file, or die trying. - */ - if (xcsv_file.is_internal ) { - xcsv_read_internal_style( intstylebuf ); + /* + * if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + */ + if (xcsv_file.is_internal) { + xcsv_read_internal_style(intstylebuf); + } else { + if (!styleopt) { + fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n"); } - else { - if (!styleopt) - fatal(MYNAME ": XCSV input style not declared. Use ... -i xcsv,style=path/to/file.style\n"); - xcsv_read_style(styleopt); - } + xcsv_read_style(styleopt); + } - if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { - if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) { - warning(MYNAME " attempt to read %s as a track or route, but this format only supports waypoints on read. Reading as waypoints instead.\n", fname); - } + if ((xcsv_file.datatype == 0) || (xcsv_file.datatype == wptdata)) { + if (global_opts.masked_objective & (TRKDATAMASK|RTEDATAMASK)) { + warning(MYNAME " attempt to read %s as a track or route, but this format only supports waypoints on read. Reading as waypoints instead.\n", fname); } + } - xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); + xcsv_file.xcsvfp = gbfopen(fname, "r", MYNAME); + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); } static void xcsv_rd_deinit(void) { - gbfclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); - xcsv_destroy_style(); + xcsv_destroy_style(); } static void xcsv_wr_init(const char *fname) { - /* if we don't have an internal style defined, we need to - * read it from a user-supplied style file, or die trying. - */ - if (xcsv_file.is_internal ) { - xcsv_read_internal_style( intstylebuf ); + /* if we don't have an internal style defined, we need to + * read it from a user-supplied style file, or die trying. + */ + if (xcsv_file.is_internal) { + xcsv_read_internal_style(intstylebuf); + } else { + + if (!styleopt) { + fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n"); } - else { - if (!styleopt) - fatal(MYNAME ": XCSV output style not declared. Use ... -o xcsv,style=path/to/file.style\n"); - - xcsv_read_style(styleopt); - } + xcsv_read_style(styleopt); + } - xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); - xcsv_file.fname = (char *)fname; + xcsv_file.xcsvfp = gbfopen(fname, "w", MYNAME); + xcsv_file.fname = (char *)fname; - /* set mkshort options from the command line */ - if (global_opts.synthesize_shortnames) { + /* set mkshort options from the command line */ + if (global_opts.synthesize_shortnames) { - if (snlenopt) - setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt)); + if (snlenopt) { + setshort_length(xcsv_file.mkshort_handle, atoi(snlenopt)); + } - if (snwhiteopt) - setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt)); + if (snwhiteopt) { + setshort_whitespace_ok(xcsv_file.mkshort_handle, atoi(snwhiteopt)); + } - if (snupperopt) - setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt)); + if (snupperopt) { + setshort_mustupper(xcsv_file.mkshort_handle, atoi(snupperopt)); + } - if (snuniqueopt) - setshort_mustuniq(xcsv_file.mkshort_handle, atoi(snuniqueopt)); + if (snuniqueopt) { + setshort_mustuniq(xcsv_file.mkshort_handle, atoi(snuniqueopt)); + } - setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars); + setshort_badchars(xcsv_file.mkshort_handle, xcsv_file.badchars); - } - xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); - is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); + } + xcsv_file.gps_datum = GPS_Lookup_Datum_Index(opt_datum); + is_fatal(xcsv_file.gps_datum < 0, MYNAME ": datum \"%s\" is not supported.", opt_datum); } static void xcsv_wr_position_init(const char *fname) { - xcsv_wr_init(fname); + xcsv_wr_init(fname); } static void xcsv_wr_deinit(void) { - gbfclose(xcsv_file.xcsvfp); + gbfclose(xcsv_file.xcsvfp); - xcsv_destroy_style(); + xcsv_destroy_style(); } static void xcsv_wr_position_deinit(void) { - xcsv_wr_deinit(); + xcsv_wr_deinit(); } static void xcsv_wr_position(waypoint *wpt) { - /* Tweak incoming name if we don't have a fix */ - switch(wpt->fix) { - case fix_none: - if (wpt->shortname) { - xfree(wpt->shortname); - } - wpt->shortname = xstrdup("ESTIMATED Position"); - break; - default: - break; - } - - waypt_add(wpt); - xcsv_data_write(); - waypt_del(wpt); - - gbfflush(xcsv_file.xcsvfp); + /* Tweak incoming name if we don't have a fix */ + switch (wpt->fix) { + case fix_none: + if (wpt->shortname) { + xfree(wpt->shortname); + } + wpt->shortname = xstrdup("ESTIMATED Position"); + break; + default: + break; + } + + waypt_add(wpt); + xcsv_data_write(); + waypt_del(wpt); + + gbfflush(xcsv_file.xcsvfp); } ff_vecs_t xcsv_vecs = { - ff_type_internal, - FF_CAP_RW_WPT, /* This is a bit of a lie for now... */ - xcsv_rd_init, - xcsv_wr_init, - xcsv_rd_deinit, - xcsv_wr_deinit, - xcsv_data_read, - xcsv_data_write, - NULL, - xcsv_args, - CET_CHARSET_ASCII, 0, /* CET-REVIEW */ - { NULL, NULL, NULL, xcsv_wr_position_init, xcsv_wr_position, xcsv_wr_position_deinit } + ff_type_internal, + FF_CAP_RW_WPT, /* This is a bit of a lie for now... */ + xcsv_rd_init, + xcsv_wr_init, + xcsv_rd_deinit, + xcsv_wr_deinit, + xcsv_data_read, + xcsv_data_write, + NULL, + xcsv_args, + CET_CHARSET_ASCII, 0, /* CET-REVIEW */ + { NULL, NULL, NULL, xcsv_wr_position_init, xcsv_wr_position, xcsv_wr_position_deinit } }; #else diff --git a/gpsbabel/xhtmlent.c b/gpsbabel/xhtmlent.c index 499122dd7..2c47c8b32 100644 --- a/gpsbabel/xhtmlent.c +++ b/gpsbabel/xhtmlent.c @@ -1,515 +1,515 @@ -char *xhtml_entities = -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -"\n" -" \n" -" \n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -"\n" -"\n" -" \n" -" \n" -" \n" -" \n" -" \n" -"\n" -" \n" -"\n" -"\n" -"\n" -" \n" -"\n" -"\n" -" \n" -"\n" -" \n" -" \n" -" \n" -; +char *xhtml_entities = + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + "\n" + " \n" + " \n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n" + " \n" + "\n" + "\n" + "\n" + " \n" + "\n" + "\n" + " \n" + "\n" + " \n" + " \n" + " \n" + ; diff --git a/gpsbabel/xmlgeneric.c b/gpsbabel/xmlgeneric.c index a8bdf32bf..53c85fdfa 100644 --- a/gpsbabel/xmlgeneric.c +++ b/gpsbabel/xmlgeneric.c @@ -24,8 +24,8 @@ #include "cet_util.h" #if HAVE_LIBEXPAT - #include - static XML_Parser psr; +#include +static XML_Parser psr; #endif static vmem_t current_tag; @@ -41,115 +41,118 @@ static const char **xg_ignore_taglist; void write_xml_header(gbfile *ofd) { - char buff[128]; - cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); - - if ((global_opts.charset != NULL) && (global_opts.charset != cs)) - snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); - else - buff[0] = 0; - gbfprintf(ofd, "\n", buff); + char buff[128]; + cet_cs_vec_t *cs = cet_find_cs_by_name(CET_CHARSET_ASCII); + + if ((global_opts.charset != NULL) && (global_opts.charset != cs)) { + snprintf(buff, sizeof(buff), " encoding=\"%s\"", global_opts.charset_name); + } else { + buff[0] = 0; + } + gbfprintf(ofd, "\n", buff); } void write_xml_entity(gbfile *ofd, const char *indent, const char *tag, const char *value) { - char *tmp_ent = xml_entitize(value); - gbfprintf(ofd, "%s<%s>%s\n", indent, tag, tmp_ent, tag); - xfree(tmp_ent); + char *tmp_ent = xml_entitize(value); + gbfprintf(ofd, "%s<%s>%s\n", indent, tag, tmp_ent, tag); + xfree(tmp_ent); } void write_optional_xml_entity(gbfile *ofd, const char *indent, const char *tag, const char *value) { - if (value && *value) - write_xml_entity(ofd, indent, tag, value); + if (value && *value) { + write_xml_entity(ofd, indent, tag, value); + } } void write_xml_entity_begin0(gbfile *ofd, const char *indent, - const char *tag) + const char *tag) { - gbfprintf(ofd, "%s<%s>\n", indent, tag); + gbfprintf(ofd, "%s<%s>\n", indent, tag); } void write_xml_entity_begin1(gbfile *ofd, const char *indent, - const char *tag, const char *attr, - const char *attrval) + const char *tag, const char *attr, + const char *attrval) { - gbfprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); + gbfprintf(ofd, "%s<%s %s=\"%s\">\n", indent, tag, attr, attrval); } void write_xml_entity_begin2(gbfile *ofd, const char *indent, - const char *tag, const char *attr1, - const char *attrval1, const char *attr2, - const char *attrval2) + const char *tag, const char *attr1, + const char *attrval1, const char *attr2, + const char *attrval2) { - gbfprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); + gbfprintf(ofd, "%s<%s %s=\"%s\" %s=\"%s\">\n", indent, tag, attr1, attrval1, attr2, attrval2); } void write_xml_entity_end(gbfile *ofd, const char *indent, - const char *tag) + const char *tag) { - gbfprintf(ofd, "%s\n", indent, tag); + gbfprintf(ofd, "%s\n", indent, tag); } void xml_fill_in_time(char *time_string, const time_t timep, int microseconds, int long_or_short) { - struct tm *tm = gmtime(&timep); - char *format; - int n; - - if (!tm) { - *time_string = 0; - return; - } - - if (long_or_short == XML_LONG_TIME) - format = "%02d-%02d-%02dT%02d:%02d:%02d"; - else - format = "%02d%02d%02dT%02d%02d%02d"; - n = sprintf(time_string, format, - tm->tm_year+1900, - tm->tm_mon+1, - tm->tm_mday, - tm->tm_hour, - tm->tm_min, - tm->tm_sec); - if (microseconds) { - n += sprintf(time_string + n, ".%03d", microseconds / 1000); - } - time_string[n++] = 'Z'; - time_string[n++] = '\0'; - + struct tm *tm = gmtime(&timep); + char *format; + int n; + + if (!tm) { + *time_string = 0; + return; + } + + if (long_or_short == XML_LONG_TIME) { + format = "%02d-%02d-%02dT%02d:%02d:%02d"; + } else { + format = "%02d%02d%02dT%02d%02d%02d"; + } + n = sprintf(time_string, format, + tm->tm_year+1900, + tm->tm_mon+1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + if (microseconds) { + n += sprintf(time_string + n, ".%03d", microseconds / 1000); + } + time_string[n++] = 'Z'; + time_string[n++] = '\0'; + } void xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *elname) { - char time_string[64]; - xml_fill_in_time(time_string, timep, microseconds, XML_LONG_TIME); - if (time_string[0]) { - gbfprintf(ofd, "<%s>%s\n", - elname, - time_string, - elname - ); - } + char time_string[64]; + xml_fill_in_time(time_string, timep, microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(ofd, "<%s>%s\n", + elname, + time_string, + elname + ); + } } /*********************************************************************** * These implement a simple interface for "generic" XML that * maps reasonably close to 1:1 between XML tags and internal data - * structures. - * + * structures. + * * It doesn't work well for formats (like GPX) that really are "real" * XML with extended namespaces and such, but it handles many simpler * xml strains and insulates us from a lot of the grubbiness of expat. @@ -158,13 +161,13 @@ xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *el xg_callback * xml_tbl_lookup(const char *tag, xg_cb_type cb_type) { - xg_tag_mapping *tm; - for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) { - if (str_match(tag, tm->tag_name) && (cb_type == tm->cb_type)) { - return tm->tag_cb; - } - } - return NULL; + xg_tag_mapping *tm; + for (tm = xg_tag_tbl; tm->tag_cb != NULL; tm++) { + if (str_match(tag, tm->tag_name) && (cb_type == tm->cb_type)) { + return tm->tag_cb; + } + } + return NULL; } /* @@ -174,202 +177,208 @@ xml_tbl_lookup(const char *tag, xg_cb_type cb_type) static int xml_consider_ignoring(const char *t) { - const char **il; - - if (!xg_ignore_taglist) { - return 0; - } - - for (il = xg_ignore_taglist; *il; il++) { - if (0 == strcmp(*il, t)) { - return 1; - } - } - return 0; + const char **il; + + if (!xg_ignore_taglist) { + return 0; + } + + for (il = xg_ignore_taglist; *il; il++) { + if (0 == strcmp(*il, t)) { + return 1; + } + } + return 0; } static void xml_start(void *data, const XML_Char *xml_el, const XML_Char **xml_attr) { - char *e; - char *ep; - xg_callback *cb; - const char *el; - const char **attrs; - - el = xml_convert_to_char_string(xml_el); - attrs = xml_convert_attrs_to_char_string(xml_attr); - - if (xml_consider_ignoring(el)) - return; - - vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); - - e = current_tag.mem; - ep = e + strlen(e); - *ep++ = '/'; - strcpy(ep, el); - - memset(cdatastr.mem, 0, cdatastr.size); - - cb = xml_tbl_lookup(e, cb_start); - if (cb) { - (*cb)(NULL, attrs); - } - xml_free_converted_string(el); - xml_free_converted_attrs(attrs); + char *e; + char *ep; + xg_callback *cb; + const char *el; + const char **attrs; + + el = xml_convert_to_char_string(xml_el); + attrs = xml_convert_attrs_to_char_string(xml_attr); + + if (xml_consider_ignoring(el)) { + return; + } + + vmem_realloc(¤t_tag, strlen(current_tag.mem) + 2 + strlen(el)); + + e = current_tag.mem; + ep = e + strlen(e); + *ep++ = '/'; + strcpy(ep, el); + + memset(cdatastr.mem, 0, cdatastr.size); + + cb = xml_tbl_lookup(e, cb_start); + if (cb) { + (*cb)(NULL, attrs); + } + xml_free_converted_string(el); + xml_free_converted_attrs(attrs); } #if HAVE_LIBEXPAT static void xml_cdata(void *dta, const XML_Char *xml_s, int len) { - char *estr; - const char *s = xml_convert_to_char_string_n(xml_s, &len); - - vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); - estr = (char *) cdatastr.mem + strlen(cdatastr.mem); - memcpy(estr, s, len); - estr[len] = 0; - xml_free_converted_string(s); + char *estr; + const char *s = xml_convert_to_char_string_n(xml_s, &len); + + vmem_realloc(&cdatastr, 1 + len + strlen(cdatastr.mem)); + estr = (char *) cdatastr.mem + strlen(cdatastr.mem); + memcpy(estr, s, len); + estr[len] = 0; + xml_free_converted_string(s); } static void xml_end(void *data, const XML_Char *xml_el) { - char *s = strrchr(current_tag.mem, '/'); - const char *el = xml_convert_to_char_string(xml_el); - xg_callback *cb; - - if (xml_consider_ignoring(el)) - return; - - if (strcmp(s + 1, el)) { - fprintf(stderr, "Mismatched tag %s\n", el); - } - cb = xml_tbl_lookup(current_tag.mem, cb_cdata); - if (cb) { - (*cb)( (char *) cdatastr.mem, NULL); - } - - cb = xml_tbl_lookup(current_tag.mem, cb_end); - if (cb) { - (*cb)(el, NULL); - } - *s = 0; - xml_free_converted_string(el); + char *s = strrchr(current_tag.mem, '/'); + const char *el = xml_convert_to_char_string(xml_el); + xg_callback *cb; + + if (xml_consider_ignoring(el)) { + return; + } + + if (strcmp(s + 1, el)) { + fprintf(stderr, "Mismatched tag %s\n", el); + } + cb = xml_tbl_lookup(current_tag.mem, cb_cdata); + if (cb) { + (*cb)((char *) cdatastr.mem, NULL); + } + + cb = xml_tbl_lookup(current_tag.mem, cb_end); + if (cb) { + (*cb)(el, NULL); + } + *s = 0; + xml_free_converted_string(el); } void xml_read(void) { - int len; - char buf[MY_CBUF]; - - while ((len = gbfread(buf, 1, sizeof(buf), ifd))) { - char *str = buf; - if (ifd->unicode) { - str = cet_str_uni_to_utf8((short *)&buf, len >> 1); - len = strlen(str); - } - if (!XML_Parse(psr, str, len, gbfeof(ifd))) { - fatal(MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - if (str != buf) xfree(str); - } - XML_ParserFree(psr); - + int len; + char buf[MY_CBUF]; + + while ((len = gbfread(buf, 1, sizeof(buf), ifd))) { + char *str = buf; + if (ifd->unicode) { + str = cet_str_uni_to_utf8((short *)&buf, len >> 1); + len = strlen(str); + } + if (!XML_Parse(psr, str, len, gbfeof(ifd))) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + if (str != buf) { + xfree(str); + } + } + XML_ParserFree(psr); + } -void xml_readstring( char *str ) +void xml_readstring(char *str) { - int len = strlen(str); - if (!XML_Parse(psr, str, len, 1)) { - fatal( MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } - XML_ParserFree(psr); + int len = strlen(str); + if (!XML_Parse(psr, str, len, 1)) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } + XML_ParserFree(psr); } -void xml_readprefixstring( char *str ) +void xml_readprefixstring(char *str) { - int len = strlen(str); - if (!XML_Parse(psr, str, len, 0)) { - fatal( MYNAME ":Parse error at %d: %s\n", - (int) XML_GetCurrentLineNumber(psr), - XML_ErrorString(XML_GetErrorCode(psr))); - } + int len = strlen(str); + if (!XML_Parse(psr, str, len, 0)) { + fatal(MYNAME ":Parse error at %d: %s\n", + (int) XML_GetCurrentLineNumber(psr), + XML_ErrorString(XML_GetErrorCode(psr))); + } } void xml_ignore_tags(const char **taglist) { - xg_ignore_taglist = taglist; + xg_ignore_taglist = taglist; } void -xml_init0(const char *fname, xg_tag_mapping *tbl, const char *encoding, - gbsize_t offset ) +xml_init0(const char *fname, xg_tag_mapping *tbl, const char *encoding, + gbsize_t offset) { - if (fname) { - ifd = gbfopen(fname, "r", MYNAME); - if (offset) { - gbfseek(ifd, offset, SEEK_SET); - } - } else { - ifd = NULL; - } + if (fname) { + ifd = gbfopen(fname, "r", MYNAME); + if (offset) { + gbfseek(ifd, offset, SEEK_SET); + } + } else { + ifd = NULL; + } - current_tag = vmem_alloc(1,0); - *((char *)current_tag.mem) = '\0'; + current_tag = vmem_alloc(1,0); + *((char *)current_tag.mem) = '\0'; - psr = XML_ParserCreate((const XML_Char *)encoding); - if (!psr) { - fatal(MYNAME ": Cannot create XML Parser\n"); - } + psr = XML_ParserCreate((const XML_Char *)encoding); + if (!psr) { + fatal(MYNAME ": Cannot create XML Parser\n"); + } - cdatastr = vmem_alloc(1, 0); - *((char *)cdatastr.mem) = '\0'; + cdatastr = vmem_alloc(1, 0); + *((char *)cdatastr.mem) = '\0'; - xg_tag_tbl = tbl; + xg_tag_tbl = tbl; - cet_convert_init(CET_CHARSET_UTF8, 1); + cet_convert_init(CET_CHARSET_UTF8, 1); - XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); - XML_SetElementHandler(psr, xml_start, xml_end); - XML_SetCharacterDataHandler(psr, xml_cdata); + XML_SetUnknownEncodingHandler(psr, cet_lib_expat_UnknownEncodingHandler, NULL); + XML_SetElementHandler(psr, xml_start, xml_end); + XML_SetCharacterDataHandler(psr, xml_cdata); } /* xml_init0 iwth a default seek argument of zero */ void -xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) { +xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) +{ xml_init0(fname, tbl, encoding, 0); } void xml_init_offset(const char *fname, xg_tag_mapping *tbl, const char *encoding, - gbsize_t offset) { + gbsize_t offset) +{ xml_init0(fname, tbl, encoding, offset); } void xml_deinit(void) { - vmem_free(¤t_tag); - vmem_free(&cdatastr); - if (ifd) { - gbfclose(ifd); - ifd = NULL; - } - xg_ignore_taglist = NULL; + vmem_free(¤t_tag); + vmem_free(&cdatastr); + if (ifd) { + gbfclose(ifd); + ifd = NULL; + } + xg_ignore_taglist = NULL; } #else /* HAVE_LIBEXPAT */ void xml_init(const char *fname, xg_tag_mapping *tbl, const char *encoding) { - fatal("This format does not support reading XML files as libexpat was not present."); + fatal("This format does not support reading XML files as libexpat was not present."); } void xml_read(void) diff --git a/gpsbabel/xmlgeneric.h b/gpsbabel/xmlgeneric.h index 79fa84a2f..22d82e535 100644 --- a/gpsbabel/xmlgeneric.h +++ b/gpsbabel/xmlgeneric.h @@ -22,37 +22,37 @@ typedef enum { - cb_start = 1, - cb_cdata, - cb_end, + cb_start = 1, + cb_cdata, + cb_end, } xg_cb_type; -typedef void (xg_callback) (const char *, const char **); +typedef void (xg_callback)(const char *, const char **); typedef struct xg_tag_mapping { - xg_callback *tag_cb; - xg_cb_type cb_type; - const char *tag_name; + xg_callback *tag_cb; + xg_cb_type cb_type; + const char *tag_name; } xg_tag_mapping; extern char *xhtml_entities; void write_xml_entity(gbfile *ofd, const char *indent, - const char *tag, const char *value); + const char *tag, const char *value); void write_xml_entity_begin0(gbfile *ofd, const char *indent, - const char *tag); -void write_xml_entity_begin1(gbfile *ofd, const char *indent, const char *tag, - const char *attr1, const char *attrval1); -void write_xml_entity_begin2(gbfile *ofd, const char *indent, const char *tag, - const char *attr1, const char *attrval1, - const char *attr2, const char *attrval2); + const char *tag); +void write_xml_entity_begin1(gbfile *ofd, const char *indent, const char *tag, + const char *attr1, const char *attrval1); +void write_xml_entity_begin2(gbfile *ofd, const char *indent, const char *tag, + const char *attr1, const char *attrval1, + const char *attr2, const char *attrval2); void write_xml_entity_end(gbfile *ofd, const char *indent, const char *tag); void write_optional_xml_entity(gbfile *ofd, const char *indent, - const char *tag, const char *value); + const char *tag, const char *value); void xml_write_time(gbfile *ofd, const time_t timep, int microseconds, const char *elname); void xml_fill_in_time(char *time_string, const time_t timep, int microseconds, - int long_or_short); + int long_or_short); void write_xml_header(gbfile *ofd); void xml_ignore_tags(const char **taglist); diff --git a/gpsbabel/xmltag.c b/gpsbabel/xmltag.c index 2fbeaa618..b769278be 100644 --- a/gpsbabel/xmltag.c +++ b/gpsbabel/xmltag.c @@ -1,6 +1,6 @@ /* - Functions to deal with xml_tags - + Functions to deal with xml_tags + Copyright (C) 2005 Ron Parker and Robert Lipe. This program is free software; you can redistribute it and/or modify @@ -26,135 +26,143 @@ #include "defs.h" static void -free_xml_tag( xml_tag *tag ) +free_xml_tag(xml_tag *tag) { - xml_tag *next = NULL; - char **ap; - - while ( tag ) { - if (tag->cdata) { - xfree(tag->cdata); - } - if (tag->child) { - free_gpx_extras(tag->child); - } - if (tag->parentcdata) { - xfree(tag->parentcdata); - } - if (tag->tagname) { - xfree(tag->tagname); - } - if (tag->attributes) { - ap = tag->attributes; - - while (*ap) - xfree(*ap++); - - xfree(tag->attributes); - } - - next = tag->sibling; - xfree(tag); - tag = next; - } + xml_tag *next = NULL; + char **ap; + + while (tag) { + if (tag->cdata) { + xfree(tag->cdata); + } + if (tag->child) { + free_gpx_extras(tag->child); + } + if (tag->parentcdata) { + xfree(tag->parentcdata); + } + if (tag->tagname) { + xfree(tag->tagname); + } + if (tag->attributes) { + ap = tag->attributes; + + while (*ap) { + xfree(*ap++); + } + + xfree(tag->attributes); + } + + next = tag->sibling; + xfree(tag); + tag = next; + } } static void -copy_xml_tag( xml_tag **copy, xml_tag *src, xml_tag *parent ) { - xml_tag *res = NULL; - char **ap = NULL; - char **ap2 = NULL; - int count = 0; - - if ( !src ) { - *copy = NULL; - return; - } - - res = (xml_tag*) xcalloc( 1, sizeof(xml_tag)); - *copy = res; - - memcpy( res, src, sizeof(xml_tag)); - res->tagname = xstrdup( src->tagname ); - res->cdata = xstrdup( src->cdata ); - res->parentcdata = xstrdup( src->parentcdata ); - if ( src->attributes ) { - ap = src->attributes; - while ( *ap ) { - count++; - ap++; - } - res->attributes = (char **)xcalloc( count+1, sizeof(char *)); - ap = src->attributes; - ap2 = res->attributes; - while (*ap) { - *ap2 = xstrdup(*ap); - ap++; - ap2++; - } - } - res->parent = parent; - copy_xml_tag( &(res->sibling), src->sibling, parent ); - copy_xml_tag( &(res->child), src->child, res ); +copy_xml_tag(xml_tag **copy, xml_tag *src, xml_tag *parent) +{ + xml_tag *res = NULL; + char **ap = NULL; + char **ap2 = NULL; + int count = 0; + + if (!src) { + *copy = NULL; + return; + } + + res = (xml_tag*) xcalloc(1, sizeof(xml_tag)); + *copy = res; + + memcpy(res, src, sizeof(xml_tag)); + res->tagname = xstrdup(src->tagname); + res->cdata = xstrdup(src->cdata); + res->parentcdata = xstrdup(src->parentcdata); + if (src->attributes) { + ap = src->attributes; + while (*ap) { + count++; + ap++; + } + res->attributes = (char **)xcalloc(count+1, sizeof(char *)); + ap = src->attributes; + ap2 = res->attributes; + while (*ap) { + *ap2 = xstrdup(*ap); + ap++; + ap2++; + } + } + res->parent = parent; + copy_xml_tag(&(res->sibling), src->sibling, parent); + copy_xml_tag(&(res->child), src->child, res); } -static void -convert_xml_tag( xml_tag *tag ) { - char **ap = NULL; - - if (tag == NULL) return; - - tag->cdata = cet_convert_string(tag->cdata); - tag->parentcdata = cet_convert_string(tag->parentcdata); - - ap = tag->attributes; - while (*ap) - { - *ap = cet_convert_string(*ap); - ap++; - } - convert_xml_tag(tag->sibling); - convert_xml_tag(tag->child); +static void +convert_xml_tag(xml_tag *tag) +{ + char **ap = NULL; + + if (tag == NULL) { + return; + } + + tag->cdata = cet_convert_string(tag->cdata); + tag->parentcdata = cet_convert_string(tag->parentcdata); + + ap = tag->attributes; + while (*ap) { + *ap = cet_convert_string(*ap); + ap++; + } + convert_xml_tag(tag->sibling); + convert_xml_tag(tag->child); } -fs_xml *fs_xml_alloc( long type ); +fs_xml *fs_xml_alloc(long type); static void -fs_xml_destroy( void *fs ) { - fs_xml *xml = (fs_xml *)fs; - if ( xml ) { - free_xml_tag( xml->tag ); - } - xfree( fs ); +fs_xml_destroy(void *fs) +{ + fs_xml *xml = (fs_xml *)fs; + if (xml) { + free_xml_tag(xml->tag); + } + xfree(fs); } static void -fs_xml_copy( void **copy, void *source ) { - fs_xml *src = (fs_xml *)source; - if ( !source ) { - *copy = NULL; - return; - } - *copy = (void *)fs_xml_alloc( src->fs.type ); - memcpy( *copy, source, sizeof(fs_xml) ); - copy_xml_tag( &(((fs_xml *)(*copy))->tag), src->tag, NULL ); +fs_xml_copy(void **copy, void *source) +{ + fs_xml *src = (fs_xml *)source; + if (!source) { + *copy = NULL; + return; + } + *copy = (void *)fs_xml_alloc(src->fs.type); + memcpy(*copy, source, sizeof(fs_xml)); + copy_xml_tag(&(((fs_xml *)(*copy))->tag), src->tag, NULL); } static void -fs_xml_convert( void *fs ) { - fs_xml *xml = (fs_xml *)fs; - if ( xml ) { - convert_xml_tag( xml->tag ); - } +fs_xml_convert(void *fs) +{ + fs_xml *xml = (fs_xml *)fs; + if (xml) { + convert_xml_tag(xml->tag); + } } -fs_xml *fs_xml_alloc( long type ) { - fs_xml *result = NULL; - - result = (fs_xml *)xcalloc( 1, sizeof(fs_xml)); - result->fs.type = type; - result->fs.copy = fs_xml_copy; - result->fs.destroy = fs_xml_destroy; - result->fs.convert = fs_xml_convert; - return result; +fs_xml *fs_xml_alloc(long type) +{ + fs_xml *result = NULL; + + result = (fs_xml *)xcalloc(1, sizeof(fs_xml)); + result->fs.type = type; + result->fs.copy = fs_xml_copy; + result->fs.destroy = fs_xml_destroy; + result->fs.convert = fs_xml_convert; + return result; } diff --git a/gpsbabel/xol.c b/gpsbabel/xol.c index d0c648f75..d03c87b1c 100644 --- a/gpsbabel/xol.c +++ b/gpsbabel/xol.c @@ -1,4 +1,4 @@ -/* +/* Support for Swiss Map # (.xol) format @@ -32,9 +32,8 @@ static int space; static bounds all_bounds; static short_handle short_h; -static arglist_t xol_args[] = -{ - ARG_TERMINATOR +static arglist_t xol_args[] = { + ARG_TERMINATOR }; #define MYNAME "xol" @@ -43,7 +42,7 @@ static arglist_t xol_args[] = void xol_rd_init(const char *fname) { - fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); + fatal(MYNAME ": This build excluded \"" MYNAME "\" support because expat was not installed.\n"); } void @@ -60,119 +59,129 @@ static xg_callback xol_waypt, xol_overlay; static xg_tag_mapping xol_map[] = { - { xol_overlay, cb_start, XOL }, - { xol_shape, cb_start, XOL "/shapes/*shape" }, - { xol_shape_end, cb_end, XOL "/shapes/*shape" }, - { xol_waypt, cb_start, XOL "/shapes/shape/*points/point" }, - { NULL, 0, NULL } + { xol_overlay, cb_start, XOL }, + { xol_shape, cb_start, XOL "/shapes/*shape" }, + { xol_shape_end, cb_end, XOL "/shapes/*shape" }, + { xol_waypt, cb_start, XOL "/shapes/shape/*points/point" }, + { NULL, 0, NULL } }; static void xol_overlay(const char *args, const char **attrv) { - const char **avp = &attrv[0]; + const char **avp = &attrv[0]; - while (*avp) { - if (strcmp(avp[0], "version") == 0) { - if (strcmp(avp[1], "1.0") != 0) - fatal(MYNAME ": Unsupported version %s.\n", avp[1]); - } + while (*avp) { + if (strcmp(avp[0], "version") == 0) { + if (strcmp(avp[1], "1.0") != 0) { + fatal(MYNAME ": Unsupported version %s.\n", avp[1]); + } + } - avp+=2; - } + avp+=2; + } } static void xol_shape(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - - while (*avp) { - if (strcmp(avp[0], "type") == 0) { - if (strcmp(avp[1], "waypoint") == 0) { - wpt = waypt_new(); - } - else if (strcmp(avp[1], "polyline") == 0) { - trk = route_head_alloc(); - track_add_head(trk); - } - } - else if (strcmp(avp[0], "name") == 0) { - if (wpt) wpt->shortname = xstrdup(avp[1]); - else if (trk) trk->rte_name = xstrdup(avp[1]); - } - else if (strcmp(avp[0], "comment") == 0) { - if (wpt) wpt->notes = xstrdup(avp[1]); - } - else if (strcmp(avp[0], "alt") == 0) { - if (wpt) wpt->altitude = atof(avp[1]); - } - else if (strcmp(avp[0], "timestamp") == 0) { - if (wpt) wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); - } - else if (strcmp(avp[0], "icon") == 0) { - if (wpt) { - wpt->icon_descr = xstrdup(avp[1]); - wpt->wpt_flags.icon_descr_is_dynamic = 1; - } - } - - avp+=2; - } + const char **avp = &attrv[0]; + + while (*avp) { + if (strcmp(avp[0], "type") == 0) { + if (strcmp(avp[1], "waypoint") == 0) { + wpt = waypt_new(); + } else if (strcmp(avp[1], "polyline") == 0) { + trk = route_head_alloc(); + track_add_head(trk); + } + } else if (strcmp(avp[0], "name") == 0) { + if (wpt) { + wpt->shortname = xstrdup(avp[1]); + } else if (trk) { + trk->rte_name = xstrdup(avp[1]); + } + } else if (strcmp(avp[0], "comment") == 0) { + if (wpt) { + wpt->notes = xstrdup(avp[1]); + } + } else if (strcmp(avp[0], "alt") == 0) { + if (wpt) { + wpt->altitude = atof(avp[1]); + } + } else if (strcmp(avp[0], "timestamp") == 0) { + if (wpt) { + wpt->creation_time = xml_parse_time(avp[1], &wpt->microseconds); + } + } else if (strcmp(avp[0], "icon") == 0) { + if (wpt) { + wpt->icon_descr = xstrdup(avp[1]); + wpt->wpt_flags.icon_descr_is_dynamic = 1; + } + } + + avp+=2; + } } -static void +static void xol_shape_end(const char *args, const char **unused) { - if (wpt) { - if (trk) track_add_wpt(trk, wpt); - else waypt_add(wpt); - wpt = NULL; - } - else if (trk) { - if (trk->rte_waypt_ct == 0) track_del_head(trk); - trk = NULL; - } + if (wpt) { + if (trk) { + track_add_wpt(trk, wpt); + } else { + waypt_add(wpt); + } + wpt = NULL; + } else if (trk) { + if (trk->rte_waypt_ct == 0) { + track_del_head(trk); + } + trk = NULL; + } } -static void -xol_waypt(const char *args, const char **attrv) { - const char **avp = &attrv[0]; - int x=0, y=0; - - while (*avp) { - if (strcmp(avp[0], "y") == 0) - y = atoi(avp[1]); - else if (strcmp(avp[0], "x") == 0) - x = atoi(avp[1]); - avp+=2; - } - - GPS_Math_Swiss_EN_To_WGS84((double)x, (double)y, &wpt->latitude, &wpt->longitude); +static void +xol_waypt(const char *args, const char **attrv) +{ + const char **avp = &attrv[0]; + int x=0, y=0; + + while (*avp) { + if (strcmp(avp[0], "y") == 0) { + y = atoi(avp[1]); + } else if (strcmp(avp[0], "x") == 0) { + x = atoi(avp[1]); + } + avp+=2; + } + + GPS_Math_Swiss_EN_To_WGS84((double)x, (double)y, &wpt->latitude, &wpt->longitude); } -static void +static void xol_rd_init(const char *fname) { - trk = NULL; - wpt = NULL; + trk = NULL; + wpt = NULL; - xml_init(fname, xol_map, NULL); + xml_init(fname, xol_map, NULL); } -static void +static void xol_read(void) { - xml_read(); + xml_read(); } #endif -static void +static void xol_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } /* writer */ @@ -180,175 +189,188 @@ xol_rd_deinit(void) static void xol_fatal_outside(const waypoint *wpt) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", - wpt->shortname ? wpt->shortname : "Waypoint", - pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), - gt_get_mps_grid_longname(grid_swiss, MYNAME)); + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": %s (%s) is outside of convertable area \"%s\"!\n", + wpt->shortname ? wpt->shortname : "Waypoint", + pretty_deg_format(wpt->latitude, wpt->longitude, 'd', NULL, 0), + gt_get_mps_grid_longname(grid_swiss, MYNAME)); } static void xol_write_time(const waypoint *wpt) { - char time_string[64]; - - xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); - if (time_string[0]) { - gbfprintf(fout, " timestamp=\"%s\"", time_string); - } + char time_string[64]; + + xml_fill_in_time(time_string, wpt->creation_time, wpt->microseconds, XML_LONG_TIME); + if (time_string[0]) { + gbfprintf(fout, " timestamp=\"%s\"", time_string); + } } static void xol_write_string(const char *name, const char *str) { - if (str && *str) { - char *temp = strenquote(str, '"'); - gbfprintf(fout, " %s=%s", name, temp); - xfree(temp); - } + if (str && *str) { + char *temp = strenquote(str, '"'); + gbfprintf(fout, " %s=%s", name, temp); + xfree(temp); + } } static void xol_waypt_bound_calc(const waypoint *wpt) { - waypt_add_to_bounds(&all_bounds, wpt); + waypt_add_to_bounds(&all_bounds, wpt); } static void xol_wr_init(const char *fname) { - fout = gbfopen(fname, "w", MYNAME); - - space = 1; - waypt_init_bounds(&all_bounds); - short_h = mkshort_new_handle(); - - setshort_length(short_h, 1024); /* ??? */ - setshort_badchars(short_h, "\r\n\t"); - setshort_mustupper(short_h, 0); - setshort_mustuniq(short_h, 1); - setshort_whitespace_ok(short_h, 1); - setshort_repeating_whitespace_ok(short_h, 1); - setshort_defname(short_h, "Waypoint"); + fout = gbfopen(fname, "w", MYNAME); + + space = 1; + waypt_init_bounds(&all_bounds); + short_h = mkshort_new_handle(); + + setshort_length(short_h, 1024); /* ??? */ + setshort_badchars(short_h, "\r\n\t"); + setshort_mustupper(short_h, 0); + setshort_mustuniq(short_h, 1); + setshort_whitespace_ok(short_h, 1); + setshort_repeating_whitespace_ok(short_h, 1); + setshort_defname(short_h, "Waypoint"); } static void xol_wr_deinit(void) { - mkshort_del_handle(&short_h); - gbfclose(fout); + mkshort_del_handle(&short_h); + gbfclose(fout); } static void xol_waypt_disp_cb(const waypoint *wpt) { - double x, y; - char *name; - - name = wpt->shortname; - if ((name == NULL) || (*name == '\0') || global_opts.synthesize_shortnames) - name = mkshort_from_wpt(short_h, wpt); - else - name = mkshort(short_h, name); - - if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) - xol_fatal_outside(wpt); - - gbfprintf(fout, "%*snotes); - xol_write_string("icon", wpt->icon_descr); - if (wpt->creation_time) xol_write_time(wpt); - if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); - gbfprintf(fout, ">\n"); - - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); - - xfree(name); + double x, y; + char *name; + + name = wpt->shortname; + if ((name == NULL) || (*name == '\0') || global_opts.synthesize_shortnames) { + name = mkshort_from_wpt(short_h, wpt); + } else { + name = mkshort(short_h, name); + } + + if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) { + xol_fatal_outside(wpt); + } + + gbfprintf(fout, "%*snotes); + xol_write_string("icon", wpt->icon_descr); + if (wpt->creation_time) { + xol_write_time(wpt); + } + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + } + gbfprintf(fout, ">\n"); + + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + + xfree(name); } static void xol_track_hdr_disp_cb(const route_head *trk) { - gbfprintf(fout, "%*srte_name); - gbfprintf(fout, " lineSize=\"3\" lineColor=\"#e60000\" lineStyle=\"solid\">\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*srte_name); + gbfprintf(fout, " lineSize=\"3\" lineColor=\"#e60000\" lineStyle=\"solid\">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); } static void xol_track_tlr_disp_cb(const route_head *trk) { - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); } static void xol_trkpt_disp_cb(const waypoint *wpt) { - double x, y; - - if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) - xol_fatal_outside(wpt); - - gbfprintf(fout, "%*screation_time) xol_write_time(wpt); - if (wpt->altitude != unknown_alt) gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); - gbfprintf(fout, ">\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); + double x, y; + + if (! GPS_Math_WGS84_To_Swiss_EN(wpt->latitude, wpt->longitude, &x, &y)) { + xol_fatal_outside(wpt); + } + + gbfprintf(fout, "%*screation_time) { + xol_write_time(wpt); + } + if (wpt->altitude != unknown_alt) { + gbfprintf(fout, " alt=\"%.f\"", wpt->altitude); + } + gbfprintf(fout, ">\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); } static void xol_write(void) { - double x, y; - - waypt_disp_all(xol_waypt_bound_calc); - track_disp_all(NULL, NULL, xol_waypt_bound_calc); - - if (! waypt_bounds_valid(&all_bounds)) { - fatal(MYNAME ": No data available!\n"); - } - - if (! GPS_Math_WGS84_To_Swiss_EN( - (all_bounds.min_lat + all_bounds.max_lat) / 2, - (all_bounds.min_lon + all_bounds.max_lon) / 2, &x, &y)) { - gbfprintf(fout, "#####\n"); - fatal(MYNAME ": At least one point is outside of convertable area \"%s\"!\n", - gt_get_mps_grid_longname(grid_swiss, MYNAME)); - } - - gbfprintf(fout, "\n", global_opts.charset_name); - gbfprintf(fout, "\n"); - gbfprintf(fout, "%*s\n", space++*2, ""); - gbfprintf(fout, "%*s

\n", space*2, "", x, y); - gbfprintf(fout, "%*s\n", space++*2, ""); - waypt_disp_all(xol_waypt_disp_cb); - track_disp_all(xol_track_hdr_disp_cb, xol_track_tlr_disp_cb, xol_trkpt_disp_cb); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "%*s\n", --space*2, ""); - gbfprintf(fout, "\n"); + double x, y; + + waypt_disp_all(xol_waypt_bound_calc); + track_disp_all(NULL, NULL, xol_waypt_bound_calc); + + if (! waypt_bounds_valid(&all_bounds)) { + fatal(MYNAME ": No data available!\n"); + } + + if (! GPS_Math_WGS84_To_Swiss_EN( + (all_bounds.min_lat + all_bounds.max_lat) / 2, + (all_bounds.min_lon + all_bounds.max_lon) / 2, &x, &y)) { + gbfprintf(fout, "#####\n"); + fatal(MYNAME ": At least one point is outside of convertable area \"%s\"!\n", + gt_get_mps_grid_longname(grid_swiss, MYNAME)); + } + + gbfprintf(fout, "\n", global_opts.charset_name); + gbfprintf(fout, "\n"); + gbfprintf(fout, "%*s\n", space++*2, ""); + gbfprintf(fout, "%*s
\n", space*2, "", x, y); + gbfprintf(fout, "%*s\n", space++*2, ""); + waypt_disp_all(xol_waypt_disp_cb); + track_disp_all(xol_track_hdr_disp_cb, xol_track_tlr_disp_cb, xol_trkpt_disp_cb); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "%*s\n", --space*2, ""); + gbfprintf(fout, "\n"); } ff_vecs_t xol_vecs = { - ff_type_file, - { ff_cap_read | ff_cap_write, /* waypoints */ - ff_cap_read | ff_cap_write, /* tracks */ - ff_cap_none }, /* routes */ - xol_rd_init, - xol_wr_init, - xol_rd_deinit, - xol_wr_deinit, - xol_read, - xol_write, - NULL, - xol_args, - CET_CHARSET_UTF8, 0 + ff_type_file, + { + ff_cap_read | ff_cap_write, /* waypoints */ + ff_cap_read | ff_cap_write, /* tracks */ + ff_cap_none + }, /* routes */ + xol_rd_init, + xol_wr_init, + xol_rd_deinit, + xol_wr_deinit, + xol_read, + xol_write, + NULL, + xol_args, + CET_CHARSET_UTF8, 0 }; diff --git a/gpsbabel/yahoo.c b/gpsbabel/yahoo.c index 8a98668fd..914bff595 100644 --- a/gpsbabel/yahoo.c +++ b/gpsbabel/yahoo.c @@ -29,91 +29,93 @@ static char *as; static arglist_t yahoo_args[] = { - {"addrsep", &as, - "String to separate concatenated address fields (default=\", \")", - ", ", ARGTYPE_STRING, ARG_NOMINMAX }, - ARG_TERMINATOR + { + "addrsep", &as, + "String to separate concatenated address fields (default=\", \")", + ", ", ARGTYPE_STRING, ARG_NOMINMAX + }, + ARG_TERMINATOR }; static xg_callback wpt_s, wpt_lat, wpt_lon, wpt_e; static xg_callback wpt_addr /*, wpt_city, wpt_state, wpt_zip, wpt_country*/; static xg_tag_mapping gl_map[] = { - { wpt_s, cb_start, "/ResultSet/Result" }, - { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, - { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, - { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, - { wpt_e, cb_end, "/ResultSet/Result" }, - { NULL, 0, NULL} + { wpt_s, cb_start, "/ResultSet/Result" }, + { wpt_lat, cb_cdata, "/ResultSet/Result/Latitude" }, + { wpt_lon, cb_cdata, "/ResultSet/Result/Longitude" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Address" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/City" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/State" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Zip" }, + { wpt_addr, cb_cdata, "/ResultSet/Result/Country" }, + { wpt_e, cb_end, "/ResultSet/Result" }, + { NULL, 0, NULL} }; static void yahoo_rd_init(const char *fname) { - xml_init(fname, gl_map, NULL); + xml_init(fname, gl_map, NULL); } static void yahoo_read(void) { - xml_read(); + xml_read(); } static void yahoo_rd_deinit(void) { - xml_deinit(); + xml_deinit(); } static void yahoo_wr_init(const char *fname) { - fatal("Writing file of type %s is not supported\n", MYNAME); + fatal("Writing file of type %s is not supported\n", MYNAME); } void wpt_s(const char *args, const char **unused) { - wpt_tmp = waypt_new(); + wpt_tmp = waypt_new(); } void wpt_e(const char *args, const char **unused) { - waypt_add(wpt_tmp); - wpt_tmp = NULL; + waypt_add(wpt_tmp); + wpt_tmp = NULL; } void wpt_lat(const char *args, const char **unused) { - wpt_tmp->latitude = atof(args); + wpt_tmp->latitude = atof(args); } void wpt_lon(const char *args, const char **unused) { - wpt_tmp->longitude = atof(args); + wpt_tmp->longitude = atof(args); } void wpt_addr(const char *args, const char **unused) { - if (wpt_tmp->notes) { - wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); - } - wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); + if (wpt_tmp->notes) { + wpt_tmp->notes = xstrappend(wpt_tmp->notes, as); + } + wpt_tmp->notes = xstrappend(wpt_tmp->notes, args); } ff_vecs_t yahoo_vecs = { - ff_type_file, - { ff_cap_read }, - yahoo_rd_init, - yahoo_wr_init, - yahoo_rd_deinit, - NULL, - yahoo_read, - NULL, - NULL, - yahoo_args, - CET_CHARSET_ASCII, 0 /* CET-REVIEW */ + ff_type_file, + { ff_cap_read }, + yahoo_rd_init, + yahoo_wr_init, + yahoo_rd_deinit, + NULL, + yahoo_read, + NULL, + NULL, + yahoo_args, + CET_CHARSET_ASCII, 0 /* CET-REVIEW */ }; -- 2.30.2